refactor: Improve diff parsing and display logic for deleted and added lines

This commit is contained in:
n loewen (aider) 2025-06-07 20:04:30 +01:00
parent 794f6d0716
commit 90a9f311fc
1 changed files with 56 additions and 45 deletions

101
gtm
View File

@ -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