@@ -21,83 +21,71 @@ function createNewOperation (
2121 )
2222}
2323
24- function getLockedRangeValueIndexesInText (
25- editor : monaco . editor . ICodeEditor ,
26- range : monaco . Range ,
27- text : string
28- ) : {
29- startIndex : number | null
30- endIndex : number | null
31- } {
32- const model = editor . getModel ( )
33- if ( model == null ) {
34- return { startIndex : null , endIndex : null }
24+ function createNewOperationsFromRanges (
25+ oldOperation : ValidAnnotatedEditOperation ,
26+ editableRanges : monaco . Range [ ] ,
27+ splitText : ( string | null ) [ ]
28+ ) : ValidAnnotatedEditOperation [ ] {
29+ if ( editableRanges . length <= 0 ) {
30+ return [ ]
3531 }
3632
37- const rangeValue = model . getValueInRange ( range )
38- const startIndex = text . indexOf ( rangeValue )
39- return {
40- startIndex,
41- endIndex : startIndex + rangeValue . length
33+ if ( splitText . length === 1 ) {
34+ return [ createNewOperation ( oldOperation , oldOperation . range , splitText [ 0 ] ?? null , 0 ) ]
4235 }
36+
37+ return splitText . map ( ( text , index ) => createNewOperation ( oldOperation , editableRanges [ index ] ! , text , index ) )
4338}
4439
45- function computeNewOperationsWithIntersectingLockedCode (
40+ function splitOperationText (
4641 editor : monaco . editor . ICodeEditor ,
47- operation : ValidAnnotatedEditOperation ,
48- uneditableRanges : monaco . Range [ ]
49- ) : ValidAnnotatedEditOperation [ ] {
50- const newOperations : ValidAnnotatedEditOperation [ ] = [ ]
51- const editableRanges : monaco . Range [ ] = minusRanges ( operation . range , uneditableRanges )
52-
53- // Index of the current uneditable range in the text
54- let uneditableRangeIndex : number = 0
55- // Index of the current editable range in the text
56- let editableRangeIndex : number = 0
57- // The operation text is null or an empty string when it's a delete
58- let remainingText : string = operation . text ?? ''
42+ uneditableRanges : monaco . Range [ ] ,
43+ text : string | null
44+ ) : ( string | null ) [ ] {
45+ if ( text == null || text === '' ) {
46+ return [ text ]
47+ }
5948
60- do {
61- const editableRange = editableRanges [ editableRangeIndex ]
62- if ( editableRange == null ) {
63- // There are no editable ranges left
64- return newOperations
65- }
49+ const model = editor . getModel ( )
50+ if ( model == null ) {
51+ return [ ]
52+ }
6653
67- const uneditableRange = uneditableRanges [ uneditableRangeIndex ]
68- if ( uneditableRange == null ) {
69- // There are no more locked ranges
70- return [
71- ...newOperations ,
72- createNewOperation ( operation , editableRange , remainingText , editableRangeIndex )
73- ]
54+ const splitText : string [ ] = [ ]
55+ const uneditableRangesText = uneditableRanges . map ( range => model . getValueInRange ( range ) )
56+ let currentRange : number = 0
57+ let textToSplit : string | undefined = text
58+ while ( textToSplit != null && textToSplit !== '' && currentRange < uneditableRangesText . length ) {
59+ const rangeText = uneditableRangesText [ currentRange ]
60+ if ( rangeText != null && rangeText !== '' ) {
61+ const result : string [ ] = textToSplit . split ( rangeText )
62+ splitText . push ( result [ 0 ] ! )
63+ textToSplit = result [ 1 ]
7464 }
65+ currentRange ++
66+ }
7567
76- const { startIndex, endIndex } = getLockedRangeValueIndexesInText ( editor , uneditableRange , remainingText )
77- if ( startIndex == null || endIndex == null ) {
78- return newOperations
79- } else if ( startIndex === - 1 ) {
80- // The uneditable text is not in the remaining operation text
81- return [
82- ...newOperations ,
83- createNewOperation ( operation , editableRange , remainingText , editableRangeIndex )
84- ]
85- // remainingText = null
86- } else if ( startIndex === 0 ) {
87- // The uneditable text is at the beginning of the remaining operation text
88- uneditableRangeIndex ++
89- remainingText = remainingText . slice ( endIndex )
90- } else {
91- // The uneditable text is in the middle or at the end of the remaining operation text
92- newOperations . push (
93- createNewOperation ( operation , editableRange , remainingText . slice ( 0 , startIndex ) , editableRangeIndex )
94- )
95- uneditableRangeIndex ++
96- editableRangeIndex ++
97- remainingText = remainingText . slice ( endIndex )
98- }
99- } while ( remainingText . length > 0 )
68+ if ( textToSplit != null && textToSplit !== '' ) {
69+ splitText . push ( textToSplit )
70+ }
71+ return splitText
72+ }
10073
74+ function splitOperationsForLockedCode (
75+ editor : monaco . editor . ICodeEditor ,
76+ operations : ValidAnnotatedEditOperation [ ] ,
77+ uneditableRanges : monaco . Range [ ]
78+ ) : ValidAnnotatedEditOperation [ ] {
79+ let newOperations : ValidAnnotatedEditOperation [ ] = [ ]
80+ for ( const operation of operations ) {
81+ const operationEditableRanges : monaco . Range [ ] = minusRanges ( operation . range , uneditableRanges )
82+ const operationUneditableRanges : monaco . Range [ ] = minusRanges ( operation . range , operationEditableRanges )
83+ const splitText = splitOperationText ( editor , operationUneditableRanges , operation . text )
84+ newOperations = [
85+ ...newOperations ,
86+ ...createNewOperationsFromRanges ( operation , operationEditableRanges , splitText )
87+ ]
88+ }
10189 return newOperations
10290}
10391
@@ -107,24 +95,15 @@ export function computeNewOperationsForLockedCode (
10795 editorOperations : ValidAnnotatedEditOperation [ ] ,
10896 withDecoration : boolean
10997) : ValidAnnotatedEditOperation [ ] {
98+ const model = editor . getModel ( )
99+ if ( model == null ) {
100+ return [ ]
101+ }
102+
110103 const uneditableRanges = getLockedRanges ( editor , decorationFilter , withDecoration )
111104 if ( uneditableRanges . length <= 0 ) {
112105 return editorOperations
113106 }
114107
115- const newOperations : ValidAnnotatedEditOperation [ ] = [ ]
116- for ( const operation of editorOperations ) {
117- const operationRange = operation . range
118- const uneditableRangesThatIntersects = uneditableRanges . filter ( range => monaco . Range . areIntersecting ( range , operationRange ) )
119-
120- if ( uneditableRangesThatIntersects . length <= 0 ) {
121- // The operation range doesn't intersect with an uneditable range
122- newOperations . push ( operation )
123- } else {
124- // The operation range intersects with one or more uneditable range
125- newOperations . push ( ...computeNewOperationsWithIntersectingLockedCode ( editor , operation , uneditableRangesThatIntersects ) )
126- }
127- }
128-
129- return newOperations
108+ return splitOperationsForLockedCode ( editor , editorOperations , uneditableRanges )
130109}
0 commit comments