diff --git a/extensions/terminal-suggest/src/fig/figInterface.ts b/extensions/terminal-suggest/src/fig/figInterface.ts index df37585394a..1e283e46355 100644 --- a/extensions/terminal-suggest/src/fig/figInterface.ts +++ b/extensions/terminal-suggest/src/fig/figInterface.ts @@ -16,6 +16,7 @@ import type { ICompletionResource } from '../types'; import { osIsWindows } from '../helpers/os'; import { removeAnyFileExtension } from '../helpers/file'; import type { EnvironmentVariable } from './api-bindings/types'; +import { asArray } from '../terminalSuggestMain'; import { IFigExecuteExternals } from './execute'; export interface IFigSpecSuggestionsResult { @@ -67,10 +68,13 @@ export async function getFigSuggestions( result.items.push(createCompletionItem( terminalContext.cursorPosition, prefix, - { label: { label: specLabel, description } }, + { + label: { label: specLabel, description }, + kind: vscode.TerminalCompletionItemKind.Method + }, description, - availableCommand.detail) - ); + availableCommand.detail + )); } continue; } @@ -147,7 +151,7 @@ async function getFigSpecSuggestions( foldersRequested, fileExtensions, hasCurrentArg: !!parsedArguments.currentArg, - items: items, + items, }; } @@ -252,6 +256,33 @@ export async function collectCompletionItemResult( return { filesRequested, foldersRequested }; } const flagsToExclude = kind === vscode.TerminalCompletionItemKind.Flag ? parsedArguments?.passedOptions.map(option => option.name).flat() : undefined; + + function addItem(label: string, item: SpecArg) { + if (flagsToExclude?.includes(label)) { + return; + } + + let itemKind = kind; + if (typeof item === 'object' && 'args' in item && (asArray(item.args ?? [])).length > 0) { + itemKind = vscode.TerminalCompletionItemKind.Option; + } + const lastArgType: string | undefined = parsedArguments?.annotations.at(-1)?.type; + if (lastArgType === 'option_arg') { + itemKind = vscode.TerminalCompletionItemKind.OptionValue; + } + + items.push( + createCompletionItem( + terminalContext.cursorPosition, + prefix, + { label }, + undefined, + typeof item === 'string' ? item : item.description, + itemKind, + ) + ); + } + if (Array.isArray(specArgs)) { for (const item of specArgs) { const suggestionLabels = getFigSuggestionLabel(item); @@ -259,36 +290,12 @@ export async function collectCompletionItemResult( continue; } for (const label of suggestionLabels) { - if (flagsToExclude?.includes(label)) { - continue; - } - items.push( - createCompletionItem( - terminalContext.cursorPosition, - prefix, - { label }, - undefined, - typeof item === 'string' ? item : item.description, - kind - ) - ); + addItem(label, item); } } } else { for (const [label, item] of Object.entries(specArgs)) { - if (flagsToExclude?.includes(label)) { - continue; - } - items.push( - createCompletionItem( - terminalContext.cursorPosition, - prefix, - { label }, - undefined, - typeof item === 'string' ? item : item.description, - kind - ) - ); + addItem(label, item); } } }; diff --git a/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css b/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css index 475006090b4..a025a03ac2a 100644 --- a/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css +++ b/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css @@ -11,6 +11,10 @@ .monaco-workbench .codicon.codicon-symbol-class { color: var(--vscode-symbolIcon-classForeground); } .monaco-editor .codicon.codicon-symbol-method, .monaco-workbench .codicon.codicon-symbol-method { color: var(--vscode-symbolIcon-methodForeground); } +.monaco-editor .codicon.codicon-symbol-method-arrow, +.monaco-workbench .codicon.codicon-symbol-method-arrow { color: var(--vscode-symbolIcon-methodArrowForeground); } +.monaco-editor .codicon.codicon-flag, +.monaco-workbench .codicon.codicon-flag { color: var(--vscode-symbolIcon-flagForeground); } .monaco-editor .codicon.codicon-symbol-color, .monaco-workbench .codicon.codicon-symbol-color { color: var(--vscode-symbolIcon-colorForeground); } .monaco-editor .codicon.codicon-symbol-constant, diff --git a/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts b/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts index a2795f7541c..0cd56619647 100644 --- a/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts +++ b/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts @@ -36,6 +36,9 @@ export const SYMBOL_ICON_ENUMERATOR_FOREGROUND = registerColor('symbolIcon.enume hcLight: '#D67E00' }, localize('symbolIcon.enumeratorForeground', 'The foreground color for enumerator symbols. These symbols appear in the outline, breadcrumb, and suggest widget.')); + +export const SYMBOL_ICON_FLAG_FOREGROUND = registerColor('symbolIcon.flagForeground', SYMBOL_ICON_ENUMERATOR_FOREGROUND, localize('symbolIcon.enumeratorForeground', 'The foreground color for enumerator symbols. These symbols appear in the outline, breadcrumb, and suggest widget.')); + export const SYMBOL_ICON_ENUMERATOR_MEMBER_FOREGROUND = registerColor('symbolIcon.enumeratorMemberForeground', { dark: '#75BEFF', light: '#007ACC', @@ -86,6 +89,8 @@ export const SYMBOL_ICON_METHOD_FOREGROUND = registerColor('symbolIcon.methodFor hcLight: '#652D90' }, localize('symbolIcon.methodForeground', 'The foreground color for method symbols. These symbols appear in the outline, breadcrumb, and suggest widget.')); +export const SYMBOL_ICON_METHOD_ARROW_FOREGROUND = registerColor('symbolIcon.methodArrowForeground', SYMBOL_ICON_METHOD_FOREGROUND, localize('symbolIcon.methodArrowForeground', 'The foreground color for method with an arrow symbols. These symbols appear in the suggest widget.')); + export const SYMBOL_ICON_MODULE_FOREGROUND = registerColor('symbolIcon.moduleForeground', foreground, localize('symbolIcon.moduleForeground', 'The foreground color for module symbols. These symbols appear in the outline, breadcrumb, and suggest widget.')); export const SYMBOL_ICON_NAMESPACE_FOREGROUND = registerColor('symbolIcon.namespaceForeground', foreground, localize('symbolIcon.namespaceForeground', 'The foreground color for namespace symbols. These symbols appear in the outline, breadcrumb, and suggest widget.')); diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index ba135ce6215..7c3a1df0171 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -276,11 +276,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape id, provideCompletions: async (commandLine, cursorPosition, allowFallbackCompletions, token) => { const completions = await this._proxy.$provideTerminalCompletions(id, { commandLine, cursorPosition, allowFallbackCompletions }, token); - if (Array.isArray(completions)) { - return completions.map(c => ({ ...c, provider: id })); - } else { - return { items: completions?.items.map(c => ({ ...c, provider: id })), resourceRequestConfig: completions?.resourceRequestConfig }; - } + return { + items: completions?.items.map(c => ({ ...c, provider: id })), + resourceRequestConfig: completions?.resourceRequestConfig + }; } }, ...triggerCharacters)); } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index d05e0b628b0..edaf58d9a47 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2141,10 +2141,12 @@ export class TerminalProfile implements vscode.TerminalProfile { export enum TerminalCompletionItemKind { File = 0, Folder = 1, - Flag = 2, - Method = 3, + Method = 2, + Alias = 3, Argument = 4, - Alias = 5 + Option = 5, + OptionValue = 6, + Flag = 7, } export class TerminalCompletionItem implements vscode.TerminalCompletionItem { diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionItem.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionItem.ts index 8d02c076a95..f3c889ef22c 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionItem.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionItem.ts @@ -10,12 +10,15 @@ import { ISimpleCompletion, SimpleCompletionItem } from '../../../../services/su export enum TerminalCompletionItemKind { File = 0, Folder = 1, - Flag = 2, - Method = 3, + Method = 2, + Alias = 3, Argument = 4, - Alias = 5, - InlineSuggestion = 6, - InlineSuggestionAlwaysOnTop = 7, + Option = 5, + OptionValue = 6, + Flag = 7, + // Kinds only for core + InlineSuggestion = 100, + InlineSuggestionAlwaysOnTop = 101, } export interface ITerminalCompletion extends ISimpleCompletion { diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts index 5dd7147ef30..eb7f998cc39 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts @@ -166,7 +166,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo if (provider.shellTypes && !provider.shellTypes.includes(shellType)) { return undefined; } - const completions: ITerminalCompletion[] | TerminalCompletionList | undefined = await provider.provideCompletions(promptValue, cursorPosition, allowFallbackCompletions, token); + const completions = await provider.provideCompletions(promptValue, cursorPosition, allowFallbackCompletions, token); if (!completions) { return undefined; } @@ -190,9 +190,8 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo if (resourceCompletions) { completionItems.push(...resourceCompletions); } - return completionItems; } - return completionItems.length ? completionItems : undefined; + return completionItems; }); const results = await Promise.all(completionPromises); diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index 77010a1a383..1b2ccfdc8e4 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -91,11 +91,14 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest private _kindToIconMap = new Map([ [TerminalCompletionItemKind.File, Codicon.file], [TerminalCompletionItemKind.Folder, Codicon.folder], - [TerminalCompletionItemKind.Flag, Codicon.symbolProperty], [TerminalCompletionItemKind.Method, Codicon.symbolMethod], + [TerminalCompletionItemKind.Alias, Codicon.symbolMethodArrow], [TerminalCompletionItemKind.Argument, Codicon.symbolVariable], - [TerminalCompletionItemKind.Alias, Codicon.replace], + [TerminalCompletionItemKind.Option, Codicon.symbolEnum], + [TerminalCompletionItemKind.OptionValue, Codicon.symbolEnumMember], + [TerminalCompletionItemKind.Flag, Codicon.flag], [TerminalCompletionItemKind.InlineSuggestion, Codicon.star], + [TerminalCompletionItemKind.InlineSuggestionAlwaysOnTop, Codicon.star], ]); private readonly _inlineCompletion: ITerminalCompletion = { @@ -521,11 +524,13 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest this._inlineCompletionItem.idx = x.idx; this._inlineCompletionItem.score = x.score; this._inlineCompletionItem.labelLow = x.labelLow; + this._inlineCompletionItem.textLabel = x.textLabel; this._inlineCompletionItem.fileExtLow = x.fileExtLow; this._inlineCompletionItem.labelLowExcludeFileExt = x.labelLowExcludeFileExt; this._inlineCompletionItem.labelLowNormalizedPath = x.labelLowNormalizedPath; this._inlineCompletionItem.underscorePenalty = x.underscorePenalty; this._inlineCompletionItem.word = x.word; + this._model?.forceRefilterAll(); } // Force a filter all in order to re-evaluate the inline completion diff --git a/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts b/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts index 9b7f0edf856..49c3fa397af 100644 --- a/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts @@ -60,10 +60,12 @@ declare module 'vscode' { export enum TerminalCompletionItemKind { File = 0, Folder = 1, - Flag = 2, - Method = 3, + Method = 2, + Alias = 3, Argument = 4, - Alias = 5, + Option = 5, + OptionValue = 6, + Flag = 7, } export interface TerminalCompletionContext {