diff options
Diffstat (limited to 'src/vs/editor/contrib/snippet/browser/snippetParser.ts')
-rw-r--r-- | src/vs/editor/contrib/snippet/browser/snippetParser.ts | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/src/vs/editor/contrib/snippet/browser/snippetParser.ts b/src/vs/editor/contrib/snippet/browser/snippetParser.ts index 6faf65e0d4d..f68dcbfa953 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetParser.ts @@ -613,11 +613,17 @@ export class SnippetParser { } parse(value: string, insertFinalTabstop?: boolean, enforceFinalTabstop?: boolean): TextmateSnippet { + const snippet = new TextmateSnippet(); + this.parseFragment(value, snippet); + this.ensureFinalTabstop(snippet, enforceFinalTabstop ?? false, insertFinalTabstop ?? false); + return snippet; + } + parseFragment(value: string, snippet: TextmateSnippet): readonly Marker[] { + + const offset = snippet.children.length; this._scanner.text(value); this._token = this._scanner.next(); - - const snippet = new TextmateSnippet(); while (this._parse(snippet)) { // nothing } @@ -626,10 +632,8 @@ export class SnippetParser { // that has a value defines the value for all placeholders with that index const placeholderDefaultValues = new Map<number, Marker[] | undefined>(); const incompletePlaceholders: Placeholder[] = []; - let placeholderCount = 0; snippet.walk(marker => { if (marker instanceof Placeholder) { - placeholderCount += 1; if (marker.isFinalTabstop) { placeholderDefaultValues.set(0, undefined); } else if (!placeholderDefaultValues.has(marker.index) && marker.children.length > 0) { @@ -640,6 +644,7 @@ export class SnippetParser { } return true; }); + for (const placeholder of incompletePlaceholders) { const defaultValues = placeholderDefaultValues.get(placeholder.index); if (defaultValues) { @@ -652,17 +657,20 @@ export class SnippetParser { } } - if (!enforceFinalTabstop) { - enforceFinalTabstop = placeholderCount > 0 && insertFinalTabstop; - } + return snippet.children.slice(offset); + } - if (!placeholderDefaultValues.has(0) && enforceFinalTabstop) { - // the snippet uses placeholders but has no - // final tabstop defined -> insert at the end - snippet.appendChild(new Placeholder(0)); + ensureFinalTabstop(snippet: TextmateSnippet, enforceFinalTabstop: boolean, insertFinalTabstop: boolean) { + + if (enforceFinalTabstop || insertFinalTabstop && snippet.placeholders.length > 0) { + const finalTabstop = snippet.placeholders.find(p => p.index === 0); + if (!finalTabstop) { + // the snippet uses placeholders but has no + // final tabstop defined -> insert at the end + snippet.appendChild(new Placeholder(0)); + } } - return snippet; } private _accept(type?: TokenType): boolean; |