提交 377eabe6 编写于 作者: M Matt Bierner

Add optional CompletionContext to provideCompletionItems

Fixes #752

Adds a new overload of `provideCompletionItems` that takes a context argument. This context is currently used to provide the trigger character of the suggestion
上级 b86108e5
...@@ -247,6 +247,13 @@ export interface ISuggestResult { ...@@ -247,6 +247,13 @@ export interface ISuggestResult {
dispose?(): void; dispose?(): void;
} }
/**
* @internal
*/
export interface SuggestContext {
triggerCharacter?: string;
}
/** /**
* @internal * @internal
*/ */
...@@ -254,7 +261,7 @@ export interface ISuggestSupport { ...@@ -254,7 +261,7 @@ export interface ISuggestSupport {
triggerCharacters?: string[]; triggerCharacters?: string[];
provideCompletionItems(model: editorCommon.IModel, position: Position, token: CancellationToken): ISuggestResult | Thenable<ISuggestResult>; provideCompletionItems(model: editorCommon.IModel, position: Position, context: SuggestContext, token: CancellationToken): ISuggestResult | Thenable<ISuggestResult>;
resolveCompletionItem?(model: editorCommon.IModel, position: Position, item: ISuggestion, token: CancellationToken): ISuggestion | Thenable<ISuggestion>; resolveCompletionItem?(model: editorCommon.IModel, position: Position, item: ISuggestion, token: CancellationToken): ISuggestion | Thenable<ISuggestion>;
} }
......
...@@ -12,7 +12,7 @@ import { onUnexpectedExternalError } from 'vs/base/common/errors'; ...@@ -12,7 +12,7 @@ import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { IModel, IEditorContribution, ICommonCodeEditor } from 'vs/editor/common/editorCommon'; import { IModel, IEditorContribution, ICommonCodeEditor } from 'vs/editor/common/editorCommon';
import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions'; import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
import { ISuggestResult, ISuggestSupport, ISuggestion, SuggestRegistry } from 'vs/editor/common/modes'; import { ISuggestResult, ISuggestSupport, ISuggestion, SuggestRegistry, SuggestContext } from 'vs/editor/common/modes';
import { Position, IPosition } from 'vs/editor/common/core/position'; import { Position, IPosition } from 'vs/editor/common/core/position';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
...@@ -42,7 +42,7 @@ export function setSnippetSuggestSupport(support: ISuggestSupport): ISuggestSupp ...@@ -42,7 +42,7 @@ export function setSnippetSuggestSupport(support: ISuggestSupport): ISuggestSupp
return old; return old;
} }
export function provideSuggestionItems(model: IModel, position: Position, snippetConfig: SnippetConfig = 'bottom', onlyFrom?: ISuggestSupport[]): TPromise<ISuggestionItem[]> { export function provideSuggestionItems(model: IModel, position: Position, snippetConfig: SnippetConfig = 'bottom', onlyFrom?: ISuggestSupport[], context?: SuggestContext): TPromise<ISuggestionItem[]> {
const allSuggestions: ISuggestionItem[] = []; const allSuggestions: ISuggestionItem[] = [];
const acceptSuggestion = createSuggesionFilter(snippetConfig); const acceptSuggestion = createSuggesionFilter(snippetConfig);
...@@ -73,7 +73,7 @@ export function provideSuggestionItems(model: IModel, position: Position, snippe ...@@ -73,7 +73,7 @@ export function provideSuggestionItems(model: IModel, position: Position, snippe
return undefined; return undefined;
} }
return asWinJsPromise(token => support.provideCompletionItems(model, position, token)).then(container => { return asWinJsPromise(token => support.provideCompletionItems(model, position, context || {}, token)).then(container => {
const len = allSuggestions.length; const len = allSuggestions.length;
......
...@@ -209,7 +209,7 @@ export class SuggestController implements IEditorContribution { ...@@ -209,7 +209,7 @@ export class SuggestController implements IEditorContribution {
} }
triggerSuggest(onlyFrom?: ISuggestSupport[]): void { triggerSuggest(onlyFrom?: ISuggestSupport[]): void {
this._model.trigger(false, false, onlyFrom); this._model.trigger({ auto: false }, false, onlyFrom);
this._editor.revealLine(this._editor.getPosition().lineNumber, ScrollType.Smooth); this._editor.revealLine(this._editor.getPosition().lineNumber, ScrollType.Smooth);
this._editor.focus(); this._editor.focus();
} }
......
...@@ -31,6 +31,11 @@ export interface ISuggestEvent { ...@@ -31,6 +31,11 @@ export interface ISuggestEvent {
auto: boolean; auto: boolean;
} }
export interface SuggestTriggerContext {
auto: boolean;
triggerCharacter?: string;
}
export class LineContext { export class LineContext {
static shouldAutoTrigger(editor: ICommonCodeEditor): boolean { static shouldAutoTrigger(editor: ICommonCodeEditor): boolean {
...@@ -201,7 +206,7 @@ export class SuggestModel implements IDisposable { ...@@ -201,7 +206,7 @@ export class SuggestModel implements IDisposable {
} }
} }
} }
this.trigger(true, Boolean(this.completionModel), supports, items); this.trigger({ auto: true, triggerCharacter: lastChar }, Boolean(this.completionModel), supports, items);
} }
}); });
} }
...@@ -237,7 +242,7 @@ export class SuggestModel implements IDisposable { ...@@ -237,7 +242,7 @@ export class SuggestModel implements IDisposable {
if (!SuggestRegistry.has(this.editor.getModel())) { if (!SuggestRegistry.has(this.editor.getModel())) {
this.cancel(); this.cancel();
} else { } else {
this.trigger(this._state === State.Auto, true); this.trigger({ auto: this._state === State.Auto }, true);
} }
} }
} }
...@@ -311,7 +316,7 @@ export class SuggestModel implements IDisposable { ...@@ -311,7 +316,7 @@ export class SuggestModel implements IDisposable {
} }
this.triggerAutoSuggestPromise = null; this.triggerAutoSuggestPromise = null;
this.trigger(true); this.trigger({ auto: true });
}); });
} }
} }
...@@ -326,14 +331,14 @@ export class SuggestModel implements IDisposable { ...@@ -326,14 +331,14 @@ export class SuggestModel implements IDisposable {
} }
} }
public trigger(auto: boolean, retrigger: boolean = false, onlyFrom?: ISuggestSupport[], existingItems?: ISuggestionItem[]): void { public trigger(context: SuggestTriggerContext, retrigger: boolean = false, onlyFrom?: ISuggestSupport[], existingItems?: ISuggestionItem[]): void {
const model = this.editor.getModel(); const model = this.editor.getModel();
if (!model) { if (!model) {
return; return;
} }
const auto = context.auto;
const ctx = new LineContext(model, this.editor.getPosition(), auto); const ctx = new LineContext(model, this.editor.getPosition(), auto);
if (!LineContext.isInEditableRange(this.editor)) { if (!LineContext.isInEditableRange(this.editor)) {
...@@ -350,7 +355,8 @@ export class SuggestModel implements IDisposable { ...@@ -350,7 +355,8 @@ export class SuggestModel implements IDisposable {
this.requestPromise = provideSuggestionItems(model, this.editor.getPosition(), this.requestPromise = provideSuggestionItems(model, this.editor.getPosition(),
this.editor.getConfiguration().contribInfo.snippetSuggestions, this.editor.getConfiguration().contribInfo.snippetSuggestions,
onlyFrom onlyFrom,
context
).then(items => { ).then(items => {
this.requestPromise = null; this.requestPromise = null;
...@@ -394,7 +400,7 @@ export class SuggestModel implements IDisposable { ...@@ -394,7 +400,7 @@ export class SuggestModel implements IDisposable {
if (ctx.column < this.context.column) { if (ctx.column < this.context.column) {
// typed -> moved cursor LEFT -> retrigger if still on a word // typed -> moved cursor LEFT -> retrigger if still on a word
if (ctx.leadingWord.word) { if (ctx.leadingWord.word) {
this.trigger(this.context.auto, true); this.trigger({ auto: this.context.auto }, true);
} else { } else {
this.cancel(); this.cancel();
} }
...@@ -409,7 +415,7 @@ export class SuggestModel implements IDisposable { ...@@ -409,7 +415,7 @@ export class SuggestModel implements IDisposable {
if (ctx.column > this.context.column && this.completionModel.incomplete && ctx.leadingWord.word.length !== 0) { if (ctx.column > this.context.column && this.completionModel.incomplete && ctx.leadingWord.word.length !== 0) {
// typed -> moved cursor RIGHT & incomple model & still on a word -> retrigger // typed -> moved cursor RIGHT & incomple model & still on a word -> retrigger
const { complete, incomplete } = this.completionModel.resolveIncompleteInfo(); const { complete, incomplete } = this.completionModel.resolveIncompleteInfo();
this.trigger(this._state === State.Auto, true, incomplete, complete); this.trigger({ auto: this._state === State.Auto }, true, incomplete, complete);
} else { } else {
// typed -> moved cursor RIGHT -> update UI // typed -> moved cursor RIGHT -> update UI
...@@ -425,7 +431,7 @@ export class SuggestModel implements IDisposable { ...@@ -425,7 +431,7 @@ export class SuggestModel implements IDisposable {
if (LineContext.shouldAutoTrigger(this.editor) && this.context.leadingWord.endColumn < ctx.leadingWord.startColumn) { if (LineContext.shouldAutoTrigger(this.editor) && this.context.leadingWord.endColumn < ctx.leadingWord.startColumn) {
// retrigger when heading into a new word // retrigger when heading into a new word
this.trigger(this.context.auto, true); this.trigger({ auto: this.context.auto }, true);
return; return;
} }
......
...@@ -149,25 +149,25 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -149,25 +149,25 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
// cancel on trigger // cancel on trigger
assertEvent(model.onDidCancel, function () { assertEvent(model.onDidCancel, function () {
model.trigger(false); model.trigger({ auto: false });
}, function (event) { }, function (event) {
assert.equal(event.retrigger, false); assert.equal(event.retrigger, false);
}), }),
assertEvent(model.onDidCancel, function () { assertEvent(model.onDidCancel, function () {
model.trigger(false, true); model.trigger({ auto: false }, true);
}, function (event) { }, function (event) {
assert.equal(event.retrigger, true); assert.equal(event.retrigger, true);
}), }),
assertEvent(model.onDidTrigger, function () { assertEvent(model.onDidTrigger, function () {
model.trigger(true); model.trigger({ auto: true });
}, function (event) { }, function (event) {
assert.equal(event.auto, true); assert.equal(event.auto, true);
}), }),
assertEvent(model.onDidTrigger, function () { assertEvent(model.onDidTrigger, function () {
model.trigger(false); model.trigger({ auto: false });
}, function (event) { }, function (event) {
assert.equal(event.auto, false); assert.equal(event.auto, false);
}) })
...@@ -183,12 +183,12 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -183,12 +183,12 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
return withOracle(model => { return withOracle(model => {
return TPromise.join([ return TPromise.join([
assertEvent(model.onDidCancel, function () { assertEvent(model.onDidCancel, function () {
model.trigger(true); model.trigger({ auto: true });
}, function (event) { }, function (event) {
assert.equal(event.retrigger, false); assert.equal(event.retrigger, false);
}), }),
assertEvent(model.onDidSuggest, function () { assertEvent(model.onDidSuggest, function () {
model.trigger(false); model.trigger({ auto: false });
}, function (event) { }, function (event) {
assert.equal(event.auto, false); assert.equal(event.auto, false);
assert.equal(event.isFrozen, false); assert.equal(event.isFrozen, false);
...@@ -239,7 +239,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -239,7 +239,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
return assertEvent(model.onDidSuggest, () => { return assertEvent(model.onDidSuggest, () => {
// make sure completionModel starts here! // make sure completionModel starts here!
model.trigger(true); model.trigger({ auto: true });
}, event => { }, event => {
return assertEvent(model.onDidSuggest, () => { return assertEvent(model.onDidSuggest, () => {
...@@ -338,7 +338,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -338,7 +338,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
editor.setPosition({ lineNumber: 1, column: 3 }); editor.setPosition({ lineNumber: 1, column: 3 });
return assertEvent(model.onDidSuggest, () => { return assertEvent(model.onDidSuggest, () => {
model.trigger(false); model.trigger({ auto: false });
}, event => { }, event => {
assert.equal(event.auto, false); assert.equal(event.auto, false);
assert.equal(event.isFrozen, false); assert.equal(event.isFrozen, false);
...@@ -363,7 +363,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -363,7 +363,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
editor.setPosition({ lineNumber: 1, column: 3 }); editor.setPosition({ lineNumber: 1, column: 3 });
return assertEvent(model.onDidSuggest, () => { return assertEvent(model.onDidSuggest, () => {
model.trigger(false); model.trigger({ auto: false });
}, event => { }, event => {
assert.equal(event.auto, false); assert.equal(event.auto, false);
assert.equal(event.isFrozen, false); assert.equal(event.isFrozen, false);
...@@ -400,7 +400,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -400,7 +400,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
editor.setPosition({ lineNumber: 1, column: 4 }); editor.setPosition({ lineNumber: 1, column: 4 });
return assertEvent(model.onDidSuggest, () => { return assertEvent(model.onDidSuggest, () => {
model.trigger(false); model.trigger({ auto: false });
}, event => { }, event => {
assert.equal(event.auto, false); assert.equal(event.auto, false);
assert.equal(event.completionModel.incomplete, true); assert.equal(event.completionModel.incomplete, true);
...@@ -437,7 +437,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -437,7 +437,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
editor.setPosition({ lineNumber: 1, column: 4 }); editor.setPosition({ lineNumber: 1, column: 4 });
return assertEvent(model.onDidSuggest, () => { return assertEvent(model.onDidSuggest, () => {
model.trigger(false); model.trigger({ auto: false });
}, event => { }, event => {
assert.equal(event.auto, false); assert.equal(event.auto, false);
assert.equal(event.completionModel.incomplete, true); assert.equal(event.completionModel.incomplete, true);
...@@ -457,4 +457,38 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { ...@@ -457,4 +457,38 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
}); });
}); });
}); });
test('Trigger characters is provided in suggest context', function () {
let triggerCharacter = '';
disposables.push(SuggestRegistry.register({ scheme: 'test' }, {
triggerCharacters: ['.'],
provideCompletionItems(doc, pos, context) {
triggerCharacter = context.triggerCharacter;
return <ISuggestResult>{
currentWord: '',
incomplete: false,
suggestions: [
{
label: 'foo.bar',
type: 'property',
insertText: 'foo.bar',
overwriteBefore: pos.column - 1
}
]
};
}
}));
model.setValue('');
return withOracle((model, editor) => {
return assertEvent(model.onDidSuggest, () => {
editor.setPosition({ lineNumber: 1, column: 1 });
editor.trigger('keyboard', Handler.Type, { text: 'foo.' });
}, event => {
assert.equal(triggerCharacter, '.');
});
});
});
}); });
...@@ -373,8 +373,8 @@ export function registerCompletionItemProvider(languageId: string, provider: Com ...@@ -373,8 +373,8 @@ export function registerCompletionItemProvider(languageId: string, provider: Com
let adapter = new SuggestAdapter(provider); let adapter = new SuggestAdapter(provider);
return modes.SuggestRegistry.register(languageId, { return modes.SuggestRegistry.register(languageId, {
triggerCharacters: provider.triggerCharacters, triggerCharacters: provider.triggerCharacters,
provideCompletionItems: (model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<modes.ISuggestResult> => { provideCompletionItems: (model: editorCommon.IReadOnlyModel, position: Position, context: modes.SuggestContext, token: CancellationToken): Thenable<modes.ISuggestResult> => {
return adapter.provideCompletionItems(model, position, token); return adapter.provideCompletionItems(model, position, context, token);
}, },
resolveCompletionItem: (model: editorCommon.IReadOnlyModel, position: Position, suggestion: modes.ISuggestion, token: CancellationToken): Thenable<modes.ISuggestion> => { resolveCompletionItem: (model: editorCommon.IReadOnlyModel, position: Position, suggestion: modes.ISuggestion, token: CancellationToken): Thenable<modes.ISuggestion> => {
return adapter.resolveCompletionItem(model, position, suggestion, token); return adapter.resolveCompletionItem(model, position, suggestion, token);
...@@ -537,6 +537,23 @@ export interface CompletionList { ...@@ -537,6 +537,23 @@ export interface CompletionList {
*/ */
items: CompletionItem[]; items: CompletionItem[];
} }
/**
* Contains additional information about the context in which
* [completion provider](#CompletionItemProvider.provideCompletionItems) is triggered.
*/
export interface CompletionContext {
/**
* Character that triggered the completion item provider.
*
* Undefined if provider was not triggered by a character.
*/
triggerCharacter?: string;
}
export type ProviderCompletionItems = (document: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken) => CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>;
export type ProviderCompletionItemsForContext = (document: editorCommon.IReadOnlyModel, position: Position, context: CompletionContext, token: CancellationToken) => CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>;
/** /**
* The completion item provider interface defines the contract between extensions and * The completion item provider interface defines the contract between extensions and
* the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense). * the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense).
...@@ -553,7 +570,7 @@ export interface CompletionItemProvider { ...@@ -553,7 +570,7 @@ export interface CompletionItemProvider {
/** /**
* Provide completion items for the given position and document. * Provide completion items for the given position and document.
*/ */
provideCompletionItems(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>; provideCompletionItems: ProviderCompletionItems | ProviderCompletionItemsForContext;
/** /**
* Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation) * Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation)
* or [details](#CompletionItem.detail). * or [details](#CompletionItem.detail).
...@@ -639,9 +656,14 @@ class SuggestAdapter { ...@@ -639,9 +656,14 @@ class SuggestAdapter {
return suggestion; return suggestion;
} }
provideCompletionItems(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<modes.ISuggestResult> { provideCompletionItems(model: editorCommon.IReadOnlyModel, position: Position, context: modes.SuggestContext, token: CancellationToken): Thenable<modes.ISuggestResult> {
let request: any;
return toThenable<CompletionItem[] | CompletionList>(this._provider.provideCompletionItems(model, position, token)).then(value => { if (this._provider.provideCompletionItems.length <= 3) {
request = (this._provider.provideCompletionItems as ProviderCompletionItems)(model, position, token);
} else {
request = (this._provider.provideCompletionItems as ProviderCompletionItemsForContext)(model, position, context, token);
}
return toThenable<CompletionItem[] | CompletionList>(request).then(value => {
const result: modes.ISuggestResult = { const result: modes.ISuggestResult = {
suggestions: [] suggestions: []
}; };
......
...@@ -4229,6 +4229,23 @@ declare module monaco.languages { ...@@ -4229,6 +4229,23 @@ declare module monaco.languages {
items: CompletionItem[]; items: CompletionItem[];
} }
/**
* Contains additional information about the context in which
* [completion provider](#CompletionItemProvider.provideCompletionItems) is triggered.
*/
export interface CompletionContext {
/**
* Character that triggered the completion item provider.
*
* Undefined if provider was not triggered by a character.
*/
triggerCharacter?: string;
}
export type ProviderCompletionItems = (document: editor.IReadOnlyModel, position: Position, token: CancellationToken) => CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>;
export type ProviderCompletionItemsForContext = (document: editor.IReadOnlyModel, position: Position, context: CompletionContext, token: CancellationToken) => CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>;
/** /**
* The completion item provider interface defines the contract between extensions and * The completion item provider interface defines the contract between extensions and
* the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense). * the [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense).
...@@ -4245,7 +4262,7 @@ declare module monaco.languages { ...@@ -4245,7 +4262,7 @@ declare module monaco.languages {
/** /**
* Provide completion items for the given position and document. * Provide completion items for the given position and document.
*/ */
provideCompletionItems(model: editor.IReadOnlyModel, position: Position, token: CancellationToken): CompletionItem[] | Thenable<CompletionItem[]> | CompletionList | Thenable<CompletionList>; provideCompletionItems: ProviderCompletionItems | ProviderCompletionItemsForContext;
/** /**
* Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation) * Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation)
* or [details](#CompletionItem.detail). * or [details](#CompletionItem.detail).
......
...@@ -2718,6 +2718,22 @@ declare module 'vscode' { ...@@ -2718,6 +2718,22 @@ declare module 'vscode' {
constructor(items?: CompletionItem[], isIncomplete?: boolean); constructor(items?: CompletionItem[], isIncomplete?: boolean);
} }
/**
* Contains additional information about the context in which
* [completion provider](#CompletionItemProvider.provideCompletionItems) is triggered.
*/
export interface CompletionContext {
/**
* Character that triggered the completion item provider.
*
* Undefined if provider was not triggered by a character.
*/
readonly triggerCharacter?: string;
}
export type ProviderCompletionItems = (document: TextDocument, position: Position, token: CancellationToken) => ProviderResult<CompletionItem[] | CompletionList>;
export type ProviderCompletionItemsForContext = (document: TextDocument, position: Position, context: CompletionContext, token: CancellationToken) => ProviderResult<CompletionItem[] | CompletionList>;
/** /**
* The completion item provider interface defines the contract between extensions and * The completion item provider interface defines the contract between extensions and
* [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense). * [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense).
...@@ -2743,7 +2759,7 @@ declare module 'vscode' { ...@@ -2743,7 +2759,7 @@ declare module 'vscode' {
* @return An array of completions, a [completion list](#CompletionList), or a thenable that resolves to either. * @return An array of completions, a [completion list](#CompletionList), or a thenable that resolves to either.
* The lack of a result can be signaled by returning `undefined`, `null`, or an empty array. * The lack of a result can be signaled by returning `undefined`, `null`, or an empty array.
*/ */
provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<CompletionItem[] | CompletionList>; provideCompletionItems: ProviderCompletionItems | ProviderCompletionItemsForContext;
/** /**
* Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation) * Given a completion item fill in more data, like [doc-comment](#CompletionItem.documentation)
......
...@@ -233,8 +233,8 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha ...@@ -233,8 +233,8 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
this._registrations[handle] = modes.SuggestRegistry.register(selector, <modes.ISuggestSupport>{ this._registrations[handle] = modes.SuggestRegistry.register(selector, <modes.ISuggestSupport>{
triggerCharacters, triggerCharacters,
provideCompletionItems: (model: IReadOnlyModel, position: EditorPosition, token: CancellationToken): Thenable<modes.ISuggestResult> => { provideCompletionItems: (model: IReadOnlyModel, position: EditorPosition, context: modes.SuggestContext, token: CancellationToken): Thenable<modes.ISuggestResult> => {
return wireCancellationToken(token, this._proxy.$provideCompletionItems(handle, model.uri, position)).then(result => { return wireCancellationToken(token, this._proxy.$provideCompletionItems(handle, model.uri, position, context)).then(result => {
if (!result) { if (!result) {
return result; return result;
} }
......
...@@ -552,7 +552,7 @@ export interface ExtHostLanguageFeaturesShape { ...@@ -552,7 +552,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideWorkspaceSymbols(handle: number, search: string): TPromise<modes.SymbolInformation[]>; $provideWorkspaceSymbols(handle: number, search: string): TPromise<modes.SymbolInformation[]>;
$resolveWorkspaceSymbol(handle: number, symbol: modes.SymbolInformation): TPromise<modes.SymbolInformation>; $resolveWorkspaceSymbol(handle: number, symbol: modes.SymbolInformation): TPromise<modes.SymbolInformation>;
$provideRenameEdits(handle: number, resource: URI, position: IPosition, newName: string): TPromise<modes.WorkspaceEdit>; $provideRenameEdits(handle: number, resource: URI, position: IPosition, newName: string): TPromise<modes.WorkspaceEdit>;
$provideCompletionItems(handle: number, resource: URI, position: IPosition): TPromise<IExtHostSuggestResult>; $provideCompletionItems(handle: number, resource: URI, position: IPosition, context: modes.SuggestContext): TPromise<IExtHostSuggestResult>;
$resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion>; $resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion>;
$releaseCompletionItems(handle: number, id: number): void; $releaseCompletionItems(handle: number, id: number): void;
$provideSignatureHelp(handle: number, resource: URI, position: IPosition): TPromise<modes.SignatureHelp>; $provideSignatureHelp(handle: number, resource: URI, position: IPosition): TPromise<modes.SignatureHelp>;
......
...@@ -486,12 +486,17 @@ class SuggestAdapter { ...@@ -486,12 +486,17 @@ class SuggestAdapter {
this._provider = provider; this._provider = provider;
} }
provideCompletionItems(resource: URI, position: IPosition): TPromise<IExtHostSuggestResult> { provideCompletionItems(resource: URI, position: IPosition, context: modes.SuggestContext): TPromise<IExtHostSuggestResult> {
const doc = this._documents.getDocumentData(resource).document; const doc = this._documents.getDocumentData(resource).document;
const pos = TypeConverters.toPosition(position); const pos = TypeConverters.toPosition(position);
return asWinJsPromise<vscode.CompletionItem[] | vscode.CompletionList>(token => this._provider.provideCompletionItems(doc, pos, token)).then(value => { return asWinJsPromise<vscode.CompletionItem[] | vscode.CompletionList>(token => {
if (this._provider.provideCompletionItems.length <= 3) {
return (this._provider.provideCompletionItems as vscode.ProviderCompletionItems)(doc, pos, token);
}
return (this._provider.provideCompletionItems as vscode.ProviderCompletionItemsForContext)(doc, pos, context, token);
}).then(value => {
const _id = this._idPool++; const _id = this._idPool++;
...@@ -1001,8 +1006,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { ...@@ -1001,8 +1006,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle); return this._createDisposable(handle);
} }
$provideCompletionItems(handle: number, resource: URI, position: IPosition): TPromise<IExtHostSuggestResult> { $provideCompletionItems(handle: number, resource: URI, position: IPosition, context: modes.SuggestContext): TPromise<IExtHostSuggestResult> {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(resource, position)); return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(resource, position, context));
} }
$resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion> { $resolveCompletionItem(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion> {
......
...@@ -180,7 +180,7 @@ export class Repl extends Panel implements IPrivateReplService { ...@@ -180,7 +180,7 @@ export class Repl extends Panel implements IPrivateReplService {
modes.SuggestRegistry.register({ scheme: debug.DEBUG_SCHEME }, { modes.SuggestRegistry.register({ scheme: debug.DEBUG_SCHEME }, {
triggerCharacters: ['.'], triggerCharacters: ['.'],
provideCompletionItems: (model: IReadOnlyModel, position: Position, token: CancellationToken): Thenable<modes.ISuggestResult> => { provideCompletionItems: (model: IReadOnlyModel, position: Position, _context: modes.SuggestContext, token: CancellationToken): Thenable<modes.ISuggestResult> => {
const word = this.replInput.getModel().getWordAtPosition(position); const word = this.replInput.getModel().getWordAtPosition(position);
const overwriteBefore = word ? word.word.length : 0; const overwriteBefore = word ? word.word.length : 0;
const text = this.replInput.getModel().getLineContent(position.lineNumber); const text = this.replInput.getModel().getLineContent(position.lineNumber);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册