@@ -38,22 +38,23 @@ class EditNew implements Action {
3838
3939 const editor = ensureSingleEditor ( targets ) ;
4040
41- const richTargets : RichTarget [ ] = targets . map ( ( target ) => {
41+ const richTargets = targets . map < RichTarget > ( ( target ) => {
4242 const context = target . getEditNewContext ( this . isBefore ) ;
43- const common = {
44- target,
45- cursorRange : target . contentRange ,
46- } ;
43+
4744 switch ( context . type ) {
4845 case "command" :
4946 return {
50- ...common ,
47+ target,
48+ thatTarget : target . thatTarget ,
49+ cursorRange : undefined ,
5150 type : "command" ,
5251 command : context . command ,
5352 } ;
5453 case "delimiter" :
5554 return {
56- ...common ,
55+ target,
56+ thatTarget : target . thatTarget ,
57+ cursorRange : undefined ,
5758 type : "delimiter" ,
5859 delimiter : context . delimiter ,
5960 } ;
@@ -71,11 +72,16 @@ class EditNew implements Action {
7172 await this . runCommandTargets ( editor , richTargets , commandTargets ) ;
7273 }
7374 if ( delimiterTargets . length > 0 ) {
74- await this . runDelimiterTargets ( editor , commandTargets , delimiterTargets ) ;
75+ await this . runDelimiterTargets (
76+ editor ,
77+ richTargets ,
78+ commandTargets ,
79+ delimiterTargets
80+ ) ;
7581 }
7682
7783 const newSelections = richTargets . map ( ( target ) =>
78- selectionFromRange ( target . target . isReversed , target . cursorRange )
84+ selectionFromRange ( target . target . isReversed , target . cursorRange ! )
7985 ) ;
8086 await setSelectionsAndFocusEditor ( editor , newSelections ) ;
8187
@@ -106,18 +112,23 @@ class EditNew implements Action {
106112
107113 async runDelimiterTargets (
108114 editor : TextEditor ,
115+ allTargets : RichTarget [ ] ,
109116 commandTargets : CommandTarget [ ] ,
110117 delimiterTargets : DelimiterTarget [ ]
111118 ) {
112119 const position = this . isBefore ? "before" : "after" ;
120+ // NB: We don't use `constructEmptyChangeEdit` here because we want padding
121+ // if it's a line target
113122 const edits = delimiterTargets . flatMap ( ( target ) =>
114123 toPositionTarget ( target . target , position ) . constructChangeEdit ( "" )
115124 ) ;
116125
117- const cursorSelections = { selections : editor . selections } ;
118- const contentSelections = {
119- selections : delimiterTargets . map (
120- ( { target } ) => target . thatTarget . contentSelection
126+ const commandTargetCursorSelections = commandTargets . map (
127+ ( richTarget ) => richTarget . cursorRange
128+ ) ;
129+ const thatTargetSelections = {
130+ selections : allTargets . map (
131+ ( { thatTarget } ) => thatTarget . contentSelection
121132 ) ,
122133 } ;
123134 const editSelections = {
@@ -129,20 +140,24 @@ class EditNew implements Action {
129140
130141 const [
131142 updatedEditorSelections ,
132- updatedContentSelections ,
143+ updatedThatTargetSelections ,
133144 updatedEditSelections ,
134145 ] : Selection [ ] [ ] = await performEditsAndUpdateSelectionsWithBehavior (
135146 this . graph . rangeUpdater ,
136147 editor ,
137148 edits ,
138- [ cursorSelections , contentSelections , editSelections ]
149+ [ commandTargetCursorSelections , thatTargetSelections , editSelections ]
139150 ) ;
140151
141152 const insertionRanges = zip ( edits , updatedEditSelections ) . map (
142153 ( [ edit , selection ] ) => edit ! . updateRange ( selection ! )
143154 ) ;
144155
145- updateTargets ( delimiterTargets , updatedContentSelections , insertionRanges ) ;
156+ updateRichTargets (
157+ delimiterTargets ,
158+ updatedThatTargetSelections ,
159+ insertionRanges
160+ ) ;
146161 updateCommandTargets ( commandTargets , updatedEditorSelections ) ;
147162 }
148163
@@ -155,19 +170,24 @@ class EditNew implements Action {
155170
156171 await this . setSelections ( commandTargets . map ( ( { target } ) => target ) ) ;
157172
158- const [ updatedTargetRanges , updatedCursorRanges ] =
173+ const [ updatedThatTargetRanges , updatedTargetRanges ] =
159174 await callFunctionAndUpdateRanges (
160175 this . graph . rangeUpdater ,
161176 ( ) => commands . executeCommand ( command ) ,
162177 editor . document ,
163178 [
164179 targets . map ( ( { target } ) => target . thatTarget . contentRange ) ,
165- targets . map ( ( { cursorRange } ) => cursorRange ) ,
180+ targets . map ( ( { target } ) => target . contentRange ) ,
166181 ]
167182 ) ;
168183
169- updateTargets ( targets , updatedTargetRanges , updatedCursorRanges ) ;
170- updateCommandTargets ( commandTargets , editor . selections ) ;
184+ updateRichTargets ( targets , {
185+ updatedThatTargetRanges,
186+ updatedTargetRanges,
187+ } ) ;
188+ updateRichTargets ( commandTargets , {
189+ updatedCursorRanges : editor . selections ,
190+ } ) ;
171191 }
172192
173193 private async setSelections ( targets : Target [ ] ) {
@@ -192,10 +212,24 @@ export class EditNewAfter extends EditNew {
192212}
193213
194214interface CommonTarget {
215+ /**
216+ * The target that we apply the edit to. Note that we keep this target up to
217+ * date as edits come in
218+ */
195219 target : Target ;
196- cursorRange : Range ;
197- }
198220
221+ /**
222+ * The `that` target that we will return. Note that we keep this target up to
223+ * date as edits come in
224+ */
225+ thatTarget : Target ;
226+
227+ /**
228+ * The range of where we would like the cursor to end up before or after this
229+ * target. Note that this will be undefined at the start
230+ */
231+ cursorRange : Range | undefined ;
232+ }
199233interface CommandTarget extends CommonTarget {
200234 type : "command" ;
201235 command : string ;
@@ -204,6 +238,12 @@ interface DelimiterTarget extends CommonTarget {
204238 type : "delimiter" ;
205239 delimiter : string ;
206240}
241+ /**
242+ * Keeps a target as well as information about how to perform and edit. The
243+ * target will be kept up to date as the edit is performed so that we can turn
244+ * it as a that mark. We also keep track of where the cursor should end up after
245+ * applying this edit
246+ */
207247type RichTarget = CommandTarget | DelimiterTarget ;
208248
209249function ensureSingleCommand ( targets : CommandTarget [ ] ) {
@@ -214,24 +254,40 @@ function ensureSingleCommand(targets: CommandTarget[]) {
214254 return commands [ 0 ] ;
215255}
216256
217- function updateCommandTargets (
218- targets : CommandTarget [ ] ,
219- cursorRanges : readonly Range [ ]
220- ) {
221- targets . forEach ( ( target , i ) => {
222- target . cursorRange = cursorRanges [ i ] ;
223- } ) ;
257+ interface RangesToUpdate {
258+ updatedTargetRanges ?: readonly Range [ ] ;
259+ updatedThatTargetRanges ?: readonly Range [ ] ;
260+ updatedCursorRanges ?: readonly Range [ ] ;
224261}
225262
226- function updateTargets (
263+ function updateRichTargets (
227264 targets : RichTarget [ ] ,
228- updatedTargetRanges : Range [ ] ,
229- updatedCursorRanges : Range [ ]
265+ rangesToUpdate : RangesToUpdate
230266) {
231- zip ( targets , updatedTargetRanges , updatedCursorRanges ) . forEach (
232- ( [ target , updatedTargetRange , updatedCursorRange ] ) => {
233- target ! . target = target ! . target . withContentRange ( updatedTargetRange ! ) ;
234- target ! . cursorRange = updatedCursorRange ! ;
235- }
236- ) ;
267+ const { updatedTargetRanges, updatedThatTargetRanges, updatedCursorRanges } =
268+ rangesToUpdate ;
269+
270+ if ( updatedTargetRanges != null ) {
271+ zip ( targets , updatedTargetRanges ) . forEach (
272+ ( [ target , updatedTargetRange ] ) => {
273+ target ! . target = target ! . target . withContentRange ( updatedTargetRange ! ) ;
274+ }
275+ ) ;
276+ }
277+
278+ if ( updatedThatTargetRanges != null ) {
279+ zip ( targets , updatedThatTargetRanges ) . forEach (
280+ ( [ target , updatedTargetRange ] ) => {
281+ target ! . target = target ! . target . withContentRange ( updatedTargetRange ! ) ;
282+ }
283+ ) ;
284+ }
285+
286+ if ( updatedCursorRanges != null ) {
287+ zip ( targets , updatedCursorRanges ) . forEach (
288+ ( [ target , updatedCursorRange ] ) => {
289+ target ! . cursorRange = updatedCursorRange ! ;
290+ }
291+ ) ;
292+ }
237293}
0 commit comments