Merge pull request #283994 from microsoft/dev/dmitriv/keybinding-labels

Add IKeybindingService.appendKeybinding to unify and reduce duplicated code
This commit is contained in:
Dmitriy Vasyura
2026-01-08 08:36:25 +01:00
committed by GitHub
35 changed files with 198 additions and 159 deletions
@@ -88,8 +88,7 @@ class PostEditWidget<T extends DocumentPasteEdit | DocumentDropEdit> extends Dis
}
private _updateButtonTitle() {
const binding = this._keybindingService.lookupKeybinding(this.showCommand.id)?.getLabel();
this.button.element.title = this.showCommand.label + (binding ? ` (${binding})` : '');
this.button.element.title = this._keybindingService.appendKeybinding(this.showCommand.label, this.showCommand.id);
}
private create(): void {
@@ -120,11 +120,7 @@ export class FindOptionsWidget extends Widget implements IOverlayWidget {
}
private _keybindingLabelFor(actionId: string): string {
const kb = this._keybindingService.lookupKeybinding(actionId);
if (!kb) {
return '';
}
return ` (${kb.getLabel()})`;
return this._keybindingService.appendKeybinding('', actionId);
}
public override dispose(): void {
@@ -910,11 +910,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
// ----- initialization
private _keybindingLabelFor(actionId: string): string {
const kb = this._keybindingService.lookupKeybinding(actionId);
if (!kb) {
return '';
}
return ` (${kb.getLabel()})`;
return this._keybindingService.appendKeybinding('', actionId);
}
private _buildDomNode(): void {
@@ -527,17 +527,9 @@ function renderMarkdown(
export function labelForHoverVerbosityAction(keybindingService: IKeybindingService, action: HoverVerbosityAction): string {
switch (action) {
case HoverVerbosityAction.Increase: {
const kb = keybindingService.lookupKeybinding(INCREASE_HOVER_VERBOSITY_ACTION_ID);
return kb ?
nls.localize('increaseVerbosityWithKb', "Increase Hover Verbosity ({0})", kb.getLabel()) :
nls.localize('increaseVerbosity', "Increase Hover Verbosity");
}
case HoverVerbosityAction.Decrease: {
const kb = keybindingService.lookupKeybinding(DECREASE_HOVER_VERBOSITY_ACTION_ID);
return kb ?
nls.localize('decreaseVerbosityWithKb', "Decrease Hover Verbosity ({0})", kb.getLabel()) :
nls.localize('decreaseVerbosity', "Decrease Hover Verbosity");
}
case HoverVerbosityAction.Increase:
return keybindingService.appendKeybinding(nls.localize('increaseVerbosity', "Increase Hover Verbosity"), INCREASE_HOVER_VERBOSITY_ACTION_ID);
case HoverVerbosityAction.Decrease:
return keybindingService.appendKeybinding(nls.localize('decreaseVerbosity', "Decrease Hover Verbosity"), DECREASE_HOVER_VERBOSITY_ACTION_ID);
}
}
@@ -143,12 +143,7 @@ export class InlineSuggestionHintsContentWidget extends Disposable implements IC
true,
() => this._commandService.executeCommand(commandId),
);
const kb = this.keybindingService.lookupKeybinding(commandId, this._contextKeyService);
let tooltip = label;
if (kb) {
tooltip = localize({ key: 'content', comment: ['A label', 'A keybinding'] }, '{0} ({1})', label, kb.getLabel());
}
action.tooltip = tooltip;
action.tooltip = this.keybindingService.appendKeybinding(label, commandId, this._contextKeyService);
return action;
}
@@ -74,13 +74,8 @@ export class ActionWidgetDropdownActionViewItem extends BaseActionViewItem {
}
protected override getTooltip() {
const keybinding = this._keybindingService.lookupKeybinding(this.action.id, this._contextKeyService);
const keybindingLabel = keybinding && keybinding.getLabel();
const tooltip = this.action.tooltip ?? this.action.label;
return keybindingLabel
? `${tooltip} (${keybindingLabel})`
: tooltip;
return this._keybindingService.appendKeybinding(tooltip, this.action.id, this._contextKeyService);
}
show(): void {
+3 -6
View File
@@ -85,12 +85,9 @@ export class WorkbenchButtonBar extends ButtonBar {
const actionOrSubmenu = actions[i];
let action: IAction;
let btn: IButton;
let tooltip: string = '';
const kb = actionOrSubmenu instanceof SubmenuAction ? '' : this._keybindingService.lookupKeybinding(actionOrSubmenu.id);
if (kb) {
tooltip = localize('labelWithKeybinding', "{0} ({1})", actionOrSubmenu.tooltip || actionOrSubmenu.label, kb.getLabel());
} else {
tooltip = actionOrSubmenu.tooltip || actionOrSubmenu.label;
let tooltip = actionOrSubmenu.tooltip || actionOrSubmenu.label;
if (!(actionOrSubmenu instanceof SubmenuAction)) {
tooltip = this._keybindingService.appendKeybinding(tooltip, actionOrSubmenu.id);
}
if (actionOrSubmenu instanceof SubmenuAction && actionOrSubmenu.actions.length > 0) {
const [first, ...rest] = actionOrSubmenu.actions;
@@ -7,7 +7,6 @@ import { IContextMenuProvider } from '../../../base/browser/contextmenu.js';
import { IActionProvider } from '../../../base/browser/ui/dropdown/dropdown.js';
import { DropdownMenuActionViewItem, IDropdownMenuActionViewItemOptions } from '../../../base/browser/ui/dropdown/dropdownActionViewItem.js';
import { IAction } from '../../../base/common/actions.js';
import * as nls from '../../../nls.js';
import { IContextKeyService } from '../../contextkey/common/contextkey.js';
import { IKeybindingService } from '../../keybinding/common/keybinding.js';
@@ -24,12 +23,7 @@ export class DropdownMenuActionViewItemWithKeybinding extends DropdownMenuAction
}
protected override getTooltip() {
const keybinding = this.keybindingService.lookupKeybinding(this.action.id, this.contextKeyService);
const keybindingLabel = keybinding && keybinding.getLabel();
const tooltip = this.action.tooltip ?? this.action.label;
return keybindingLabel
? nls.localize('titleAndKb', "{0} ({1})", tooltip, keybindingLabel)
: tooltip;
return this.keybindingService.appendKeybinding(tooltip, this.action.id, this.contextKeyService);
}
}
@@ -263,20 +263,11 @@ export class MenuEntryActionViewItem<T extends IMenuEntryActionViewItemOptions =
}
protected override getTooltip() {
const keybinding = this._keybindingService.lookupKeybinding(this._commandAction.id, this._contextKeyService);
const keybindingLabel = keybinding && keybinding.getLabel();
const tooltip = this._commandAction.tooltip || this._commandAction.label;
let title = keybindingLabel
? localize('titleAndKb', "{0} ({1})", tooltip, keybindingLabel)
: tooltip;
let title = this._keybindingService.appendKeybinding(tooltip, this._commandAction.id, this._contextKeyService);
if (!this._wantsAltCommand && this._menuItemAction.alt?.enabled) {
const altTooltip = this._menuItemAction.alt.tooltip || this._menuItemAction.alt.label;
const altKeybinding = this._keybindingService.lookupKeybinding(this._menuItemAction.alt.id, this._contextKeyService);
const altKeybindingLabel = altKeybinding && altKeybinding.getLabel();
const altTitleSection = altKeybindingLabel
? localize('titleAndKb', "{0} ({1})", altTooltip, altKeybindingLabel)
: altTooltip;
const altTitleSection = this._keybindingService.appendKeybinding(altTooltip, this._menuItemAction.alt.id, this._contextKeyService);
title = localize('titleAndKbAndAlt', "{0}\n[{1}] {2}", title, UILabelProvider.modifierLabels[OS].altKey, altTitleSection);
}
@@ -400,6 +400,20 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
}
return false;
}
public appendKeybinding(label: string, commandId: string | undefined | null, context?: IContextKeyService, enforceContextCheck?: boolean): string {
if (commandId) {
const keybindingLabel = this.lookupKeybinding(commandId, context, enforceContextCheck)?.getLabel();
if (keybindingLabel) {
return nls.localize(
{ key: 'keybindingLabel', comment: ['UI element label', 'A keybinding label'] },
"{0} ({1})",
label,
keybindingLabel);
}
}
return label;
}
}
class KeybindingModifierSet {
@@ -106,6 +106,12 @@ export interface IKeybindingService {
toggleLogging(): boolean;
/**
* Given a UI element label and a command ID, appends the keybinding label if any.
* If the command is defined and has a keybinding, returns `${label} (keybinding label)`, otherwise just `label`.
*/
appendKeybinding(label: string, commandId: string | undefined | null, context?: IContextKeyService, enforceContextCheck?: boolean): string;
_dumpDebugInfo(): string;
_dumpDebugInfoJSON(): string;
}
@@ -134,7 +134,15 @@ suite('AbstractKeybindingService', () => {
onDidChangeContext: undefined!,
bufferChangeEvents() { },
createKey: undefined!,
contextMatchesRules: undefined!,
contextMatchesRules: (rules: ContextKeyExpression | null | undefined) => {
if (!rules) {
return true;
}
if (!currentContextValue) {
return false;
}
return rules.evaluate(currentContextValue);
},
getContextKeyValue: undefined!,
createScoped: undefined!,
createOverlay: undefined!,
@@ -613,4 +621,110 @@ suite('AbstractKeybindingService', () => {
kbService.dispose();
});
suite('appendKeybinding', () => {
test('appends keybinding label when command has a keybinding', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand'),
]);
const result = kbService.appendKeybinding('My Label', 'myCommand');
const expectedLabel = toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(result, `My Label (${expectedLabel})`);
kbService.dispose();
});
test('returns only label when command has no keybinding', () => {
const kbService = createTestKeybindingService([]);
const result = kbService.appendKeybinding('My Label', 'myCommand');
assert.strictEqual(result, 'My Label');
kbService.dispose();
});
test('returns only label when commandId is null', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand'),
]);
const result = kbService.appendKeybinding('My Label', null);
assert.strictEqual(result, 'My Label');
kbService.dispose();
});
test('returns only label when commandId is undefined', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand'),
]);
const result = kbService.appendKeybinding('My Label', undefined);
assert.strictEqual(result, 'My Label');
kbService.dispose();
});
test('returns only label when commandId is empty string', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand'),
]);
const result = kbService.appendKeybinding('My Label', '');
assert.strictEqual(result, 'My Label');
kbService.dispose();
});
test('appends keybinding for command with context when context matches', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand', ContextKeyExpr.has('key1')),
]);
currentContextValue = createContext({ key1: true });
const result = kbService.appendKeybinding('My Label', 'myCommand');
const expectedLabel = toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(result, `My Label (${expectedLabel})`);
kbService.dispose();
});
test('returns only label when context does not match and enforceContextCheck is true', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand', ContextKeyExpr.has('key1')),
]);
currentContextValue = createContext({});
const result = kbService.appendKeybinding('My Label', 'myCommand', undefined, true);
assert.strictEqual(result, 'My Label');
kbService.dispose();
});
test('appends keybinding when context does not match but enforceContextCheck is false', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand', ContextKeyExpr.has('key1')),
]);
currentContextValue = createContext({});
const result = kbService.appendKeybinding('My Label', 'myCommand', undefined, false);
const expectedLabel = toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(result, `My Label (${expectedLabel})`);
kbService.dispose();
});
test('appends keybinding even when label is empty string', () => {
const kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'myCommand'),
]);
const result = kbService.appendKeybinding('', 'myCommand');
const expectedLabel = toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(result, ` (${expectedLabel})`);
kbService.dispose();
});
});
});
@@ -171,4 +171,8 @@ export class MockKeybindingService implements IKeybindingService {
public registerSchemaContribution() {
return Disposable.None;
}
public appendKeybinding(label: string, _commandId: string, _context?: IContextKeyService, _enforceContextCheck?: boolean): string {
return label;
}
}
+1 -5
View File
@@ -139,11 +139,7 @@ export class FloatingEditorClickWidget extends FloatingClickWidget implements IO
keyBindingAction: string | null,
@IKeybindingService keybindingService: IKeybindingService
) {
super(
keyBindingAction && keybindingService.lookupKeybinding(keyBindingAction)
? `${label} (${keybindingService.lookupKeybinding(keyBindingAction)!.getLabel()})`
: label
);
super(keybindingService.appendKeybinding(label, keyBindingAction));
}
getId(): string {
@@ -280,11 +280,7 @@ class ChatEditorOverlayWidget extends Disposable {
if (!value) {
return value;
}
const kb = that._keybindingService.lookupKeybinding(this.action.id);
if (!kb) {
return value;
}
return localize('tooltip', "{0} ({1})", value, kb.getLabel());
return that._keybindingService.appendKeybinding(value, action.id);
}
};
}
@@ -47,8 +47,7 @@ export class ChatElicitationContentPart extends Disposable implements IChatConte
const buttons: IChatConfirmationButton<unknown>[] = [];
if (elicitation.kind === 'elicitation2') {
const acceptKeybinding = this.keybindingService.lookupKeybinding(AcceptElicitationRequestActionId);
const acceptTooltip = acceptKeybinding ? `${elicitation.acceptButtonLabel} (${acceptKeybinding.getLabel()})` : elicitation.acceptButtonLabel;
const acceptTooltip = this.keybindingService.appendKeybinding(elicitation.acceptButtonLabel, AcceptElicitationRequestActionId);
buttons.push({
label: elicitation.acceptButtonLabel,
@@ -264,13 +264,7 @@ export class ChatMarkdownDecorationsRenderer {
private injectKeybindingHint(a: HTMLAnchorElement, href: string, keybindingService: IKeybindingService): void {
const command = href.match(/command:([^\)]+)/)?.[1];
if (command) {
const kb = keybindingService.lookupKeybinding(command);
if (kb) {
const keybinding = kb.getLabel();
if (keybinding) {
a.textContent = `${a.textContent} (${keybinding})`;
}
}
a.textContent = keybindingService.appendKeybinding(a.textContent || '', command);
}
}
}
@@ -54,10 +54,8 @@ export abstract class AbstractToolConfirmationSubPart extends BaseChatToolInvoca
}
protected render(config: IToolConfirmationConfig) {
const { keybindingService, languageModelToolsService, toolInvocation } = this;
const allowKeybinding = keybindingService.lookupKeybinding(config.allowActionId)?.getLabel();
const allowTooltip = allowKeybinding ? `${config.allowLabel} (${allowKeybinding})` : config.allowLabel;
const skipKeybinding = keybindingService.lookupKeybinding(config.skipActionId)?.getLabel();
const skipTooltip = skipKeybinding ? `${config.skipLabel} (${skipKeybinding})` : config.skipLabel;
const allowTooltip = keybindingService.appendKeybinding(config.allowLabel, config.allowActionId);
const skipTooltip = keybindingService.appendKeybinding(config.skipLabel, config.skipActionId);
const additionalActions = this.additionalPrimaryActions();
@@ -57,12 +57,10 @@ export class ExtensionsInstallConfirmationWidgetSubPart extends BaseChatToolInvo
if (toolInvocation.state.get().type === IChatToolInvocation.StateKind.WaitingForConfirmation) {
const allowLabel = localize('allow', "Allow");
const allowKeybinding = keybindingService.lookupKeybinding(AcceptToolConfirmationActionId)?.getLabel();
const allowTooltip = allowKeybinding ? `${allowLabel} (${allowKeybinding})` : allowLabel;
const allowTooltip = keybindingService.appendKeybinding(allowLabel, AcceptToolConfirmationActionId);
const cancelLabel = localize('cancel', "Cancel");
const cancelKeybinding = keybindingService.lookupKeybinding(CancelChatActionId)?.getLabel();
const cancelTooltip = cancelKeybinding ? `${cancelLabel} (${cancelKeybinding})` : cancelLabel;
const cancelTooltip = keybindingService.appendKeybinding(cancelLabel, CancelChatActionId);
const enableAllowButtonEvent = this._register(new Emitter<boolean>());
const buttons: IChatConfirmationButton<ConfirmedReason>[] = [
@@ -384,8 +384,7 @@ export class ChatTerminalToolConfirmationSubPart extends BaseChatToolInvocationS
private _createButtons(moreActions: (IChatConfirmationButton<TerminalNewAutoApproveButtonData> | Separator)[] | undefined): IChatConfirmationButton<boolean | TerminalNewAutoApproveButtonData>[] {
const getLabelAndTooltip = (label: string, actionId: string, tooltipDetail: string = label): { label: string; tooltip: string } => {
const keybinding = this.keybindingService.lookupKeybinding(actionId)?.getLabel();
const tooltip = keybinding ? `${tooltipDetail} (${keybinding})` : (tooltipDetail);
const tooltip = this.keybindingService.appendKeybinding(tooltipDetail, actionId);
return { label, tooltip };
};
return [
@@ -1072,9 +1072,7 @@ export class ToggleChatTerminalOutputAction extends Action implements IAction {
}
private _updateTooltip(): void {
const keybinding = this._keybindingService.lookupKeybinding(TerminalContribCommandId.FocusMostRecentChatTerminalOutput);
const label = keybinding?.getLabel();
this.tooltip = label ? `${this.label} (${label})` : this.label;
this.tooltip = this._keybindingService.appendKeybinding(this.label, TerminalContribCommandId.FocusMostRecentChatTerminalOutput);
}
}
@@ -1170,8 +1168,6 @@ export class FocusChatInstanceAction extends Action implements IAction {
}
private _updateTooltip(): void {
const keybinding = this._keybindingService.lookupKeybinding(TerminalContribCommandId.FocusMostRecentChatTerminal);
const label = keybinding?.getLabel();
this.tooltip = label ? `${this.label} (${label})` : this.label;
this.tooltip = this._keybindingService.appendKeybinding(this.label, TerminalContribCommandId.FocusMostRecentChatTerminal);
}
}
@@ -275,11 +275,7 @@ export abstract class SimpleFindWidget extends Widget implements IVerticalSashLa
}
private _getKeybinding(actionId: string): string {
const kb = this._keybindingService?.lookupKeybinding(actionId);
if (!kb) {
return '';
}
return ` (${kb.getLabel()})`;
return this._keybindingService.appendKeybinding('', actionId);
}
override dispose() {
@@ -79,9 +79,7 @@ export class StartDebugActionViewItem extends BaseActionViewItem {
this.container = container;
container.classList.add('start-debug-action-item');
this.start = dom.append(container, $(ThemeIcon.asCSSSelector(debugStart)));
const keybinding = this.keybindingService.lookupKeybinding(this.action.id)?.getLabel();
const keybindingLabel = keybinding ? ` (${keybinding})` : '';
const title = this.action.label + keybindingLabel;
const title = this.keybindingService.appendKeybinding(this.action.label, this.action.id);
this.toDispose.push(this.hoverService.setupManagedHover(getDefaultHoverDelegate('mouse'), this.start, title));
this.start.setAttribute('role', 'button');
this._setAriaLabel(title);
@@ -105,8 +105,7 @@ export class WelcomeView extends ViewPane {
}));
setContextKey();
const debugKeybinding = this.keybindingService.lookupKeybinding(DEBUG_START_COMMAND_ID);
debugKeybindingLabel = debugKeybinding ? ` (${debugKeybinding.getLabel()})` : '';
debugKeybindingLabel = this.keybindingService.appendKeybinding('', DEBUG_START_COMMAND_ID);
}
override shouldShowWelcome(): boolean {
@@ -88,12 +88,10 @@ class LanguageDetectionStatusContribution implements IWorkbenchContribution {
const existing = editorModel.getLanguageId();
if (lang && lang !== existing && skip[existing] !== lang) {
const detectedName = this._languageService.getLanguageName(lang) || lang;
let tooltip = localize('status.autoDetectLanguage', "Accept Detected Language: {0}", detectedName);
const keybinding = this._keybindingService.lookupKeybinding(detectLanguageCommandId);
const label = keybinding?.getLabel();
if (label) {
tooltip += ` (${label})`;
}
const tooltip = this._keybindingService.appendKeybinding(
localize('status.autoDetectLanguage', "Accept Detected Language: {0}", detectedName),
detectLanguageCommandId
);
const props: IStatusbarEntry = {
name: localize('langDetection.name', "Language Detection"),
@@ -58,8 +58,9 @@ class DiagnosticCellStatusBarItem extends Disposable {
let item: INotebookCellStatusBarItem | undefined;
if (error?.location && this.hasNotebookAgent()) {
const keybinding = this.keybindingService.lookupKeybinding(OPEN_CELL_FAILURE_ACTIONS_COMMAND_ID)?.getLabel();
const tooltip = localize('notebook.cell.status.diagnostic', "Quick Actions {0}", `(${keybinding})`);
const tooltip = this.keybindingService.appendKeybinding(
localize('notebook.cell.status.diagnostic', "Quick Actions"),
OPEN_CELL_FAILURE_ACTIONS_COMMAND_ID);
item = {
text: `$(sparkle)`,
@@ -137,12 +137,10 @@ class CellStatusBarLanguageDetectionProvider implements INotebookCellStatusBarIt
const items: INotebookCellStatusBarItem[] = [];
if (cached.guess && currentLanguageId !== cached.guess) {
const detectedName = this._languageService.getLanguageName(cached.guess) || cached.guess;
let tooltip = localize('notebook.cell.status.autoDetectLanguage', "Accept Detected Language: {0}", detectedName);
const keybinding = this._keybindingService.lookupKeybinding(DETECT_CELL_LANGUAGE);
const label = keybinding?.getLabel();
if (label) {
tooltip += ` (${label})`;
}
const tooltip = this._keybindingService.appendKeybinding(
localize('notebook.cell.status.autoDetectLanguage', "Accept Detected Language: {0}", detectedName),
DETECT_CELL_LANGUAGE
);
items.push({
text: '$(lightbulb-autofix)',
command: DETECT_CELL_LANGUAGE,
@@ -886,23 +886,21 @@ class ActionsColumnRenderer implements ITableRenderer<IKeybindingItemEntry, IAct
}
private createEditAction(keybindingItemEntry: IKeybindingItemEntry): IAction {
const keybinding = this.keybindingsService.lookupKeybinding(KEYBINDINGS_EDITOR_COMMAND_DEFINE);
return <IAction>{
class: ThemeIcon.asClassName(keybindingsEditIcon),
enabled: true,
id: 'editKeybinding',
tooltip: keybinding ? localize('editKeybindingLabelWithKey', "Change Keybinding {0}", `(${keybinding.getLabel()})`) : localize('editKeybindingLabel', "Change Keybinding"),
tooltip: this.keybindingsService.appendKeybinding(localize('editKeybindingLabel', "Change Keybinding"), KEYBINDINGS_EDITOR_COMMAND_DEFINE),
run: () => this.keybindingsEditor.defineKeybinding(keybindingItemEntry, false)
};
}
private createAddAction(keybindingItemEntry: IKeybindingItemEntry): IAction {
const keybinding = this.keybindingsService.lookupKeybinding(KEYBINDINGS_EDITOR_COMMAND_DEFINE);
return <IAction>{
class: ThemeIcon.asClassName(keybindingsAddIcon),
enabled: true,
id: 'addKeybinding',
tooltip: keybinding ? localize('addKeybindingLabelWithKey', "Add Keybinding {0}", `(${keybinding.getLabel()})`) : localize('addKeybindingLabel', "Add Keybinding"),
tooltip: this.keybindingsService.appendKeybinding(localize('addKeybindingLabel', "Add Keybinding"), KEYBINDINGS_EDITOR_COMMAND_DEFINE),
run: () => this.keybindingsEditor.defineKeybinding(keybindingItemEntry, false)
};
}
@@ -963,11 +963,9 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
}
protected renderSettingToolbar(container: HTMLElement): ToolBar {
const toggleMenuKeybinding = this._keybindingService.lookupKeybinding(SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU);
let toggleMenuTitle = localize('settingsContextMenuTitle', "More Actions... ");
if (toggleMenuKeybinding) {
toggleMenuTitle += ` (${toggleMenuKeybinding && toggleMenuKeybinding.getLabel()})`;
}
const toggleMenuTitle = this._keybindingService.appendKeybinding(
localize('settingsContextMenuTitle', "More Actions... "),
SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU);
const toolbar = new ToolBar(container, this._contextMenuService, {
toggleMenuTitle,
@@ -130,8 +130,7 @@ class QuickDiffWidgetEditorAction extends Action {
@IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService instantiationService: IInstantiationService
) {
const keybinding = keybindingService.lookupKeybinding(action.id);
const label = action.label + (keybinding ? ` (${keybinding.getLabel()})` : '');
const label = keybindingService.appendKeybinding(action.label, action.id);
super(action.id, label, cssClass);
@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as DOM from '../../../../base/browser/dom.js';
import { ResolvedKeybinding } from '../../../../base/common/keybindings.js';
import * as nls from '../../../../nls.js';
import { WorkbenchCompressibleAsyncDataTree } from '../../../../platform/list/browser/listService.js';
import { IViewsService } from '../../../services/views/common/viewsService.js';
@@ -20,10 +19,6 @@ export function isSearchViewFocused(viewsService: IViewsService): boolean {
return !!(searchView && DOM.isAncestorOfActiveElement(searchView.getContainer()));
}
export function appendKeyBindingLabel(label: string, inputKeyBinding: ResolvedKeybinding | undefined): string {
return doAppendKeyBindingLabel(label, inputKeyBinding);
}
export function getSearchView(viewsService: IViewsService): SearchView | undefined {
return viewsService.getActiveViewWithId(VIEW_ID) as SearchView;
}
@@ -68,8 +63,3 @@ function hasDownstreamMatch(elements: RenderableMatch[], focusElement: Renderabl
export function openSearchView(viewsService: IViewsService, focus?: boolean): Promise<SearchView | undefined> {
return viewsService.openView(VIEW_ID, focus).then(view => (view as SearchView ?? undefined));
}
function doAppendKeyBindingLabel(label: string, keyBinding: ResolvedKeybinding | undefined): string {
return keyBinding ? label + ' (' + keyBinding.getLabel() + ')' : label;
}
@@ -56,7 +56,6 @@ import { Memento } from '../../../common/memento.js';
import { IViewDescriptorService } from '../../../common/views.js';
import { NotebookEditor } from '../../notebook/browser/notebookEditor.js';
import { ExcludePatternInputWidget, IncludePatternInputWidget } from './patternInputWidget.js';
import { appendKeyBindingLabel } from './searchActionsBase.js';
import { IFindInFilesArgs } from './searchActionsFind.js';
import { searchDetailsIcon } from './searchIcons.js';
import { renderSearchMessage } from './searchMessage.js';
@@ -1737,9 +1736,9 @@ export class SearchView extends ViewPane {
}
private appendSearchWithAIButton(messageEl: HTMLElement) {
const searchWithAIButtonTooltip = appendKeyBindingLabel(
const searchWithAIButtonTooltip = this.keybindingService.appendKeybinding(
nls.localize('triggerAISearch.tooltip', "Search with AI."),
this.keybindingService.lookupKeybinding(Constants.SearchCommandIds.SearchWithAIActionId)
Constants.SearchCommandIds.SearchWithAIActionId
);
const searchWithAIButtonText = nls.localize('searchWithAIButtonTooltip', "Search with AI");
const searchWithAIButton = this.messageDisposables.add(new SearchLinkButton(
@@ -2039,9 +2038,9 @@ export class SearchView extends ViewPane {
dom.append(messageEl, ' - ');
const openInEditorTooltip = appendKeyBindingLabel(
const openInEditorTooltip = this.keybindingService.appendKeybinding(
nls.localize('openInEditor.tooltip', "Copy current search results to an editor"),
this.keybindingService.lookupKeybinding(Constants.SearchCommandIds.OpenInEditorCommandId));
Constants.SearchCommandIds.OpenInEditorCommandId);
const openInEditorButton = this.messageDisposables.add(new SearchLinkButton(
nls.localize('openInEditor.message', "Open in editor"),
() => this.instantiationService.invokeFunction(createEditorFromSearchResult, this.searchResult, this.searchIncludePattern.getValue(), this.searchExcludePattern.getValue(), this.searchIncludePattern.onlySearchInOpenEditors()), this.hoverService,
@@ -26,7 +26,7 @@ import { KeybindingsRegistry, KeybindingWeight } from '../../../../platform/keyb
import { ISearchConfigurationProperties } from '../../../services/search/common/search.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { ContextScopedReplaceInput } from '../../../../platform/history/browser/contextScopedHistoryWidget.js';
import { appendKeyBindingLabel, isSearchViewFocused, getSearchView } from './searchActionsBase.js';
import { isSearchViewFocused, getSearchView } from './searchActionsBase.js';
import * as Constants from '../common/constants.js';
import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js';
import { isMacintosh } from '../../../../base/common/platform.js';
@@ -117,8 +117,7 @@ export class SearchWidget extends Widget {
private static readonly REPLACE_ALL_DISABLED_LABEL = nls.localize('search.action.replaceAll.disabled.label', "Replace All (Submit Search to Enable)");
private static readonly REPLACE_ALL_ENABLED_LABEL = (keyBindingService2: IKeybindingService): string => {
const kb = keyBindingService2.lookupKeybinding(ReplaceAllAction.ID);
return appendKeyBindingLabel(nls.localize('search.action.replaceAll.enabled.label', "Replace All"), kb);
return keyBindingService2.appendKeybinding(nls.localize('search.action.replaceAll.enabled.label', "Replace All"), ReplaceAllAction.ID);
};
domNode: HTMLElement | undefined;
@@ -400,9 +399,9 @@ export class SearchWidget extends Widget {
label: nls.localize('label.Search', 'Search: Type Search Term and press Enter to search'),
validation: (value: string) => this.validateSearchInput(value),
placeholder: nls.localize('search.placeHolder', "Search"),
appendCaseSensitiveLabel: appendKeyBindingLabel('', this.keybindingService.lookupKeybinding(Constants.SearchCommandIds.ToggleCaseSensitiveCommandId)),
appendWholeWordsLabel: appendKeyBindingLabel('', this.keybindingService.lookupKeybinding(Constants.SearchCommandIds.ToggleWholeWordCommandId)),
appendRegexLabel: appendKeyBindingLabel('', this.keybindingService.lookupKeybinding(Constants.SearchCommandIds.ToggleRegexCommandId)),
appendCaseSensitiveLabel: this.keybindingService.appendKeybinding('', Constants.SearchCommandIds.ToggleCaseSensitiveCommandId),
appendWholeWordsLabel: this.keybindingService.appendKeybinding('', Constants.SearchCommandIds.ToggleWholeWordCommandId),
appendRegexLabel: this.keybindingService.appendKeybinding('', Constants.SearchCommandIds.ToggleRegexCommandId),
history: new Set(history),
showHistoryHint: () => showHistoryKeybindingHint(this.keybindingService),
flexibleHeight: true,
@@ -465,7 +464,7 @@ export class SearchWidget extends Widget {
this.showContextToggle = new Toggle({
isChecked: false,
title: appendKeyBindingLabel(nls.localize('showContext', "Toggle Context Lines"), this.keybindingService.lookupKeybinding(ToggleSearchEditorContextLinesCommandId)),
title: this.keybindingService.appendKeybinding(nls.localize('showContext', "Toggle Context Lines"), ToggleSearchEditorContextLinesCommandId),
icon: searchShowContextIcon,
hoverLifecycleOptions,
...defaultToggleStyles
@@ -513,7 +512,7 @@ export class SearchWidget extends Widget {
this.replaceInput = this._register(new ContextScopedReplaceInput(replaceBox, this.contextViewService, {
label: nls.localize('label.Replace', 'Replace: Type replace term and press Enter to preview'),
placeholder: nls.localize('search.replace.placeHolder', "Replace"),
appendPreserveCaseLabel: appendKeyBindingLabel('', this.keybindingService.lookupKeybinding(Constants.SearchCommandIds.TogglePreserveCaseId)),
appendPreserveCaseLabel: this.keybindingService.appendKeybinding('', Constants.SearchCommandIds.TogglePreserveCaseId),
history: new Set(options.replaceHistory),
showHistoryHint: () => showHistoryKeybindingHint(this.keybindingService),
flexibleHeight: true,
@@ -718,10 +718,7 @@ class CoverageToolbarWidget extends Disposable implements IOverlayWidget {
() => this.coverage.showInline.set(!this.coverage.showInline.get(), undefined),
);
const kb = this.keybindingService.lookupKeybinding(TOGGLE_INLINE_COMMAND_ID);
if (kb) {
toggleAction.tooltip = `${TOGGLE_INLINE_COMMAND_TEXT} (${kb.getLabel()})`;
}
toggleAction.tooltip = this.keybindingService.appendKeybinding(TOGGLE_INLINE_COMMAND_TEXT, TOGGLE_INLINE_COMMAND_ID);
const hasUncoveredStmt = current.coverage.statement.covered < current.coverage.statement.total;
// Navigation buttons for missed coverage lines
+1 -1
View File
@@ -1210,7 +1210,7 @@ class ZoomStatusEntry extends Disposable {
const zoomOutAction: Action = disposables.add(new Action('workbench.action.zoomOut', localize('zoomOut', "Zoom Out"), ThemeIcon.asClassName(Codicon.remove), true, () => this.commandService.executeCommand(zoomOutAction.id)));
const zoomInAction: Action = disposables.add(new Action('workbench.action.zoomIn', localize('zoomIn', "Zoom In"), ThemeIcon.asClassName(Codicon.plus), true, () => this.commandService.executeCommand(zoomInAction.id)));
const zoomResetAction: Action = disposables.add(new Action('workbench.action.zoomReset', localize('zoomReset', "Reset"), undefined, true, () => this.commandService.executeCommand(zoomResetAction.id)));
zoomResetAction.tooltip = localize('zoomResetLabel', "{0} ({1})", zoomResetAction.label, this.keybindingService.lookupKeybinding(zoomResetAction.id)?.getLabel());
zoomResetAction.tooltip = this.keybindingService.appendKeybinding(zoomResetAction.label, zoomResetAction.id);
const zoomSettingsAction: Action = disposables.add(new Action('workbench.action.openSettings', localize('zoomSettings', "Settings"), ThemeIcon.asClassName(Codicon.settingsGear), true, () => this.commandService.executeCommand(zoomSettingsAction.id, 'window.zoom')));
const zoomLevelLabel = disposables.add(new Action('zoomLabel', undefined, undefined, false));