mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-15 08:08:18 +00:00
fix(ui): ⌘⌫ erases a tree's speed search query (#3226)
While a tree's speed search has a query, the keymap dispatcher ran ⌫ shortcuts before the tree saw the key: in the Database view ⌘⌫ opened Drop or Remove Data Source. The shared Tree now claims ⌫ with any modifier while a query is active and edits the query like a text field: ⌘⌫ erases it, ⌥⌫ / Ctrl+⌫ erase the last word. Without a query the view's shortcuts run as before. Co-authored-by: Mr0Bread <55754540+Mr0Bread@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,8 @@ import { createRef } from "react";
|
||||
import { act, fireEvent, render, screen, within } from "@testing-library/react";
|
||||
import { Tree, type TreeHandle } from "./Tree";
|
||||
import { getContext } from "@/platform/context";
|
||||
import { registerAction } from "@/platform/actions";
|
||||
import { installKeyboardDispatcher, useKeymap } from "@/platform/keymap";
|
||||
|
||||
interface N {
|
||||
id: string;
|
||||
@@ -251,6 +253,30 @@ describe("Tree speed search", () => {
|
||||
expect(labels(tree)).toContain("App.tsx");
|
||||
});
|
||||
|
||||
it("⌘⌫ erases the query and ⌥⌫ its last word instead of running the view's ⌘⌫ action", () => {
|
||||
const drop = vi.fn();
|
||||
useKeymap.setState({ preset: "intellij-macos", overrides: { "test.drop": ["Meta+Backspace", "Alt+Backspace"] } });
|
||||
const dispose = [registerAction({ id: "test.drop", title: "Drop", run: drop }), installKeyboardDispatcher()];
|
||||
try {
|
||||
const { tree, lead, key } = setup({ defaultExpanded: ["src", "main"] });
|
||||
key("ArrowDown");
|
||||
for (const c of "index.t") key(c);
|
||||
expect(lead()).toBe("index.ts");
|
||||
key("Backspace", { altKey: true });
|
||||
expect(screen.getByRole("status")).toHaveTextContent(/^index\.$/);
|
||||
key("Backspace", { metaKey: true });
|
||||
expect(screen.queryByRole("status")).toBeNull();
|
||||
expect(drop).not.toHaveBeenCalled();
|
||||
// Without a query the shortcut reaches the view again.
|
||||
key("Backspace", { metaKey: true });
|
||||
expect(drop).toHaveBeenCalledOnce();
|
||||
expect(tree).toHaveFocus();
|
||||
} finally {
|
||||
dispose.forEach((d) => d());
|
||||
useKeymap.setState({ overrides: {} });
|
||||
}
|
||||
});
|
||||
|
||||
it("filter mode hides non-matching rows but keeps ancestors", () => {
|
||||
const { tree, key } = setup({ defaultExpanded: ["src", "main"], speedSearchMode: "filter" });
|
||||
key("ArrowDown");
|
||||
|
||||
+13
-3
@@ -31,6 +31,7 @@ import { acquirePopup } from "./popupState";
|
||||
import styles from "./Tree.module.css";
|
||||
import { T } from "./T";
|
||||
import { setContext } from "@/platform/context";
|
||||
import { registerKeyClaim } from "@/platform/keymap";
|
||||
import { useGivenTx } from "@/platform/i18n";
|
||||
import { useTreeReorder, type TreeReorder } from "./treeReorder";
|
||||
import { startPointerDrag, type DragData } from "./pointerDrag";
|
||||
@@ -367,10 +368,18 @@ export function Tree<T>(props: TreeProps<T>) {
|
||||
pendingScrollToLead.current = null;
|
||||
}, [lead, indexOfKey, virtualizer]);
|
||||
|
||||
// Speed search owns Escape while active.
|
||||
// Speed search owns Escape while active, and ⌫ with any modifier: the query is edited like a
|
||||
// text field instead of the view's shortcuts running (⌘⌫ is Drop… in the Database view).
|
||||
useEffect(() => {
|
||||
if (!query) return;
|
||||
return acquirePopup();
|
||||
const release = acquirePopup();
|
||||
const unclaim = registerKeyClaim(
|
||||
(e) => e.key === "Backspace" && e.target instanceof Node && !!scrollRef.current?.contains(e.target),
|
||||
);
|
||||
return () => {
|
||||
release();
|
||||
unclaim();
|
||||
};
|
||||
}, [query]);
|
||||
|
||||
const setExpanded = (row: Row<T>, open: boolean) => {
|
||||
@@ -524,7 +533,8 @@ export function Tree<T>(props: TreeProps<T>) {
|
||||
break;
|
||||
case "Backspace":
|
||||
if (!query) return;
|
||||
setQuery(query.slice(0, -1));
|
||||
// ⌘⌫ erases the query, ⌥⌫ / Ctrl+⌫ its last word, as in a text field.
|
||||
setQuery(e.metaKey ? "" : e.altKey || e.ctrlKey ? query.replace(/\w*\W*$/, "") : query.slice(0, -1));
|
||||
break;
|
||||
case "ArrowDown":
|
||||
case "ArrowUp": {
|
||||
|
||||
Reference in New Issue
Block a user