Skip to content

Commit 216dea5

Browse files
committed
When inserting a nested snippet into an existing snippet there is no need to merge them.
This helps with choice completions and enables to go back to an accepted choice element to get prompted again
1 parent 4d77159 commit 216dea5

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

src/vs/editor/contrib/snippet/browser/snippetController2.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export class SnippetController2 implements IEditorContribution {
145145
}
146146

147147
const info = model.getWordUntilPosition(position);
148-
const isDefaultOption = info.word === activeChoice.options[0].value;
148+
const isAnyOfOptions = Boolean(activeChoice.options.find(o => o.value === info.word));
149149
const suggestions: CompletionItem[] = [];
150150
for (let i = 0; i < activeChoice.options.length; i++) {
151151
const option = activeChoice.options[i];
@@ -155,7 +155,7 @@ export class SnippetController2 implements IEditorContribution {
155155
insertText: option.value,
156156
sortText: 'a'.repeat(i + 1),
157157
range: new Range(position.lineNumber, info.startColumn, position.lineNumber, info.endColumn),
158-
filterText: isDefaultOption ? `${info.word}_${option.value}` : option.value,
158+
filterText: isAnyOfOptions ? `${info.word}_${option.value}` : undefined,
159159
command: { id: 'jumpToNextSnippetPlaceholder', title: localize('next', 'Go to next placeholder...') }
160160
});
161161
}

src/vs/editor/contrib/snippet/browser/snippetSession.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ export class OneSnippet {
207207
return this._snippet.placeholders.length > 0;
208208
}
209209

210+
get isTrivialSnippet(): boolean {
211+
return this._snippet.placeholders.length === 0
212+
|| (this._snippet.placeholders.length === 1 && this._snippet.placeholders[0].isFinalTabstop);
213+
}
214+
210215
computePossibleSelections() {
211216
const result = new Map<number, Range[]>();
212217
for (const placeholdersWithEqualIndex of this._placeholderGroups) {
@@ -561,18 +566,21 @@ export class SnippetSession {
561566
snippets[idx].initialize(undoEdits[idx].textChange);
562567
}
563568

564-
for (const snippet of this._snippets) {
565-
snippet.merge(snippets);
569+
// Trivial snippets have no placeholder or are just the final placeholder. That means they
570+
// are just text insertions and we don't need to merge the nested snippet into the existing
571+
// snippet
572+
const isTrivialSnippet = snippets[0].isTrivialSnippet;
573+
if (!isTrivialSnippet) {
574+
for (const snippet of this._snippets) {
575+
snippet.merge(snippets);
576+
}
577+
console.assert(snippets.length === 0);
566578
}
567-
console.assert(snippets.length === 0);
568579

569-
if (this._snippets[0].hasPlaceholder) {
580+
if (this._snippets[0].hasPlaceholder && !isTrivialSnippet) {
570581
return this._move(undefined);
571582
} else {
572-
return (
573-
undoEdits
574-
.map(edit => Selection.fromPositions(edit.range.getEndPosition()))
575-
);
583+
return undoEdits.map(edit => Selection.fromPositions(edit.range.getEndPosition()));
576584
}
577585
});
578586
}

src/vs/editor/contrib/snippet/test/browser/snippetController2.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ suite('SnippetController2', function () {
165165
// assertContextKeys(contextKeys, false, false, false);
166166
});
167167

168+
test('insert, nested trivial snippet', function () {
169+
const ctrl = instaService.createInstance(SnippetController2, editor);
170+
ctrl.insert('${1:foo}bar$0');
171+
assertContextKeys(contextKeys, true, false, true);
172+
assertSelections(editor, new Selection(1, 1, 1, 4), new Selection(2, 5, 2, 8));
173+
174+
ctrl.insert('FOO$0');
175+
assertSelections(editor, new Selection(1, 4, 1, 4), new Selection(2, 8, 2, 8));
176+
assertContextKeys(contextKeys, true, false, true);
177+
178+
ctrl.next();
179+
assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11));
180+
assertContextKeys(contextKeys, false, false, false);
181+
});
182+
168183
test('insert, nested snippet', function () {
169184
const ctrl = instaService.createInstance(SnippetController2, editor);
170185
ctrl.insert('${1:foobar}$0');

0 commit comments

Comments
 (0)