1414DIFF_INSERTION = '+'
1515DIFF_DELETION = '-'
1616DIFF_COMMENT = '?'
17+ DIFF_EDIT = 'e'
1718
1819
1920def first_whitespace (s ):
@@ -136,6 +137,30 @@ def edit_line(self, line, diffline):
136137 def quit (self ):
137138 self ._quit_requested = True
138139
140+ def process_deltas (self , delta ):
141+ # Strip comments.
142+ delta = [d for d in delta if d [0 ] != DIFF_COMMENT ]
143+
144+ # Process DIFF_DELETION, DIFF_INSERTION into DIFF_EDIT
145+ tdelta = []
146+ tdl = 0
147+ while tdl < len (delta ):
148+ cc1 , _ = parse_delta (delta [tdl ])
149+ if tdl < len (delta ) - 1 :
150+ cc2 , _ = parse_delta (delta [tdl + 1 ])
151+ else :
152+ cc2 = None
153+ if (cc1 , cc2 ) == (DIFF_DELETION , DIFF_INSERTION ):
154+ deltast = delta [tdl + 1 ]
155+ deltast = DIFF_EDIT + deltast [1 :]
156+ tdelta .append (deltast )
157+ tdl += 2
158+ continue
159+ tdelta .append (delta [tdl ])
160+ tdl += 1
161+
162+ return tdelta
163+
139164 @pyqtSlot ()
140165 def run (self ):
141166 initial_file , files = self .files [0 ], self .files [1 :]
@@ -165,9 +190,7 @@ def run(self):
165190
166191 diff = difflib .Differ ()
167192 delta = list (diff .compare (self .current , target ))
168-
169- # Strip comments.
170- delta = [d for d in delta if d [0 ] != DIFF_COMMENT ]
193+ delta = self .process_deltas (delta )
171194
172195 cl , dl = 0 , 0 # current line, diff line
173196 block_indented = 0 # track indents, so not reapplied
@@ -204,33 +227,26 @@ def run(self):
204227
205228 # End temporary lookahead.
206229
207- if dl < len (delta ) - 1 :
208- # Handle subsequent edit lines, delete>insert = modify
209- dn = delta [dl + 1 ]
210- next_char , nextdiffline = parse_delta (dn )
211- else :
212- next_char = None
213-
214230 # Temporary look-ahead to correctly indent/dedent a block of lines. Does not
215231 # modify the diffs, just the current state. Lines are then re-applied as normal.
216- if tdl > block_indented and ( first_char , next_char ) == ( DIFF_DELETION , DIFF_INSERTION ) :
232+ if tdl > block_indented and first_char == DIFF_EDIT :
217233 # Calculate the in/dedent.
218- dent = first_whitespace (nextdiffline ) - first_whitespace (diffline )
234+ dent = first_whitespace (diffline ) - first_whitespace (self . current [ cl ] )
219235 n_dents = 1
220236 tcl = cl
221237 tdl = dl
222238 while tdl < len (delta ) - 3 :
223- tdl += 2
239+ tdl += 1
224240 tcl += 1
225241
226242 # Get the chars to check.
243+ tcurrline = self .current [tcl ]
227244 tchar1 , tdiffline1 = parse_delta (delta [tdl ])
228- tchar2 , tdiffline2 = parse_delta (delta [tdl + 1 ])
229245
230- if ( tchar1 , tchar2 ) != ( DIFF_DELETION , DIFF_INSERTION ) :
246+ if tchar1 != DIFF_EDIT :
231247 break
232248
233- tdent = first_whitespace (tdiffline2 ) - first_whitespace (tdiffline1 )
249+ tdent = first_whitespace (tdiffline1 ) - first_whitespace (tcurrline )
234250 if tdent != dent :
235251 break
236252
@@ -241,18 +257,18 @@ def run(self):
241257 self .block_indent (cl , n_dents , dent )
242258 # End temporary lookahead.
243259
244- if ( first_char , next_char ) == ( DIFF_DELETION , DIFF_INSERTION ) :
245- if nextdiffline == self .current [cl ]:
260+ if first_char == DIFF_EDIT :
261+ if diffline == self .current [cl ]:
246262 # Skip if no change (can happen with the block indents).
247- dl += 2
263+ dl += 1
248264 cl += 1
249265 continue
250266
251267 # Correct the indentation of the line.
252- self .indent_line (cl , nextdiffline )
268+ self .indent_line (cl , diffline )
253269 # Modify diffline to nextdiffline.
254- self .edit_line (cl , nextdiffline )
255- dl += 2 # Advance diff 2, deletion & insertion.
270+ self .edit_line (cl , diffline )
271+ dl += 1
256272 cl += 1
257273 time .sleep (INSERT_SPEED )
258274 continue
0 commit comments