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