Skip to content

Commit d9ca709

Browse files
committed
Refactor command handling by introducing command IDs for better maintainability
- Added a new file `commandIds.ts` to centralize command identifiers. - Updated keybindings in `registerKeybindings.ts` to use the new command IDs. - Refactored command registration in `useBuiltInCommands.ts` to utilize command IDs. - Enhanced command routing in `useCommandRouting.ts` to support function keys. - Improved interaction commands in `useInteractionCommands.ts` by replacing string literals with command IDs. - Updated terminal view to use command IDs for routing. - Refactored help dialog styles to use composition for better styling management. - Added missing command IDs for various commands including file operations and command line actions.
1 parent 16154fb commit d9ca709

16 files changed

Lines changed: 737 additions & 357 deletions

packages/ui/lib/components/FileList/FileList.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ActionQueue } from "@/components/FileList/actionQueue";
22
import type { PanelSide } from "@/entities/panel/model/types";
33
import type { FileListTabState } from "@/entities/tab/model/types";
44
import { useCommandRegistry } from "@/features/commands/commands";
5+
import { TERMINAL_EXECUTE, VIEW_FILE } from "@/features/commands/commandIds";
56
import { useFileStyleResolver } from "@/features/fss/fileStyleResolver";
67
import { usePanelControllerRegistry } from "@/features/panels/panelControllers";
78
import { useMediaQuery } from "@/hooks/useMediaQuery";
@@ -205,7 +206,7 @@ export const FileList = memo(function FileList({ side, tabId, state, showHidden,
205206
} else if (entry.type === "folder") {
206207
await onNavigateRef.current(join(currentPathRef.current, entry.name));
207208
} else if (entry.type === "file") {
208-
void commandRegistry.executeCommand("viewFile", entry.path as string, entry.name, Number(entry.meta.size));
209+
void commandRegistry.executeCommand(VIEW_FILE, entry.path as string, entry.name, Number(entry.meta.size));
209210
}
210211
},
211212
[commandRegistry],
@@ -323,7 +324,7 @@ export const FileList = memo(function FileList({ side, tabId, state, showHidden,
323324
if (now - lastClickTimeRef.current < 300) {
324325
lastClickTimeRef.current = 0;
325326
if (executable) {
326-
actionQueue.enqueue(() => commandRegistry.executeCommand("terminal.execute", entry.path as string));
327+
actionQueue.enqueue(() => commandRegistry.executeCommand(TERMINAL_EXECUTE, entry.path as string));
327328
} else {
328329
actionQueue.enqueue(() => navigateToEntry(entry));
329330
}

packages/ui/lib/components/FileList/fileListActions.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { ActionQueue } from "@/components/FileList/actionQueue";
22
import { useCommandLine } from "@/features/command-line/useCommandLine";
33
import { useCommandRegistry } from "@/features/commands/commands";
4+
import { EDIT_FILE, TERMINAL_EXECUTE, VIEW_FILE } from "@/features/commands/commandIds";
45
import { useFileOperationHandlers } from "@/features/file-ops/fileOperationHandlers";
56
import type { FsNode } from "fss-lang";
67
import { useMemo, useRef } from "react";
@@ -50,7 +51,7 @@ export function useFileListActionHandlers(deps: FileListActionDeps) {
5051
const [item] = getSelectedOrActiveEntries(depsRef.current);
5152
if (!item || item.entry.type !== "file") return;
5253
if (!(item.entry.meta as { executable?: boolean }).executable) return;
53-
void commandRegistry.executeCommand("terminal.execute", item.entry.path as string);
54+
void commandRegistry.executeCommand(TERMINAL_EXECUTE, item.entry.path as string);
5455
}),
5556
open: () =>
5657
depsRef.current.actionQueue.enqueue(async () => {
@@ -61,15 +62,15 @@ export function useFileListActionHandlers(deps: FileListActionDeps) {
6162
depsRef.current.actionQueue.enqueue(() => {
6263
const [item] = getSelectedOrActiveEntries(depsRef.current);
6364
if (item && item.entry.type === "file") {
64-
void commandRegistry.executeCommand("viewFile", item.entry.path as string, item.entry.name, Number(item.entry.meta.size));
65+
void commandRegistry.executeCommand(VIEW_FILE, item.entry.path as string, item.entry.name, Number(item.entry.meta.size));
6566
}
6667
}),
6768
editFile: () =>
6869
depsRef.current.actionQueue.enqueue(() => {
6970
const [item] = getSelectedOrActiveEntries(depsRef.current);
7071
if (item && item.entry.type === "file") {
7172
const langId = typeof item.entry.lang === "string" && item.entry.lang ? item.entry.lang : "plaintext";
72-
void commandRegistry.executeCommand("editFile", item.entry.path as string, item.entry.name, Number(item.entry.meta.size), langId);
73+
void commandRegistry.executeCommand(EDIT_FILE, item.entry.path as string, item.entry.name, Number(item.entry.meta.size), langId);
7374
}
7475
}),
7576
moveToTrash: () =>

packages/ui/lib/components/FileList/useFileListCommands.ts

Lines changed: 94 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,54 @@
11
import type { ActionQueue } from "@/components/FileList/actionQueue";
22
import { useBridge } from "@/features/bridge/useBridge";
33
import { useCommandRegistry } from "@/features/commands/commands";
4+
import {
5+
CURSOR_DOWN,
6+
CURSOR_END,
7+
CURSOR_HOME,
8+
CURSOR_LEFT,
9+
CURSOR_PAGE_DOWN,
10+
CURSOR_PAGE_UP,
11+
CURSOR_RIGHT,
12+
CURSOR_UP,
13+
FILELIST_CURSOR_DOWN,
14+
FILELIST_CURSOR_END,
15+
FILELIST_CURSOR_HOME,
16+
FILELIST_CURSOR_LEFT,
17+
FILELIST_CURSOR_PAGE_DOWN,
18+
FILELIST_CURSOR_PAGE_UP,
19+
FILELIST_CURSOR_RIGHT,
20+
FILELIST_CURSOR_UP,
21+
FILELIST_GO_HOME,
22+
FILELIST_GO_TO_PARENT,
23+
FILELIST_REFRESH,
24+
FILELIST_SELECT_DOWN,
25+
FILELIST_SELECT_END,
26+
FILELIST_SELECT_HOME,
27+
FILELIST_SELECT_LEFT,
28+
FILELIST_SELECT_PAGE_DOWN,
29+
FILELIST_SELECT_PAGE_UP,
30+
FILELIST_SELECT_RIGHT,
31+
FILELIST_SELECT_UP,
32+
LIST_COPY,
33+
LIST_EDIT_FILE,
34+
LIST_EXECUTE,
35+
LIST_MOVE,
36+
LIST_MOVE_TO_TRASH,
37+
LIST_OPEN,
38+
LIST_PERMANENT_DELETE,
39+
LIST_RENAME,
40+
LIST_VIEW_FILE,
41+
PASTE_FILENAME,
42+
PASTE_PATH,
43+
SELECT_DOWN,
44+
SELECT_END,
45+
SELECT_HOME,
46+
SELECT_LEFT,
47+
SELECT_PAGE_DOWN,
48+
SELECT_PAGE_UP,
49+
SELECT_RIGHT,
50+
SELECT_UP,
51+
} from "@/features/commands/commandIds";
452
import { useFocusContext } from "@/focusContext";
553
import { useInteractionContext, type InteractionIntent } from "@/interactionContext";
654
import { isContainerPath, parseContainerPath } from "@/utils/containerPath";
@@ -28,36 +76,36 @@ interface UseFileListCommandsArgs {
2876
type CommandHandler = (...args: unknown[]) => void;
2977

3078
const COMMAND_KEYS = {
31-
cursorUp: "cursorUp",
32-
cursorDown: "cursorDown",
33-
cursorLeft: "cursorLeft",
34-
cursorRight: "cursorRight",
35-
cursorHome: "cursorHome",
36-
cursorEnd: "cursorEnd",
37-
cursorPageUp: "cursorPageUp",
38-
cursorPageDown: "cursorPageDown",
39-
selectUp: "selectUp",
40-
selectDown: "selectDown",
41-
selectLeft: "selectLeft",
42-
selectRight: "selectRight",
43-
selectHome: "selectHome",
44-
selectEnd: "selectEnd",
45-
selectPageUp: "selectPageUp",
46-
selectPageDown: "selectPageDown",
47-
goToParent: "filelist.goToParent",
48-
goHome: "filelist.goHome",
49-
refresh: "filelist.refresh",
50-
execute: "list.execute",
51-
open: "list.open",
52-
viewFile: "list.viewFile",
53-
editFile: "list.editFile",
54-
moveToTrash: "list.moveToTrash",
55-
permanentDelete: "list.permanentDelete",
56-
copy: "list.copy",
57-
move: "list.move",
58-
rename: "list.rename",
59-
pasteFilename: "pasteFilename",
60-
pastePath: "pastePath",
79+
cursorUp: CURSOR_UP,
80+
cursorDown: CURSOR_DOWN,
81+
cursorLeft: CURSOR_LEFT,
82+
cursorRight: CURSOR_RIGHT,
83+
cursorHome: CURSOR_HOME,
84+
cursorEnd: CURSOR_END,
85+
cursorPageUp: CURSOR_PAGE_UP,
86+
cursorPageDown: CURSOR_PAGE_DOWN,
87+
selectUp: SELECT_UP,
88+
selectDown: SELECT_DOWN,
89+
selectLeft: SELECT_LEFT,
90+
selectRight: SELECT_RIGHT,
91+
selectHome: SELECT_HOME,
92+
selectEnd: SELECT_END,
93+
selectPageUp: SELECT_PAGE_UP,
94+
selectPageDown: SELECT_PAGE_DOWN,
95+
goToParent: FILELIST_GO_TO_PARENT,
96+
goHome: FILELIST_GO_HOME,
97+
refresh: FILELIST_REFRESH,
98+
execute: LIST_EXECUTE,
99+
open: LIST_OPEN,
100+
viewFile: LIST_VIEW_FILE,
101+
editFile: LIST_EDIT_FILE,
102+
moveToTrash: LIST_MOVE_TO_TRASH,
103+
permanentDelete: LIST_PERMANENT_DELETE,
104+
copy: LIST_COPY,
105+
move: LIST_MOVE,
106+
rename: LIST_RENAME,
107+
pasteFilename: PASTE_FILENAME,
108+
pastePath: PASTE_PATH,
61109
} as const;
62110

63111
const INTERACTION_COMMAND_IDS = new Set<string>([
@@ -77,22 +125,22 @@ const INTERACTION_COMMAND_IDS = new Set<string>([
77125
COMMAND_KEYS.selectEnd,
78126
COMMAND_KEYS.selectPageUp,
79127
COMMAND_KEYS.selectPageDown,
80-
"filelist.cursorUp",
81-
"filelist.cursorDown",
82-
"filelist.cursorLeft",
83-
"filelist.cursorRight",
84-
"filelist.cursorHome",
85-
"filelist.cursorEnd",
86-
"filelist.cursorPageUp",
87-
"filelist.cursorPageDown",
88-
"filelist.selectUp",
89-
"filelist.selectDown",
90-
"filelist.selectLeft",
91-
"filelist.selectRight",
92-
"filelist.selectHome",
93-
"filelist.selectEnd",
94-
"filelist.selectPageUp",
95-
"filelist.selectPageDown",
128+
FILELIST_CURSOR_UP,
129+
FILELIST_CURSOR_DOWN,
130+
FILELIST_CURSOR_LEFT,
131+
FILELIST_CURSOR_RIGHT,
132+
FILELIST_CURSOR_HOME,
133+
FILELIST_CURSOR_END,
134+
FILELIST_CURSOR_PAGE_UP,
135+
FILELIST_CURSOR_PAGE_DOWN,
136+
FILELIST_SELECT_UP,
137+
FILELIST_SELECT_DOWN,
138+
FILELIST_SELECT_LEFT,
139+
FILELIST_SELECT_RIGHT,
140+
FILELIST_SELECT_HOME,
141+
FILELIST_SELECT_END,
142+
FILELIST_SELECT_PAGE_UP,
143+
FILELIST_SELECT_PAGE_DOWN,
96144
]);
97145

98146
export function useFileListCommands({

packages/ui/lib/components/PanelGroup/PanelGroup.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import {
1515
import type { PanelTab } from "@/entities/tab/model/types";
1616
import { useBridge } from "@/features/bridge/useBridge";
1717
import { useCommandRegistry } from "@/features/commands/commands";
18+
import {
19+
DOTDIR_OPEN_LEFT_PANEL_MENU,
20+
DOTDIR_OPEN_RIGHT_PANEL_MENU,
21+
LIST_OPEN,
22+
} from "@/features/commands/commandIds";
1823
import { EditorContainer, ViewerContainer } from "@/features/extensions/ExtensionContainer";
1924
import { usePanelControllerRegistry } from "@/features/panels/panelControllers";
2025
import { type FileListPanelController } from "@/features/panels/useFileListPanel";
@@ -471,7 +476,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
471476
}, [setActivePanel, side]);
472477

473478
useEffect(() => {
474-
const commandId = side === "left" ? "dotdir.openLeftPanelMenu" : "dotdir.openRightPanelMenu";
479+
const commandId = side === "left" ? DOTDIR_OPEN_LEFT_PANEL_MENU : DOTDIR_OPEN_RIGHT_PANEL_MENU;
475480
return commandRegistry.registerCommand(commandId, () => {
476481
openPanelMenu();
477482
});
@@ -564,7 +569,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
564569
onConfirm={() => {
565570
close();
566571
requestAnimationFrame(() => {
567-
void commandRegistry.executeCommand("list.open");
572+
void commandRegistry.executeCommand(LIST_OPEN);
568573
});
569574
}}
570575
/>

packages/ui/lib/components/PanelGroup/usePanelCommands.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import type { PanelSide } from "@/entities/panel/model/types";
22
import { useCommandRegistry } from "@/features/commands/commands";
3+
import {
4+
CLOSE_TAB,
5+
EDIT_IN_OPPOSITE_PANEL,
6+
NEW_TAB,
7+
OPEN_CURRENT_DIR_IN_OPPOSITE_PANEL_CURRENT_TAB,
8+
OPEN_CURRENT_DIR_IN_OPPOSITE_PANEL_NEW_TAB,
9+
OPEN_SELECTED_DIR_IN_OPPOSITE_PANEL_CURRENT_TAB,
10+
OPEN_SELECTED_DIR_IN_OPPOSITE_PANEL_NEW_TAB,
11+
PREVIEW_IN_OPPOSITE_PANEL,
12+
} from "@/features/commands/commandIds";
313
import { OPPOSITE_PANEL } from "@/entities/panel/model/panelSide";
414
import { createFilelistTab, createPreviewTab } from "@/entities/tab/model/tabsAtoms";
515
import type { PanelTab } from "@/entities/tab/model/types";
@@ -32,13 +42,13 @@ export function usePanelCommands(args: UsePanelCommandsArgs): void {
3242
useEffect(() => {
3343
if (!args.active) return;
3444

35-
const disposables = [commandRegistry.registerCommand("newTab", () => argsRef.current.handleNewTab()), commandRegistry.registerCommand("closeTab", () => void argsRef.current.handleCloseActiveTab())];
45+
const disposables = [commandRegistry.registerCommand(NEW_TAB, () => argsRef.current.handleNewTab()), commandRegistry.registerCommand(CLOSE_TAB, () => void argsRef.current.handleCloseActiveTab())];
3646

3747
const register = (id: string, fn: () => void | Promise<void>) => {
3848
disposables.push(commandRegistry.registerCommand(id, fn));
3949
};
4050

41-
register("openCurrentDirInOppositePanelCurrentTab", () => {
51+
register(OPEN_CURRENT_DIR_IN_OPPOSITE_PANEL_CURRENT_TAB, () => {
4252
const opposite = OPPOSITE_PANEL[argsRef.current.side];
4353
const fileListTab = argsRef.current.activeTabRef.current?.type === "filelist" ? argsRef.current.activeTabRef.current : null;
4454
if (!fileListTab) return;
@@ -51,7 +61,7 @@ export function usePanelCommands(args: UsePanelCommandsArgs): void {
5161
argsRef.current.setActivePanel(opposite);
5262
});
5363

54-
register("openCurrentDirInOppositePanelNewTab", () => {
64+
register(OPEN_CURRENT_DIR_IN_OPPOSITE_PANEL_NEW_TAB, () => {
5565
const opposite = OPPOSITE_PANEL[argsRef.current.side];
5666
const fileListTab = argsRef.current.activeTabRef.current?.type === "filelist" ? argsRef.current.activeTabRef.current : null;
5767
if (!fileListTab) return;
@@ -63,7 +73,7 @@ export function usePanelCommands(args: UsePanelCommandsArgs): void {
6373
argsRef.current.setActivePanel(opposite);
6474
});
6575

66-
register("openSelectedDirInOppositePanelCurrentTab", () => {
76+
register(OPEN_SELECTED_DIR_IN_OPPOSITE_PANEL_CURRENT_TAB, () => {
6777
const entry = getSelectedEntry(argsRef.current.activeTabRef.current);
6878
if (!entry || entry.type !== "folder") return;
6979
const opposite = OPPOSITE_PANEL[argsRef.current.side];
@@ -75,7 +85,7 @@ export function usePanelCommands(args: UsePanelCommandsArgs): void {
7585
argsRef.current.setActivePanel(opposite);
7686
});
7787

78-
register("openSelectedDirInOppositePanelNewTab", () => {
88+
register(OPEN_SELECTED_DIR_IN_OPPOSITE_PANEL_NEW_TAB, () => {
7989
const entry = getSelectedEntry(argsRef.current.activeTabRef.current);
8090
if (!entry || entry.type !== "folder") return;
8191
const opposite = OPPOSITE_PANEL[argsRef.current.side];
@@ -87,7 +97,7 @@ export function usePanelCommands(args: UsePanelCommandsArgs): void {
8797
argsRef.current.setActivePanel(opposite);
8898
});
8999

90-
register("previewInOppositePanel", () => {
100+
register(PREVIEW_IN_OPPOSITE_PANEL, () => {
91101
const side = argsRef.current.side;
92102
const entry = getSelectedEntry(argsRef.current.activeTabRef.current);
93103
if (!entry || entry.type !== "file") return;
@@ -117,7 +127,7 @@ export function usePanelCommands(args: UsePanelCommandsArgs): void {
117127
argsRef.current.setActivePanel(opposite);
118128
});
119129

120-
register("editInOppositePanel", () => {
130+
register(EDIT_IN_OPPOSITE_PANEL, () => {
121131
const side = argsRef.current.side;
122132
const entry = getSelectedEntry(argsRef.current.activeTabRef.current);
123133
if (!entry || entry.type !== "file") return;

packages/ui/lib/dialogs/HelpDialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { marked } from "marked";
22
import { useEffect, useRef } from "react";
3-
import styles from "./dialogs.module.css";
3+
import styles from "../styles/help-dialog.module.css";
44
import { OverlayDialog } from "./OverlayDialog";
55

66
interface HelpDialogProps {

0 commit comments

Comments
 (0)