Skip to content

Commit 4ae2f38

Browse files
authored
Merge pull request microsoft#76294 from microsoft/joh/suggest-explain
Add explain mode
2 parents df8e3f0 + 162c502 commit 4ae2f38

7 files changed

Lines changed: 51 additions & 13 deletions

File tree

src/vs/editor/common/modes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,11 @@ export interface CompletionContext {
510510
*/
511511
export interface CompletionItemProvider {
512512

513+
/**
514+
* @internal
515+
*/
516+
_debugDisplayName?: string;
517+
513518
triggerCharacters?: string[];
514519
/**
515520
* Provide completion items for the given position and document.

src/vs/editor/common/services/editorWorkerServiceImpl.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class WordBasedCompletionItemProvider implements modes.CompletionItemProvider {
133133
private readonly _configurationService: ITextResourceConfigurationService;
134134
private readonly _modelService: IModelService;
135135

136+
readonly _debugDisplayName = 'wordbasedCompletions';
137+
136138
constructor(
137139
workerManager: WorkerManager,
138140
configurationService: ITextResourceConfigurationService,

src/vs/editor/contrib/suggest/suggestWidget.ts

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import { IModelService } from 'vs/editor/common/services/modelService';
3737
import { URI } from 'vs/base/common/uri';
3838
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
3939
import { FileKind } from 'vs/platform/files/common/files';
40+
import { MarkdownString } from 'vs/base/common/htmlContent';
41+
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
42+
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
4043

4144
const expandSuggestionDocsByDefault = false;
4245

@@ -228,6 +231,18 @@ const enum State {
228231
Details
229232
}
230233

234+
235+
let _explainMode = false;
236+
KeybindingsRegistry.registerCommandAndKeybindingRule({
237+
id: 'suggest.toggleExplainMode',
238+
handler() {
239+
_explainMode = !_explainMode;
240+
},
241+
when: SuggestContext.Visible,
242+
weight: KeybindingWeight.EditorContrib,
243+
primary: KeyMod.CtrlCmd | KeyCode.US_SLASH,
244+
});
245+
231246
class SuggestionDetails {
232247

233248
private el: HTMLElement;
@@ -247,7 +262,7 @@ class SuggestionDetails {
247262
private readonly widget: SuggestWidget,
248263
private readonly editor: ICodeEditor,
249264
private readonly markdownRenderer: MarkdownRenderer,
250-
private readonly triggerKeybindingLabel: string
265+
private readonly triggerKeybindingLabel: string,
251266
) {
252267
this.disposables = [];
253268

@@ -289,27 +304,40 @@ class SuggestionDetails {
289304
renderItem(item: CompletionItem): void {
290305
this.renderDisposeable = dispose(this.renderDisposeable);
291306

292-
if (!item || !canExpandCompletionItem(item)) {
307+
let { documentation, detail } = item.completion;
308+
// --- documentation
309+
310+
if (_explainMode) {
311+
let md = '';
312+
md += `score: ${item.score[0]}${item.word ? `, compared '${item.completion.filterText && (item.completion.filterText + ' (filterText)') || item.completion.label}' with '${item.word}'` : ' (no prefix)'}\n`;
313+
md += `distance: ${item.distance}, see localityBonus-setting\n`;
314+
md += `index: ${item.idx}, based on ${item.completion.sortText && `sortText: "${item.completion.sortText}"` || 'label'}\n`;
315+
documentation = new MarkdownString().appendCodeblock('empty', md);
316+
detail = `Provider: ${item.provider._debugDisplayName}`;
317+
}
318+
319+
if (!_explainMode && !canExpandCompletionItem(item)) {
293320
this.type.textContent = '';
294321
this.docs.textContent = '';
295322
addClass(this.el, 'no-docs');
296323
this.ariaLabel = null;
297324
return;
298325
}
299326
removeClass(this.el, 'no-docs');
300-
if (typeof item.completion.documentation === 'string') {
327+
if (typeof documentation === 'string') {
301328
removeClass(this.docs, 'markdown-docs');
302-
this.docs.textContent = item.completion.documentation;
329+
this.docs.textContent = documentation;
303330
} else {
304331
addClass(this.docs, 'markdown-docs');
305332
this.docs.innerHTML = '';
306-
const renderedContents = this.markdownRenderer.render(item.completion.documentation);
333+
const renderedContents = this.markdownRenderer.render(documentation);
307334
this.renderDisposeable = renderedContents;
308335
this.docs.appendChild(renderedContents.element);
309336
}
310337

311-
if (item.completion.detail) {
312-
this.type.innerText = item.completion.detail;
338+
// --- details
339+
if (detail) {
340+
this.type.innerText = detail;
313341
show(this.type);
314342
} else {
315343
this.type.innerText = '';
@@ -333,8 +361,8 @@ class SuggestionDetails {
333361

334362
this.ariaLabel = strings.format(
335363
'{0}{1}',
336-
item.completion.detail || '',
337-
item.completion.documentation ? (typeof item.completion.documentation === 'string' ? item.completion.documentation : item.completion.documentation.value) : '');
364+
detail || '',
365+
documentation ? (typeof documentation === 'string' ? documentation : documentation.value) : '');
338366
}
339367

340368
getAriaLabel() {
@@ -479,7 +507,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
479507

480508
this.messageElement = append(this.element, $('.message'));
481509
this.listElement = append(this.element, $('.tree'));
482-
this.details = new SuggestionDetails(this.element, this, this.editor, markdownRenderer, triggerKeybindingLabel);
510+
this.details = instantiationService.createInstance(SuggestionDetails, this.element, this, this.editor, markdownRenderer, triggerKeybindingLabel);
483511

484512
const applyIconStyle = () => toggleClass(this.element, 'no-icons', !this.editor.getConfiguration().contribInfo.suggest.showIcons);
485513
applyIconStyle();

src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,10 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
346346
};
347347
}
348348

349-
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean): void {
349+
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void {
350350
const provider: modes.CompletionItemProvider = {
351351
triggerCharacters,
352+
_debugDisplayName: extensionId.value,
352353
provideCompletionItems: (model: ITextModel, position: EditorPosition, context: modes.CompletionContext, token: CancellationToken): Promise<modes.CompletionList | undefined> => {
353354
return this._proxy.$provideCompletionItems(handle, model.uri, position, context, token).then(result => {
354355
if (!result) {

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
348348
$registerOnTypeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void;
349349
$registerNavigateTypeSupport(handle: number): void;
350350
$registerRenameSupport(handle: number, selector: ISerializedDocumentFilter[], supportsResolveInitialValues: boolean): void;
351-
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean): void;
351+
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void;
352352
$registerSignatureHelpProvider(handle: number, selector: ISerializedDocumentFilter[], metadata: ISerializedSignatureHelpProviderMetadata): void;
353353
$registerDocumentLinkProvider(handle: number, selector: ISerializedDocumentFilter[], supportsResolve: boolean): void;
354354
$registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void;

src/vs/workbench/api/common/extHostLanguageFeatures.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
13801380

13811381
registerCompletionItemProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable {
13821382
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider), extension);
1383-
this._proxy.$registerSuggestSupport(handle, this._transformDocumentSelector(selector), triggerCharacters, SuggestAdapter.supportsResolving(provider));
1383+
this._proxy.$registerSuggestSupport(handle, this._transformDocumentSelector(selector), triggerCharacters, SuggestAdapter.supportsResolving(provider), extension.identifier);
13841384
return this._createDisposable(handle);
13851385
}
13861386

src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ export class SnippetCompletionProvider implements CompletionItemProvider {
6464

6565
private static readonly _maxPrefix = 10000;
6666

67+
readonly _debugDisplayName = 'snippetCompletions';
68+
6769
constructor(
6870
@IModeService
6971
private readonly _modeService: IModeService,

0 commit comments

Comments
 (0)