Skip to content

Commit 91a5ee7

Browse files
committed
refactor: remove [] inline change markers from render-diff
The bracket notation conflicted with actual code brackets (array indexing, list literals, type hints). Simpler approach: just show the full lines with +/- markers and let users compare visually.
1 parent 53aeec7 commit 91a5ee7

1 file changed

Lines changed: 10 additions & 144 deletions

File tree

plugin/scripts/render-diff.py

Lines changed: 10 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class UsedSymbols:
5757
space: bool = False
5858
tab: bool = False
5959
wrap: bool = False
60-
bracket: bool = False
6160

6261

6362
@dataclass
@@ -146,86 +145,6 @@ def visualize_whitespace(line: str, used: UsedSymbols) -> str:
146145
return ''.join(result)
147146

148147

149-
def common_prefix_len(s1: str, s2: str) -> int:
150-
"""Find common prefix length between two strings."""
151-
max_len = min(len(s1), len(s2))
152-
for i in range(max_len):
153-
if s1[i] != s2[i]:
154-
return i
155-
return max_len
156-
157-
158-
def common_suffix_len(s1: str, s2: str) -> int:
159-
"""Find common suffix length between two strings."""
160-
max_len = min(len(s1), len(s2))
161-
for i in range(1, max_len + 1):
162-
if s1[-i] != s2[-i]:
163-
return i - 1
164-
return max_len
165-
166-
167-
def is_word_char(c: str) -> bool:
168-
"""Check if character is part of a word/identifier."""
169-
return c.isalnum() or c == '_'
170-
171-
172-
def expand_to_word_boundary(line: str, start: int, end: int) -> tuple[int, int]:
173-
"""Expand a range to include complete words at boundaries.
174-
175-
If start is in the middle of a word, expand left to word start.
176-
If end is in the middle of a word, expand right to word end.
177-
"""
178-
# Expand start leftward if in middle of word
179-
while start > 0 and is_word_char(line[start - 1]) and is_word_char(line[start]):
180-
start -= 1
181-
182-
# Expand end rightward if in middle of word
183-
while end < len(line) and is_word_char(line[end - 1]) and is_word_char(line[end]):
184-
end += 1
185-
186-
return start, end
187-
188-
189-
def highlight_word_diff(old_line: str, new_line: str, is_old: bool, used: UsedSymbols) -> str:
190-
"""Apply word-level diff highlighting with [] brackets.
191-
192-
Expands bracket boundaries to complete words to avoid splitting identifiers.
193-
"""
194-
prefix_len = common_prefix_len(old_line, new_line)
195-
suffix_len = common_suffix_len(old_line, new_line)
196-
197-
old_len = len(old_line)
198-
new_len = len(new_line)
199-
200-
old_diff_len = old_len - prefix_len - suffix_len
201-
new_diff_len = new_len - prefix_len - suffix_len
202-
203-
# Skip if entire line changed or no meaningful diff
204-
if prefix_len == 0 and suffix_len == 0:
205-
return old_line if is_old else new_line
206-
207-
# Skip if diff portion is too small or too large
208-
if old_diff_len <= 0 or new_diff_len <= 0:
209-
return old_line if is_old else new_line
210-
211-
# Expand to word boundaries for cleaner highlighting
212-
if is_old:
213-
start = prefix_len
214-
end = prefix_len + old_diff_len
215-
start, end = expand_to_word_boundary(old_line, start, end)
216-
prefix = old_line[:start]
217-
diff_part = old_line[start:end]
218-
suffix = old_line[end:]
219-
else:
220-
start = prefix_len
221-
end = prefix_len + new_diff_len
222-
start, end = expand_to_word_boundary(new_line, start, end)
223-
prefix = new_line[:start]
224-
diff_part = new_line[start:end]
225-
suffix = new_line[end:]
226-
227-
used.bracket = True
228-
return f"{prefix}[{diff_part}]{suffix}"
229148

230149

231150
class DiffRenderer:
@@ -318,47 +237,6 @@ def _print_column_header(self, context: str):
318237
f"{fill_char(BOX_HORIZONTAL, self.content_width + 1)}{BOX_T_LEFT}"
319238
)
320239

321-
def _find_wrap_point(self, content: str, max_width: int) -> int:
322-
"""Find safe wrap point that doesn't split inside [...] brackets.
323-
324-
Returns character index to wrap at, preserving bracket integrity.
325-
"""
326-
if len(content) <= max_width:
327-
return len(content)
328-
329-
# Track bracket nesting to avoid splitting inside [...]
330-
bracket_depth = 0
331-
last_safe_point = 0
332-
current_width = 0
333-
334-
for i, char in enumerate(content):
335-
# Calculate display width
336-
ea = unicodedata.east_asian_width(char)
337-
char_width = 2 if ea in ('W', 'F') else 1
338-
339-
if current_width + char_width > max_width - 1: # -1 for wrap indicator
340-
# Must wrap here or earlier
341-
if bracket_depth == 0:
342-
return i
343-
elif last_safe_point > 0:
344-
return last_safe_point
345-
else:
346-
# No safe point found, wrap anyway (rare edge case)
347-
return i
348-
349-
current_width += char_width
350-
351-
if char == '[':
352-
bracket_depth += 1
353-
elif char == ']':
354-
bracket_depth = max(0, bracket_depth - 1)
355-
356-
# Safe points are outside brackets
357-
if bracket_depth == 0:
358-
last_safe_point = i + 1
359-
360-
return len(content)
361-
362240
def _print_row(self, old_num: str, symbol: str, new_num: str, content: str):
363241
"""Print a content row, handling wrapping for long lines."""
364242
content_len = display_width(content)
@@ -372,20 +250,16 @@ def _print_row(self, old_num: str, symbol: str, new_num: str, content: str):
372250
f"{padded_content}{BOX_VERTICAL}"
373251
)
374252
else:
375-
# Wrap long lines, preserving bracket integrity
253+
# Wrap long lines
376254
self.used.wrap = True
377-
wrap_point = self._find_wrap_point(content, self.content_width)
378-
first_part = content[:wrap_point]
379-
first_width = display_width(first_part)
380-
# Pad to content_width - 1 to leave room for wrap indicator
381-
padding = ' ' * max(0, self.content_width - 1 - first_width)
255+
first_part = content[:self.content_width - 1]
382256
self.output.append(
383257
f"{BOX_VERTICAL}{pad_num(old_num, COL_OLD)}{BOX_VERTICAL} {symbol} "
384258
f"{BOX_VERTICAL}{pad_num(new_num, COL_NEW)}{BOX_VERTICAL} "
385-
f"{first_part}{padding}{BOX_VERTICAL}"
259+
f"{first_part}{BOX_VERTICAL}"
386260
)
387261

388-
remaining = content[wrap_point:]
262+
remaining = content[self.content_width - 1:]
389263
while remaining:
390264
part_len = display_width(remaining)
391265
if part_len <= self.content_width:
@@ -397,16 +271,13 @@ def _print_row(self, old_num: str, symbol: str, new_num: str, content: str):
397271
)
398272
remaining = ''
399273
else:
400-
wrap_point = self._find_wrap_point(remaining, self.content_width)
401-
next_part = remaining[:wrap_point]
402-
next_width = display_width(next_part)
403-
padding = ' ' * max(0, self.content_width - 1 - next_width)
274+
next_part = remaining[:self.content_width - 1]
404275
self.output.append(
405276
f"{BOX_VERTICAL}{' ' * COL_OLD}{BOX_VERTICAL} "
406277
f"{BOX_VERTICAL}{' ' * COL_NEW}{BOX_VERTICAL} "
407-
f"{next_part}{padding}{BOX_VERTICAL}"
278+
f"{next_part}{BOX_VERTICAL}"
408279
)
409-
remaining = remaining[wrap_point:]
280+
remaining = remaining[self.content_width - 1:]
410281

411282
def _print_hunk_bottom(self):
412283
"""Print hunk box bottom."""
@@ -455,8 +326,6 @@ def _print_legend(self):
455326
legend_items.append("- del")
456327
if self.used.plus:
457328
legend_items.append("+ add")
458-
if self.used.bracket:
459-
legend_items.append("[] changed")
460329
if self.used.space:
461330
legend_items.append("· space")
462331
if self.used.tab:
@@ -532,15 +401,12 @@ def _render_hunk_content(self, hunk: DiffHunk):
532401
new_line += 1
533402
i += 1
534403
else:
535-
# Apply word-level diff
536-
highlighted_del = highlight_word_diff(del_content, add_content, True, self.used)
537-
highlighted_add = highlight_word_diff(del_content, add_content, False, self.used)
538-
539-
self._print_row(str(old_line), '-', '', highlighted_del)
404+
# Show full lines without inline highlighting
405+
self._print_row(str(old_line), '-', '', del_content)
540406
old_line += 1
541407
i += 1
542408
self.used.plus = True
543-
self._print_row('', '+', str(new_line), highlighted_add)
409+
self._print_row('', '+', str(new_line), add_content)
544410
new_line += 1
545411
i += 1
546412
else:

0 commit comments

Comments
 (0)