From 79ecb2a249bb2ee2dfbf8a74b36adc5493e36138 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 4 Mar 2020 12:16:26 +0100 Subject: [PATCH] prep for https://github.com/microsoft/vscode/issues/91427 --- .../browser/snippetCompletionProvider.ts | 134 +++++++++--------- 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts index 2e834ea32dc..ff9721cdfbb 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts @@ -66,92 +66,90 @@ export class SnippetCompletionProvider implements CompletionItemProvider { // } - provideCompletionItems(model: ITextModel, position: Position, context: CompletionContext): Promise | undefined { + async provideCompletionItems(model: ITextModel, position: Position, context: CompletionContext): Promise { if (position.column >= SnippetCompletionProvider._maxPrefix) { - return undefined; + return { suggestions: [] }; } if (context.triggerKind === CompletionTriggerKind.TriggerCharacter && context.triggerCharacter === ' ') { // no snippets when suggestions have been triggered by space - return undefined; + return { suggestions: [] }; } const languageId = this._getLanguageIdAtPosition(model, position); - return this._snippets.getSnippets(languageId).then(snippets => { - - let suggestions: SnippetCompletion[]; - let pos = { lineNumber: position.lineNumber, column: 1 }; - let lineOffsets: number[] = []; - const lineContent = model.getLineContent(position.lineNumber); - const linePrefixLow = lineContent.substr(0, position.column - 1).toLowerCase(); - let endsInWhitespace = linePrefixLow.match(/\s$/); - - while (pos.column < position.column) { - let word = model.getWordAtPosition(pos); - if (word) { - // at a word - lineOffsets.push(word.startColumn - 1); - pos.column = word.endColumn + 1; - if (word.endColumn - 1 < linePrefixLow.length && !/\s/.test(linePrefixLow[word.endColumn - 1])) { - lineOffsets.push(word.endColumn - 1); - } - } - else if (!/\s/.test(linePrefixLow[pos.column - 1])) { - // at a none-whitespace character - lineOffsets.push(pos.column - 1); - pos.column += 1; - } - else { - // always advance! - pos.column += 1; + const snippets = await this._snippets.getSnippets(languageId); + + let pos = { lineNumber: position.lineNumber, column: 1 }; + let lineOffsets: number[] = []; + const lineContent = model.getLineContent(position.lineNumber); + const linePrefixLow = lineContent.substr(0, position.column - 1).toLowerCase(); + const endsInWhitespace = linePrefixLow.match(/\s$/); + + while (pos.column < position.column) { + let word = model.getWordAtPosition(pos); + if (word) { + // at a word + lineOffsets.push(word.startColumn - 1); + pos.column = word.endColumn + 1; + if (word.endColumn < position.column && !/\s/.test(linePrefixLow[word.endColumn - 1])) { + lineOffsets.push(word.endColumn - 1); } } - - const lineSuffixLow = lineContent.substr(position.column - 1).toLowerCase(); - let availableSnippets = new Set(); - snippets.forEach(availableSnippets.add, availableSnippets); - suggestions = []; - for (let start of lineOffsets) { - availableSnippets.forEach(snippet => { - if (isPatternInWord(linePrefixLow, start, linePrefixLow.length, snippet.prefixLow, 0, snippet.prefixLow.length)) { - const snippetPrefixSubstr = snippet.prefixLow.substr(linePrefixLow.length - start); - const endColumn = startsWith(lineSuffixLow, snippetPrefixSubstr) ? position.column + snippetPrefixSubstr.length : position.column; - const replace = Range.fromPositions(position.delta(0, -(linePrefixLow.length - start)), { lineNumber: position.lineNumber, column: endColumn }); - const insert = replace.setEndPosition(position.lineNumber, position.column); - - suggestions.push(new SnippetCompletion(snippet, { replace, insert })); - availableSnippets.delete(snippet); - } - }); + else if (!/\s/.test(linePrefixLow[pos.column - 1])) { + // at a none-whitespace character + lineOffsets.push(pos.column - 1); + pos.column += 1; } - if (endsInWhitespace || lineOffsets.length === 0) { - // add remaing snippets when the current prefix ends in whitespace or when no - // interesting positions have been found - availableSnippets.forEach(snippet => { - let insert = Range.fromPositions(position); - let replace = startsWith(lineSuffixLow, snippet.prefixLow) ? insert.setEndPosition(position.lineNumber, position.column + snippet.prefixLow.length) : insert; - suggestions.push(new SnippetCompletion(snippet, { replace, insert })); - }); + else { + // always advance! + pos.column += 1; } + } + const lineSuffixLow = lineContent.substr(position.column - 1).toLowerCase(); + const availableSnippets = new Set(snippets); + const suggestions: SnippetCompletion[] = []; - // dismbiguate suggestions with same labels - suggestions.sort(SnippetCompletion.compareByLabel); - for (let i = 0; i < suggestions.length; i++) { - let item = suggestions[i]; - let to = i + 1; - for (; to < suggestions.length && item.label === suggestions[to].label; to++) { - suggestions[to].label.name = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[to].label.name, suggestions[to].snippet.name); - } - if (to > i + 1) { - suggestions[i].label.name = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[i].label.name, suggestions[i].snippet.name); - i = to; + for (let start of lineOffsets) { + availableSnippets.forEach(snippet => { + if (isPatternInWord(linePrefixLow, start, linePrefixLow.length, snippet.prefixLow, 0, snippet.prefixLow.length)) { + const snippetPrefixSubstr = snippet.prefixLow.substr(linePrefixLow.length - start); + const endColumn = startsWith(lineSuffixLow, snippetPrefixSubstr) ? position.column + snippetPrefixSubstr.length : position.column; + const replace = Range.fromPositions(position.delta(0, -(linePrefixLow.length - start)), { lineNumber: position.lineNumber, column: endColumn }); + const insert = replace.setEndPosition(position.lineNumber, position.column); + + suggestions.push(new SnippetCompletion(snippet, { replace, insert })); + availableSnippets.delete(snippet); } + }); + } + if (endsInWhitespace || lineOffsets.length === 0) { + // add remaing snippets when the current prefix ends in whitespace or when no + // interesting positions have been found + availableSnippets.forEach(snippet => { + let insert = Range.fromPositions(position); + let replace = startsWith(lineSuffixLow, snippet.prefixLow) ? insert.setEndPosition(position.lineNumber, position.column + snippet.prefixLow.length) : insert; + suggestions.push(new SnippetCompletion(snippet, { replace, insert })); + }); + } + + + // dismbiguate suggestions with same labels + suggestions.sort(SnippetCompletion.compareByLabel); + for (let i = 0; i < suggestions.length; i++) { + let item = suggestions[i]; + let to = i + 1; + for (; to < suggestions.length && item.label === suggestions[to].label; to++) { + suggestions[to].label.name = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[to].label.name, suggestions[to].snippet.name); + } + if (to > i + 1) { + suggestions[i].label.name = localize('snippetSuggest.longLabel', "{0}, {1}", suggestions[i].label.name, suggestions[i].snippet.name); + i = to; } + } - return { suggestions }; - }); + return { suggestions }; } resolveCompletionItem(_model: ITextModel, _position: Position, item: CompletionItem): CompletionItem { -- GitLab