@@ -38,22 +38,23 @@ class EditNew implements Action {
38
38
39
39
const editor = ensureSingleEditor ( targets ) ;
40
40
41
- const richTargets : RichTarget [ ] = targets . map ( ( target ) => {
41
+ const richTargets = targets . map < RichTarget > ( ( target ) => {
42
42
const context = target . getEditNewContext ( this . isBefore ) ;
43
- const common = {
44
- target,
45
- cursorRange : target . contentRange ,
46
- } ;
43
+
47
44
switch ( context . type ) {
48
45
case "command" :
49
46
return {
50
- ...common ,
47
+ target,
48
+ thatTarget : target . thatTarget ,
49
+ cursorRange : undefined ,
51
50
type : "command" ,
52
51
command : context . command ,
53
52
} ;
54
53
case "delimiter" :
55
54
return {
56
- ...common ,
55
+ target,
56
+ thatTarget : target . thatTarget ,
57
+ cursorRange : undefined ,
57
58
type : "delimiter" ,
58
59
delimiter : context . delimiter ,
59
60
} ;
@@ -71,11 +72,16 @@ class EditNew implements Action {
71
72
await this . runCommandTargets ( editor , richTargets , commandTargets ) ;
72
73
}
73
74
if ( delimiterTargets . length > 0 ) {
74
- await this . runDelimiterTargets ( editor , commandTargets , delimiterTargets ) ;
75
+ await this . runDelimiterTargets (
76
+ editor ,
77
+ richTargets ,
78
+ commandTargets ,
79
+ delimiterTargets
80
+ ) ;
75
81
}
76
82
77
83
const newSelections = richTargets . map ( ( target ) =>
78
- selectionFromRange ( target . target . isReversed , target . cursorRange )
84
+ selectionFromRange ( target . target . isReversed , target . cursorRange ! )
79
85
) ;
80
86
await setSelectionsAndFocusEditor ( editor , newSelections ) ;
81
87
@@ -106,18 +112,23 @@ class EditNew implements Action {
106
112
107
113
async runDelimiterTargets (
108
114
editor : TextEditor ,
115
+ allTargets : RichTarget [ ] ,
109
116
commandTargets : CommandTarget [ ] ,
110
117
delimiterTargets : DelimiterTarget [ ]
111
118
) {
112
119
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
113
122
const edits = delimiterTargets . flatMap ( ( target ) =>
114
123
toPositionTarget ( target . target , position ) . constructChangeEdit ( "" )
115
124
) ;
116
125
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
121
132
) ,
122
133
} ;
123
134
const editSelections = {
@@ -129,20 +140,24 @@ class EditNew implements Action {
129
140
130
141
const [
131
142
updatedEditorSelections ,
132
- updatedContentSelections ,
143
+ updatedThatTargetSelections ,
133
144
updatedEditSelections ,
134
145
] : Selection [ ] [ ] = await performEditsAndUpdateSelectionsWithBehavior (
135
146
this . graph . rangeUpdater ,
136
147
editor ,
137
148
edits ,
138
- [ cursorSelections , contentSelections , editSelections ]
149
+ [ commandTargetCursorSelections , thatTargetSelections , editSelections ]
139
150
) ;
140
151
141
152
const insertionRanges = zip ( edits , updatedEditSelections ) . map (
142
153
( [ edit , selection ] ) => edit ! . updateRange ( selection ! )
143
154
) ;
144
155
145
- updateTargets ( delimiterTargets , updatedContentSelections , insertionRanges ) ;
156
+ updateRichTargets (
157
+ delimiterTargets ,
158
+ updatedThatTargetSelections ,
159
+ insertionRanges
160
+ ) ;
146
161
updateCommandTargets ( commandTargets , updatedEditorSelections ) ;
147
162
}
148
163
@@ -155,19 +170,24 @@ class EditNew implements Action {
155
170
156
171
await this . setSelections ( commandTargets . map ( ( { target } ) => target ) ) ;
157
172
158
- const [ updatedTargetRanges , updatedCursorRanges ] =
173
+ const [ updatedThatTargetRanges , updatedTargetRanges ] =
159
174
await callFunctionAndUpdateRanges (
160
175
this . graph . rangeUpdater ,
161
176
( ) => commands . executeCommand ( command ) ,
162
177
editor . document ,
163
178
[
164
179
targets . map ( ( { target } ) => target . thatTarget . contentRange ) ,
165
- targets . map ( ( { cursorRange } ) => cursorRange ) ,
180
+ targets . map ( ( { target } ) => target . contentRange ) ,
166
181
]
167
182
) ;
168
183
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
+ } ) ;
171
191
}
172
192
173
193
private async setSelections ( targets : Target [ ] ) {
@@ -192,10 +212,24 @@ export class EditNewAfter extends EditNew {
192
212
}
193
213
194
214
interface 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
+ */
195
219
target : Target ;
196
- cursorRange : Range ;
197
- }
198
220
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
+ }
199
233
interface CommandTarget extends CommonTarget {
200
234
type : "command" ;
201
235
command : string ;
@@ -204,6 +238,12 @@ interface DelimiterTarget extends CommonTarget {
204
238
type : "delimiter" ;
205
239
delimiter : string ;
206
240
}
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
+ */
207
247
type RichTarget = CommandTarget | DelimiterTarget ;
208
248
209
249
function ensureSingleCommand ( targets : CommandTarget [ ] ) {
@@ -214,24 +254,40 @@ function ensureSingleCommand(targets: CommandTarget[]) {
214
254
return commands [ 0 ] ;
215
255
}
216
256
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 [ ] ;
224
261
}
225
262
226
- function updateTargets (
263
+ function updateRichTargets (
227
264
targets : RichTarget [ ] ,
228
- updatedTargetRanges : Range [ ] ,
229
- updatedCursorRanges : Range [ ]
265
+ rangesToUpdate : RangesToUpdate
230
266
) {
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
+ }
237
293
}
0 commit comments