@@ -214,7 +214,7 @@ function getPartials(diff: AddRem[], options: IUpdateModelOptions, startOffset:
214
214
let line = options . baseLine ;
215
215
let ch = options . editCh ;
216
216
let { oldval, newval} = options ;
217
- let lines : string [ ] | null = null ;
217
+ let lines : string [ ] = options . fullLines ;
218
218
let key = line ;
219
219
let linediff = 0 ;
220
220
@@ -245,14 +245,12 @@ function getPartials(diff: AddRem[], options: IUpdateModelOptions, startOffset:
245
245
} else if ( partialStart ) {
246
246
// Addrange before current line (abutting)
247
247
// and partial edit of current (unedited) line
248
- lines = options . fullLines ;
249
248
before . push ( lines [ options . editLine ] . slice ( 0 , ch ) ) ;
250
249
// Indicate that one unedited line should be removed
251
250
linediff = 1 ;
252
251
}
253
252
} else if ( partialStart ) {
254
253
// Replace previously unedited line:
255
- lines = options . fullLines ;
256
254
before = [ lines [ options . editLine ] . slice ( 0 , ch ) ] ;
257
255
// Indicate that one unedited line should be removed
258
256
linediff = 1 ;
@@ -279,9 +277,6 @@ function getPartials(diff: AddRem[], options: IUpdateModelOptions, startOffset:
279
277
}
280
278
if ( ! after && ! fullDeleteEnd && ! fullLineInsertions ) {
281
279
// Add remains of previously unedited line
282
- if ( lines === null ) {
283
- lines = options . fullLines ;
284
- }
285
280
let fullLine = lines [ options . editLine + newval . length - 1 ] ;
286
281
let cut = lastAddedLine . length ;
287
282
if ( newval . length === 1 ) {
@@ -773,6 +768,81 @@ function patchPatchedModel(options: IUpdateModelOptions, diffs: 'all' | 'custom'
773
768
// Add new decisions for changes that do no overlap
774
769
}
775
770
771
+
772
+ /**
773
+ * Modify certain edits to use trailing newlines instead of leading
774
+ *
775
+ * Certain edits, e.g. adding a newline link this (bracketed part added):
776
+ * line1[\n
777
+ * line2]\n
778
+ * can better be treated as:
779
+ * line1\n
780
+ * [line2\n]
781
+ *
782
+ * Similarly (bracketed part deleted):
783
+ * line1[\n
784
+ * line2]\n
785
+ * can better be treated as:
786
+ * line1\n
787
+ * [line2\n]
788
+ *
789
+ * The end results are the same, but the diffs become simpler.
790
+ *
791
+ * Note that this needs to be called before base line is computed!
792
+ */
793
+ export
794
+ function shiftAddRemoveLines ( base : string [ ] , change : CodeMirror . EditorChange ) {
795
+ if ( change . from . ch === 0 ) {
796
+ // Nothing to do here
797
+ return ;
798
+ }
799
+ if ( change . removed . length === 1 && change . removed [ 0 ] === '' ) {
800
+ // Nothing removed
801
+ // Check whether first inserted character is newline
802
+ if ( change . text . length > 1 && change . text [ 0 ] === '' ) {
803
+ // and first subsequent character is newline
804
+ let trailingLine = base [ change . to . line ] ;
805
+ if ( trailingLine . length > change . to . ch && trailingLine [ change . to . ch ] === '\n' ) {
806
+ // Match, shift newline from head to tail
807
+ change . from . line += 1 ;
808
+ change . from . ch = 0 ;
809
+ change . text . push ( change . text . shift ( ) ! ) ;
810
+ }
811
+ }
812
+ } else if ( change . text . length === 1 && change . text [ 0 ] === '' ) {
813
+ // Nothing added
814
+ // Check whether first removed character is newline
815
+ if ( change . removed . length > 1 && change . removed [ 0 ] === '' ) {
816
+ // and first subsequent character is newline
817
+ let trailingLine = base [ change . to . line ] ;
818
+ if ( trailingLine . length > change . to . ch && trailingLine [ change . to . ch ] === '\n' ) {
819
+ // Match, shift newline from head to tail
820
+ change . from . line += 1 ;
821
+ change . from . ch = 0 ;
822
+ change . to . line += 1 ;
823
+ change . to . ch = 0 ;
824
+ change . removed . push ( change . removed . shift ( ) ! ) ;
825
+ }
826
+ }
827
+ } else {
828
+ // Both added and removed
829
+ // Check whether first removed character is newline
830
+ if ( change . removed . length > 1 && change . removed [ 0 ] === '' ) {
831
+ // and first subsequent character is newline
832
+ let trailingLine = base [ change . to . line ] ;
833
+ if ( trailingLine . length > change . to . ch && trailingLine [ change . to . ch ] === '\n' ) {
834
+ // Match, shift newline from head to tail
835
+ change . from . line += 1 ;
836
+ change . from . ch = 0 ;
837
+ change . to . line += 1 ;
838
+ change . to . ch = 0 ;
839
+ change . text . push ( change . text . shift ( ) ! ) ;
840
+ change . removed . push ( change . removed . shift ( ) ! ) ;
841
+ }
842
+ }
843
+ }
844
+ }
845
+
776
846
export
777
847
function updateModel ( options : IUpdateModelOptions ) {
778
848
let model = options . model ;
0 commit comments