提交 a8770233 编写于 作者: J Johannes Rieken

word based completions use insert and replace ranges, #10266

上级 cab4cb5d
......@@ -17,7 +17,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import { EndOfLineSequence, IWordAtPosition } from 'vs/editor/common/model';
import { IModelChangedEvent, MirrorTextModel as BaseMirrorModel } from 'vs/editor/common/model/mirrorTextModel';
import { ensureValidWordDefinition, getWordAtText } from 'vs/editor/common/model/wordHelper';
import { CompletionItem, CompletionItemKind, CompletionList, IInplaceReplaceSupportResult, ILink, TextEdit } from 'vs/editor/common/modes';
import { IInplaceReplaceSupportResult, ILink, TextEdit } from 'vs/editor/common/modes';
import { ILinkComputerTarget, computeLinks } from 'vs/editor/common/modes/linkComputer';
import { BasicInplaceReplace } from 'vs/editor/common/modes/supports/inplaceReplaceSupport';
import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService';
......@@ -529,44 +529,38 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
private static readonly _suggestionsLimit = 10000;
public async textualSuggest(modelUrl: string, position: IPosition, wordDef: string, wordDefFlags: string): Promise<CompletionList | null> {
public async textualSuggest(modelUrl: string, position: IPosition, wordDef: string, wordDefFlags: string): Promise<string[] | null> {
const model = this._getModel(modelUrl);
if (!model) {
return null;
}
const seen: Record<string, boolean> = Object.create(null);
const suggestions: CompletionItem[] = [];
const words: string[] = [];
const seen = new Set<string>();
const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
const wordUntil = model.getWordUntilPosition(position, wordDefRegExp);
const wordAt = model.getWordAtPosition(position, wordDefRegExp);
if (wordAt) {
seen[model.getValueInRange(wordAt)] = true;
seen.add(model.getValueInRange(wordAt));
}
for (
let iter = model.createWordIterator(wordDefRegExp), e = iter.next();
!e.done && suggestions.length <= EditorSimpleWorker._suggestionsLimit;
!e.done && seen.size <= EditorSimpleWorker._suggestionsLimit;
e = iter.next()
) {
const word = e.value;
if (seen[word]) {
if (seen.has(word)) {
continue;
}
seen[word] = true;
seen.add(word);
if (!isNaN(Number(word))) {
continue;
}
suggestions.push({
kind: CompletionItemKind.Text,
label: word,
insertText: word,
range: { startLineNumber: position.lineNumber, startColumn: wordUntil.startColumn, endLineNumber: position.lineNumber, endColumn: wordUntil.endColumn }
});
words.push(word);
}
return { suggestions };
return words;
}
......
......@@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
import { SimpleWorkerClient, logOnceWebWorkerWarning, IWorkerClient } from 'vs/base/common/worker/simpleWorker';
import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { IRange } from 'vs/editor/common/core/range';
import { IRange, Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { ITextModel } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
......@@ -144,7 +144,7 @@ class WordBasedCompletionItemProvider implements modes.CompletionItemProvider {
this._modelService = modelService;
}
provideCompletionItems(model: ITextModel, position: Position): Promise<modes.CompletionList | null> | undefined {
async provideCompletionItems(model: ITextModel, position: Position): Promise<modes.CompletionList | undefined> {
const { wordBasedSuggestions } = this._configurationService.getValue<{ wordBasedSuggestions?: boolean }>(model.uri, position, 'editor');
if (!wordBasedSuggestions) {
return undefined;
......@@ -152,7 +152,27 @@ class WordBasedCompletionItemProvider implements modes.CompletionItemProvider {
if (!canSyncModel(this._modelService, model.uri)) {
return undefined; // File too large
}
return this._workerManager.withWorker().then(client => client.textualSuggest(model.uri, position));
const client = await this._workerManager.withWorker();
const words = await client.textualSuggest(model.uri, position);
if (!words) {
return undefined;
}
const word = model.getWordAtPosition(position);
const replace = !word ? Range.fromPositions(position) : new Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);
const insert = replace.setEndPosition(position.lineNumber, position.column);
return {
suggestions: words.map((word): modes.CompletionItem => {
return {
kind: modes.CompletionItemKind.Text,
label: word,
insertText: word,
range: { insert, replace }
};
})
};
}
}
......@@ -433,7 +453,7 @@ export class EditorWorkerClient extends Disposable {
});
}
public textualSuggest(resource: URI, position: IPosition): Promise<modes.CompletionList | null> {
public textualSuggest(resource: URI, position: IPosition): Promise<string[] | null> {
return this._withSyncedResources([resource]).then(proxy => {
let model = this._modelService.getModel(resource);
if (!model) {
......
......@@ -167,9 +167,8 @@ suite('EditorSimpleWorker', () => {
assert.ok(false);
return;
}
const { suggestions } = result;
assert.equal(suggestions.length, 1);
assert.equal(suggestions[0].label, 'foobar');
assert.equal(result.length, 1);
assert.equal(result, 'foobar');
});
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册