fix(editor): hide mouse-only caret action from Find Action (#2191)

Add or Remove Caret only works through its pointer gesture, so running it from Find Action did nothing. It is now hidden there. Hidden actions with default shortcuts or explicit overrides stay searchable and editable in Settings > Keymap, including after their last binding is removed. A sweep of other empty handlers found only disabled popup placeholders and an initially disabled merge editor host.
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-11-09 03:57:07 +08:00
1 джерело a41fe86d47
коміт 299fb14f80
4 files changed
+35 -4

No files matched your search

+1
Переглянути файл
@@ -806,6 +806,7 @@ export function registerEditorActions(): () => void {
title: "Add or Remove Caret",
category: "Editor Actions",
when: "textEditorActive",
hidden: true,
// The mouse selection style handles the pointer position and dragging.
run: () => {},
},
+24 -1
Переглянути файл
@@ -36,9 +36,11 @@ import {
withCustomOverrides,
type KeymapDraft,
} from "../keymap/model";
import { buildKeymapTree } from "../keymap/KeymapPage";
import { buildKeymapTree, keymapSearchLabels } from "../keymap/KeymapPage";
import { groupPath } from "../keymap/groups";
import { registerEditorActions } from "@/editor/core/actions";
import { registerLspActions } from "@/editor/lsp/actions";
import { matchActions } from "@/features/search/everywhere/model";
import { _resetI18nForTests, setLocale } from "@/platform/i18n";
it("finds the translated declaration action by 声明 and its English title", async () => {
@@ -204,6 +206,27 @@ describe("conflicts", () => {
});
describe("shortcut search", () => {
it.each(Object.keys(PRESETS))("keeps the mouse-only caret action configurable in %s", (preset) => {
const dispose = registerEditorActions();
const originalKeymap = useKeymap.getState();
const id = "editor.addOrRemoveCaret";
const title = "Add or Remove Caret";
try {
expect(matchActions(allActions(), title, { isEnabled: () => true, recent: [id] })).toEqual([]);
const variants: KeymapDraft["overrides"][] = [{}, { [id]: ["Alt+Button1"] }, { [id]: [] }];
for (const overrides of variants) {
useKeymap.setState({ preset, overrides });
expect(keymapSearchLabels()).toContain(title);
const tree = buildKeymapTree(allActions(), { preset, overrides }, title, "");
const group = tree.find((node) => node.key === "grp:Editor Actions");
expect(group?.kind === "group" && group.children.map((node) => node.key)).toEqual([id]);
}
} finally {
useKeymap.setState(originalKeymap);
dispose();
}
});
it("matches exact bindings and chord first strokes", () => {
expect(bindingMatches(["Meta+K Meta+C"], "Meta+K")).toBe(true);
expect(bindingMatches(["Shift+Meta+O"], "Meta+Shift+O")).toBe(true);
+5 -3
Переглянути файл
@@ -9,7 +9,7 @@
import { useMemo, useRef, useState, type MouseEvent } from "react";
import clsx from "clsx";
import { useActions, allActions, type Action } from "@/platform/actions";
import { defaultPreset, formatBinding, type Keymap, PRESET_TITLES, PRESETS } from "@/platform/keymap";
import { defaultPreset, formatBinding, type Keymap, PRESET_TITLES, PRESETS, useKeymap } from "@/platform/keymap";
import { confirm } from "@/workbench/messages";
import {
HighlightedText,
@@ -36,6 +36,7 @@ import {
deleteKeymap,
duplicateKeymap,
isModified,
isKeymapAction,
keymapName,
removeBinding,
removeConflicts,
@@ -61,8 +62,9 @@ type KNode =
type GroupNode = Extract<KNode, { kind: "group" }>;
export function keymapSearchLabels(): string[] {
const draft = useKeymap.getState();
return allActions()
.filter((a) => !a.hidden)
.filter((a) => isKeymapAction(a, draft))
.map((a) => a.title);
}
@@ -107,7 +109,7 @@ export function buildKeymapTree(
const q = query.toLowerCase();
for (const action of actions) {
const bindings = resolveBindings(draft, action.id);
if (action.hidden && !bindings.length) continue;
if (!isKeymapAction(action, draft)) continue;
let hits: number[] | null = null;
if (query) {
hits = wordMatch(action.title, query);
+5
Переглянути файл
@@ -27,6 +27,11 @@ export function resolveBindings(draft: KeymapDraft, id: string): string[] {
return draft.overrides[id]?.map(normalizeBinding) ?? presetBindings(draft.preset, id);
}
/** Hidden actions with shortcuts stay configurable even after their bindings are removed. */
export function isKeymapAction(action: Action, draft: KeymapDraft): boolean {
return !action.hidden || action.id in draft.overrides || presetBindings(draft.preset, action.id).length > 0;
}
export function isModified(draft: KeymapDraft, id: string): boolean {
return id in draft.overrides;
}