diff --git a/extensions/terminal-suggest/src/completions/code-insiders.ts b/extensions/terminal-suggest/src/completions/code-insiders.ts index 8014c97e8c1..89d01dc536f 100644 --- a/extensions/terminal-suggest/src/completions/code-insiders.ts +++ b/extensions/terminal-suggest/src/completions/code-insiders.ts @@ -7,6 +7,7 @@ import code from './code'; const codeInsidersCompletionSpec: Fig.Spec = { ...code, name: 'code-insiders', + description: 'Visual Studio Code Insiders', }; export default codeInsidersCompletionSpec; diff --git a/extensions/terminal-suggest/src/terminalSuggestMain.ts b/extensions/terminal-suggest/src/terminalSuggestMain.ts index 66d0962d623..6072cd048f4 100644 --- a/extensions/terminal-suggest/src/terminalSuggestMain.ts +++ b/extensions/terminal-suggest/src/terminalSuggestMain.ts @@ -198,7 +198,12 @@ export async function resolveCwdFromPrefix(prefix: string, currentCwd?: vscode.U // If the prefix is not a folder, return the current cwd return currentCwd; } - +function getDescription(spec: Fig.Spec): string { + if ('description' in spec) { + return spec.description ?? ''; + } + return ''; +} function getLabel(spec: Fig.Spec | Fig.Arg | Fig.Suggestion | string): string[] | undefined { if (typeof spec === 'string') { @@ -213,12 +218,13 @@ function getLabel(spec: Fig.Spec | Fig.Arg | Fig.Suggestion | string): string[] return spec.name; } -function createCompletionItem(cursorPosition: number, prefix: string, commandResource: ICompletionResource, description?: string, kind?: vscode.TerminalCompletionItemKind): vscode.TerminalCompletionItem { +function createCompletionItem(cursorPosition: number, prefix: string, commandResource: ICompletionResource, detail?: string, documentation?: string | vscode.MarkdownString, kind?: vscode.TerminalCompletionItemKind): vscode.TerminalCompletionItem { const endsWithSpace = prefix.endsWith(' '); const lastWord = endsWithSpace ? '' : prefix.split(' ').at(-1) ?? ''; return { label: commandResource.label, - detail: description ?? commandResource.detail ?? '', + detail: detail ?? commandResource.detail ?? '', + documentation, replacementIndex: cursorPosition - lastWord.length, replacementLength: lastWord.length, kind: kind ?? vscode.TerminalCompletionItemKind.Method @@ -327,7 +333,8 @@ export async function getCompletionItemsFromSpecs( } for (const specLabel of specLabels) { - if (!availableCommands.find(command => command.label === specLabel) || (token && token.isCancellationRequested)) { + const availableCommand = availableCommands.find(command => command.label === specLabel); + if (!availableCommand || (token && token.isCancellationRequested)) { continue; } @@ -338,7 +345,7 @@ export async function getCompletionItemsFromSpecs( || !!firstCommand && specLabel.startsWith(firstCommand) ) { // push it to the completion items - items.push(createCompletionItem(terminalContext.cursorPosition, prefix, { label: specLabel })); + items.push(createCompletionItem(terminalContext.cursorPosition, prefix, { label: specLabel }, availableCommand.detail, getDescription(spec))); } if (!terminalContext.commandLine.startsWith(specLabel)) { @@ -374,7 +381,7 @@ export async function getCompletionItemsFromSpecs( const labels = new Set(items.map((i) => i.label)); for (const command of availableCommands) { if (!labels.has(command.label)) { - items.push(createCompletionItem(terminalContext.cursorPosition, prefix, command)); + items.push(createCompletionItem(terminalContext.cursorPosition, prefix, command, command.detail)); } } } @@ -445,6 +452,7 @@ function handleOptions(specLabel: string, spec: Fig.Spec, terminalContext: { com prefix, { label: optionLabel }, option.description, + undefined, vscode.TerminalCompletionItemKind.Flag ) ); @@ -505,7 +513,7 @@ function getCompletionItemsFromArgs(args: Fig.SingleOrArray | undefined } if (suggestionLabel && suggestionLabel.startsWith(currentPrefix.trim())) { const description = typeof suggestion !== 'string' ? suggestion.description : ''; - items.push(createCompletionItem(terminalContext.cursorPosition, wordBefore ?? '', { label: suggestionLabel }, description, vscode.TerminalCompletionItemKind.Argument)); + items.push(createCompletionItem(terminalContext.cursorPosition, wordBefore ?? '', { label: suggestionLabel }, description, undefined, vscode.TerminalCompletionItemKind.Argument)); } } } diff --git a/src/vs/workbench/services/suggest/browser/simpleCompletionItem.ts b/src/vs/workbench/services/suggest/browser/simpleCompletionItem.ts index 466a979d196..9af7f683e6b 100644 --- a/src/vs/workbench/services/suggest/browser/simpleCompletionItem.ts +++ b/src/vs/workbench/services/suggest/browser/simpleCompletionItem.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { FuzzyScore } from '../../../../base/common/filters.js'; +import { MarkdownString } from '../../../../base/common/htmlContent.js'; import { isWindows } from '../../../../base/common/platform.js'; import { ThemeIcon } from '../../../../base/common/themables.js'; @@ -24,6 +25,12 @@ export interface ISimpleCompletion { * The completion's detail which appears on the right of the list. */ detail?: string; + + /** + * A human-readable string that represents a doc-comment. + */ + documentation?: string | MarkdownString; + /** * Whether the completion is a file. Files with the same score will be sorted against each other * first by extension length and then certain extensions will get a boost based on the OS. diff --git a/src/vs/workbench/services/suggest/browser/simpleSuggestWidgetDetails.ts b/src/vs/workbench/services/suggest/browser/simpleSuggestWidgetDetails.ts index 02816974549..3d52d75c938 100644 --- a/src/vs/workbench/services/suggest/browser/simpleSuggestWidgetDetails.ts +++ b/src/vs/workbench/services/suggest/browser/simpleSuggestWidgetDetails.ts @@ -18,7 +18,7 @@ import { MarkdownRenderer } from '../../../../editor/browser/widget/markdownRend import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; export function canExpandCompletionItem(item: SimpleCompletionItem | undefined): boolean { - return !!item && Boolean(item.completion.detail && item.completion.detail !== item.completion.label); + return !!item && Boolean(item.completion.documentation || item.completion.detail && item.completion.detail !== item.completion.label); } export const SuggestDetailsClassName = 'suggest-details'; @@ -104,10 +104,10 @@ export class SimpleSuggestDetailsWidget { renderItem(item: SimpleCompletionItem, explainMode: boolean): void { this._renderDisposeable.clear(); - let { detail } = item.completion; + let { detail, documentation } = item.completion; let md = ''; - let documentation; + if (explainMode) { md += `score: ${item.score[0]}\n`; md += `prefix: ${item.word ?? '(no prefix)'}\n`; diff --git a/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts b/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts index 095fdcc867a..16b4809790b 100644 --- a/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts @@ -40,6 +40,12 @@ declare module 'vscode' { */ detail?: string; + + /** + * A human-readable string that represents a doc-comment. + */ + documentation?: string | MarkdownString; + /** * The completion's kind. Note that this will map to an icon. */