refactor: Improve diff parsing and display logic for deleted and added lines
This commit is contained in:
parent
794f6d0716
commit
90a9f311fc
101
gtm
101
gtm
|
|
@ -24,49 +24,58 @@ def get_diff_info(current_commit, prev_commit, filename):
|
|||
# For the first commit, we can't compare with a previous one
|
||||
return [], []
|
||||
|
||||
# Get additions
|
||||
cmd_additions = ['git', 'diff', '--unified=0', prev_commit, current_commit, '--', filename]
|
||||
result_additions = subprocess.run(cmd_additions, capture_output=True, text=True)
|
||||
# Use a more detailed diff format to better understand the changes
|
||||
cmd = ['git', 'diff', prev_commit, current_commit, '--', filename]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
# Parse the diff output to extract added and deleted lines
|
||||
lines = result.stdout.splitlines()
|
||||
|
||||
# Store line changes with their positions
|
||||
added_lines = []
|
||||
deleted_lines = []
|
||||
|
||||
# Initialize variables outside the loop to avoid UnboundLocalError
|
||||
start_line = 0
|
||||
del_start = 0
|
||||
# Track the current position in the new file
|
||||
current_line_num = 0
|
||||
deletion_offset = 0
|
||||
|
||||
for line in result_additions.stdout.splitlines():
|
||||
# Parse the diff output to find line numbers of additions and deletions
|
||||
# Parse the diff output
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
|
||||
# Parse hunk headers to get line numbers
|
||||
if line.startswith('@@'):
|
||||
# Parse the hunk header to get line numbers
|
||||
# Format is like @@ -a,b +c,d @@
|
||||
parts = line.split()
|
||||
if len(parts) >= 3:
|
||||
# Format is like @@ -a,b +c,d @@
|
||||
# We're interested in the +c,d part for additions
|
||||
# Extract the starting line number in the new file
|
||||
add_part = parts[2][1:] # Remove the + sign
|
||||
if ',' in add_part:
|
||||
start_line, count = map(int, add_part.split(','))
|
||||
current_line_num, _ = map(int, add_part.split(','))
|
||||
else:
|
||||
start_line, count = int(add_part), 1
|
||||
current_line_num = int(add_part)
|
||||
|
||||
# For deletions, we look at the -a,b part
|
||||
del_part = parts[1][1:] # Remove the - sign
|
||||
if ',' in del_part:
|
||||
del_start, del_count = map(int, del_part.split(','))
|
||||
else:
|
||||
del_start, del_count = int(del_part), 1
|
||||
# Reset deletion offset for this hunk
|
||||
deletion_offset = 0
|
||||
|
||||
# Process added lines
|
||||
elif line.startswith('+') and not line.startswith('+++'):
|
||||
# This is an added line
|
||||
added_lines.append((start_line, line[1:]))
|
||||
start_line += 1
|
||||
added_lines.append((current_line_num, line[1:]))
|
||||
current_line_num += 1
|
||||
|
||||
# Process deleted lines
|
||||
elif line.startswith('-') and not line.startswith('---'):
|
||||
# This is a deleted line
|
||||
deleted_lines.append((del_start, line[1:]))
|
||||
del_start += 1
|
||||
# Store deleted lines with the position where they would have been
|
||||
# in the new file (before the next line)
|
||||
deleted_lines.append((current_line_num, line[1:]))
|
||||
deletion_offset += 1
|
||||
|
||||
# Process context lines
|
||||
elif not line.startswith('+') and not line.startswith('-') and not line.startswith('@@'):
|
||||
# Context line, increment both counters
|
||||
start_line += 1
|
||||
del_start += 1
|
||||
current_line_num += 1
|
||||
|
||||
i += 1
|
||||
|
||||
return added_lines, deleted_lines
|
||||
|
||||
|
|
@ -167,12 +176,30 @@ def main(stdscr, filename, show_additions=False, show_deletions=False):
|
|||
# Draw file content (right pane) - more efficiently
|
||||
right_width = width - divider_col - 3
|
||||
|
||||
# First, collect all lines to display (regular and deleted)
|
||||
# First, collect all lines to display (regular, added, and deleted)
|
||||
display_lines = []
|
||||
|
||||
# Create a map of line numbers to deleted lines for faster lookup
|
||||
deleted_line_map = {}
|
||||
if show_deletions:
|
||||
for del_line_num, del_content in deleted_lines:
|
||||
if del_line_num not in deleted_line_map:
|
||||
deleted_line_map[del_line_num] = []
|
||||
deleted_line_map[del_line_num].append(del_content)
|
||||
|
||||
# Process each visible line
|
||||
for i, line in enumerate(visible_lines):
|
||||
line_num = i + scroll_offset + 1 # 1-based line number
|
||||
|
||||
# First add any deleted lines that come before this line
|
||||
if show_deletions and line_num in deleted_line_map:
|
||||
for del_content in deleted_line_map[line_num]:
|
||||
display_lines.append({
|
||||
'type': 'deleted',
|
||||
'content': del_content,
|
||||
'line_num': line_num
|
||||
})
|
||||
|
||||
# Check if this is an added line
|
||||
is_added = False
|
||||
if show_additions:
|
||||
|
|
@ -187,22 +214,6 @@ def main(stdscr, filename, show_additions=False, show_deletions=False):
|
|||
'content': line,
|
||||
'line_num': line_num
|
||||
})
|
||||
|
||||
# If showing deletions, check if there are deleted lines at this position
|
||||
if show_deletions:
|
||||
# Collect all deleted lines at this position
|
||||
deleted_at_position = []
|
||||
for del_line_num, del_line_content in deleted_lines:
|
||||
if del_line_num == line_num:
|
||||
deleted_at_position.append(del_line_content)
|
||||
|
||||
# Add all deleted lines together after the current line
|
||||
for del_content in deleted_at_position:
|
||||
display_lines.append({
|
||||
'type': 'deleted',
|
||||
'content': del_content,
|
||||
'line_num': line_num
|
||||
})
|
||||
|
||||
# Now display all lines
|
||||
display_row = 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue