diff --git a/src/vs/editor/contrib/snippet/browser/snippetParser.ts b/src/vs/editor/contrib/snippet/browser/snippetParser.ts index 6cb1be524c4..956fdce23c5 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetParser.ts @@ -187,12 +187,12 @@ export class Placeholder extends Marker { } } - constructor(public index: string = '', children: Marker[]) { + constructor(public index: number, children: Marker[]) { super(); this.children = children; } get isFinalTabstop() { - return this.index === '0'; + return this.index === 0; } toString() { return Marker.toString(this.children); @@ -356,7 +356,7 @@ export class SnippetParser { // * fill in default for empty placeHolders // * compact sibling Text markers - function walk(marker: Marker[], placeholderDefaultValues: Map) { + function walk(marker: Marker[], placeholderDefaultValues: Map) { for (let i = 0; i < marker.length; i++) { const thisMarker = marker[i]; @@ -385,16 +385,16 @@ export class SnippetParser { } } - const placeholderDefaultValues = new Map(); + const placeholderDefaultValues = new Map(); walk(marker, placeholderDefaultValues); if ( - !placeholderDefaultValues.has('0') && // there is no final tabstop + !placeholderDefaultValues.has(0) && // there is no final tabstop (insertFinalTabstop && placeholderDefaultValues.size > 0 || enforceFinalTabstop) ) { // the snippet uses placeholders but has no // final tabstop defined -> insert at the end - marker.push(new Placeholder('0', [])); + marker.push(new Placeholder(0, [])); } return marker; @@ -433,7 +433,7 @@ export class SnippetParser { if (this._accept(TokenType.VariableName) || this._accept(TokenType.Int)) { // $FOO, $123 const idOrName = this._scanner.tokenText(this._prevToken); - marker.push(/^\d+$/.test(idOrName) ? new Placeholder(idOrName, []) : new Variable(idOrName, [])); + marker.push(/^\d+$/.test(idOrName) ? new Placeholder(Number(idOrName), []) : new Variable(idOrName, [])); return true; } else if (this._accept(TokenType.CurlyOpen)) { @@ -451,7 +451,7 @@ export class SnippetParser { if (this._accept(TokenType.CurlyClose)) { const idOrName = Marker.toString(name); - marker.push(/^\d+$/.test(idOrName) ? new Placeholder(idOrName, children) : new Variable(idOrName, children)); + marker.push(/^\d+$/.test(idOrName) ? new Placeholder(Number(idOrName), children) : new Variable(idOrName, children)); return true; } diff --git a/src/vs/editor/contrib/snippet/browser/snippetSession.ts b/src/vs/editor/contrib/snippet/browser/snippetSession.ts index 44cfd7cb388..5f9a49a97e6 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetSession.ts @@ -173,9 +173,9 @@ export class OneSnippet { // through the placeholders in the correct order for (const nestedPlaceholder of nested._snippet.placeholders) { if (nestedPlaceholder.isFinalTabstop) { - nestedPlaceholder.index = `${placeholder.index}.${nested._snippet.placeholders.length}`; + nestedPlaceholder.index = placeholder.index + (nested._snippet.placeholders.length / 10); } else { - nestedPlaceholder.index = `${placeholder.index}.${nestedPlaceholder.index}`; + nestedPlaceholder.index = placeholder.index + (nestedPlaceholder.index / 10); } } this._snippet.replace(placeholder, nested._snippet.children); diff --git a/src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts b/src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts index 874aadd1c56..e49a98baf39 100644 --- a/src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts +++ b/src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts @@ -381,4 +381,12 @@ suite('SnippetParser', () => { assert.equal(snippet.text, 'aaabbbdddeee'); assert.equal(snippet.placeholders.length, 3); }); + + test('Snippet order for placeholders, #28185', function () { + + const _10 = new Placeholder(10, []); + const _2 = new Placeholder(2, []); + + assert.equal(Placeholder.compareByIndex(_10, _2), 1); + }); }); diff --git a/src/vs/workbench/parts/emmet/electron-browser/editorAccessor.ts b/src/vs/workbench/parts/emmet/electron-browser/editorAccessor.ts index 66d77c525f9..dcc5e5ad74d 100644 --- a/src/vs/workbench/parts/emmet/electron-browser/editorAccessor.ts +++ b/src/vs/workbench/parts/emmet/electron-browser/editorAccessor.ts @@ -120,7 +120,7 @@ export class EditorAccessor implements emmet.Editor { // find highest placeholder index walk(marker, candidate => { if (candidate instanceof Placeholder) { - let index = Number(candidate.index); + let index = candidate.index; if (index > maxIndex) { maxIndex = index; } @@ -132,7 +132,7 @@ export class EditorAccessor implements emmet.Editor { walk(marker, candidate => { if (candidate instanceof Placeholder) { if (candidate.isFinalTabstop) { - candidate.index = String(++maxIndex); + candidate.index = ++maxIndex; } } return true;