This commit is contained in:
Johannes Rieken 2021-12-13 10:59:55 +01:00
parent ff8f37a796
commit a5924046c2
No known key found for this signature in database
GPG key ID: 96634B5AF12F8798
2 changed files with 31 additions and 5 deletions

View file

@ -17,6 +17,7 @@ import { Snippet, SnippetSource } from 'vs/workbench/contrib/snippets/browser/sn
import { isPatternInWord } from 'vs/base/common/filters';
import { StopWatch } from 'vs/base/common/stopwatch';
import { ILanguageConfigurationService } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { getWordAtText } from 'vs/editor/common/model/wordHelper';
export class SnippetCompletion implements CompletionItem {
@ -68,6 +69,7 @@ export class SnippetCompletionProvider implements CompletionItemProvider {
const sw = new StopWatch(true);
const languageId = this._getLanguageIdAtPosition(model, position);
const languageConfig = this._languageConfigurationService.getLanguageConfiguration(languageId);
const snippets = new Set(await this._snippets.getSnippets(languageId));
const lineContentLow = model.getLineContent(position.lineNumber).toLowerCase();
@ -78,9 +80,12 @@ export class SnippetCompletionProvider implements CompletionItemProvider {
const triggerCharacterLow = context.triggerCharacter?.toLowerCase() ?? '';
for (const snippet of snippets) {
if (wordUntil && snippet.prefixLow.length < wordUntil.length && !isPatternInWord(snippet.prefixLow, 0, snippet.prefixLow.length, wordUntil, 0, wordUntil.length)) {
const word = getWordAtText(1, languageConfig.getWordDefinition(), snippet.prefixLow, 0);
if (wordUntil && word && !isPatternInWord(wordUntil, 0, wordUntil.length, snippet.prefixLow, 0, snippet.prefixLow.length)) {
// when at a word the snippet prefix must match
continue;
}
@ -104,7 +109,7 @@ export class SnippetCompletionProvider implements CompletionItemProvider {
// First check if there is anything to the right of the cursor
if (columnOffset < lineContentLow.length) {
const autoClosingPairs = this._languageConfigurationService.getLanguageConfiguration(languageId).getAutoClosingPairs();
const autoClosingPairs = languageConfig.getAutoClosingPairs();
const standardAutoClosingPairConditionals = autoClosingPairs.autoClosingPairsCloseSingleChar.get(lineContentLow[columnOffset]);
// If the character to the right of the cursor is a closing character of an autoclosing pair
if (standardAutoClosingPairConditionals?.some(p =>

View file

@ -650,7 +650,7 @@ suite('SnippetsService', function () {
test('Snippet suggestions are too eager #138707 (word)', async function () {
snippetService = new SimpleSnippetService([
new Snippet(['fooLang'], 'tys', 'tys', '', 'value', '', SnippetSource.User),
new Snippet(['fooLang'], 't', 't', '', 'value', '', SnippetSource.User),
new Snippet(['fooLang'], 'hell_or_tell', 'hell_or_tell', '', 'value', '', SnippetSource.User),
new Snippet(['fooLang'], '^y', '^y', '', 'value', '', SnippetSource.User),
]);
@ -663,8 +663,9 @@ suite('SnippetsService', function () {
{ triggerKind: CompletionTriggerKind.Invoke }
)!;
assert.strictEqual(result.suggestions.length, 1);
assert.strictEqual((<SnippetCompletion>result.suggestions[0]).label.label, 't');
assert.strictEqual(result.suggestions.length, 2);
assert.strictEqual((<SnippetCompletion>result.suggestions[0]).label.label, '^y');
assert.strictEqual((<SnippetCompletion>result.suggestions[1]).label.label, 'hell_or_tell');
model.dispose();
});
@ -688,4 +689,24 @@ suite('SnippetsService', function () {
assert.strictEqual((<SnippetCompletion>result.suggestions[0]).label.label, '^y');
model.dispose();
});
test('Snippet suggestions are too eager #138707 (word/word)', async function () {
snippetService = new SimpleSnippetService([
new Snippet(['fooLang'], 'async arrow function', 'async arrow function', '', 'value', '', SnippetSource.User),
new Snippet(['fooLang'], 'foobarrrrrr', 'foobarrrrrr', '', 'value', '', SnippetSource.User),
]);
const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService());
let model = createTextModel('foobar', undefined, 'fooLang');
let result = await provider.provideCompletionItems(
model,
new Position(1, 7),
{ triggerKind: CompletionTriggerKind.Invoke }
)!;
assert.strictEqual(result.suggestions.length, 1);
assert.strictEqual((<SnippetCompletion>result.suggestions[0]).label.label, 'foobarrrrrr');
model.dispose();
});
});