Skip to content

Commit 3ad56a9

Browse files
authored
Merge pull request #7 from dotdirfm/inline-editor-viewer
Inline editor viewer
2 parents 2b7ac7c + cf6e1f0 commit 3ad56a9

21 files changed

Lines changed: 2916 additions & 26 deletions

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type ParkedPreviewSurface = {
4444
reuseKey: string;
4545
surfaceKey: string;
4646
mode: "viewer" | "editor";
47+
contributionId?: string;
4748
extensionDirPath: string;
4849
entry: string;
4950
path: string;
@@ -161,6 +162,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
161162
reuseKey,
162163
surfaceKey,
163164
mode,
165+
contributionId: resolved.contribution.id,
164166
extensionDirPath: resolved.extensionDirPath,
165167
entry: resolved.contribution.entry,
166168
path: closingTab.path,
@@ -638,6 +640,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
638640
}}
639641
>
640642
<EditorContainer
643+
contributionId={resolvedEditor.contribution.id}
641644
extensionDirPath={resolvedEditor.extensionDirPath}
642645
entry={resolvedEditor.contribution.entry}
643646
filePath={tab.path}
@@ -685,6 +688,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
685688
}}
686689
>
687690
<ViewerContainer
691+
contributionId={resolved.contribution.id}
688692
extensionDirPath={resolved.extensionDirPath}
689693
entry={resolved.contribution.entry}
690694
filePath={tab.path}
@@ -789,6 +793,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
789793
style={{ visibility: "hidden", position: "absolute", inset: 0, opacity: 0, pointerEvents: "none" }}
790794
>
791795
<EditorContainer
796+
contributionId={slot.contributionId}
792797
extensionDirPath={slot.extensionDirPath}
793798
entry={slot.entry}
794799
filePath={slot.path}
@@ -806,6 +811,7 @@ export function PanelGroup({ side }: PanelGroupProps) {
806811
style={{ visibility: "hidden", position: "absolute", inset: 0, opacity: 0, pointerEvents: "none" }}
807812
>
808813
<ViewerContainer
814+
contributionId={slot.contributionId}
809815
extensionDirPath={slot.extensionDirPath}
810816
entry={slot.entry}
811817
filePath={slot.path}

packages/ui/lib/dialogs/dialogContext.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export type DialogSpec =
147147
| {
148148
type: "viewer";
149149
surfaceKey?: string;
150+
contributionId?: string;
150151
extensionDirPath: string;
151152
entry: string;
152153
props: ViewerProps;
@@ -156,6 +157,7 @@ export type DialogSpec =
156157
| {
157158
type: "editor";
158159
surfaceKey?: string;
160+
contributionId?: string;
159161
extensionDirPath: string;
160162
entry: string;
161163
props: EditorProps;
@@ -556,6 +558,7 @@ function renderDialogContent(dialog: DialogSpec, ctx: DialogContextValue, stackI
556558
case "viewer":
557559
return (
558560
<ViewerContainer
561+
contributionId={dialog.contributionId}
559562
extensionDirPath={dialog.extensionDirPath}
560563
entry={dialog.entry}
561564
filePath={dialog.props.filePath}
@@ -569,6 +572,7 @@ function renderDialogContent(dialog: DialogSpec, ctx: DialogContextValue, stackI
569572
case "editor":
570573
return (
571574
<EditorContainer
575+
contributionId={dialog.contributionId}
572576
extensionDirPath={dialog.extensionDirPath}
573577
entry={dialog.entry}
574578
filePath={dialog.props.filePath}
@@ -589,6 +593,7 @@ function renderExtensionDialogSurface(dialog: ExtensionDialogSpec, visible: bool
589593
return (
590594
<ViewerContainer
591595
key={dialog.surfaceKey}
596+
contributionId={dialog.contributionId}
592597
extensionDirPath={dialog.extensionDirPath}
593598
entry={dialog.entry}
594599
filePath={dialog.props.filePath}
@@ -605,6 +610,7 @@ function renderExtensionDialogSurface(dialog: ExtensionDialogSpec, visible: bool
605610
return (
606611
<EditorContainer
607612
key={dialog.surfaceKey}
613+
contributionId={dialog.contributionId}
608614
extensionDirPath={dialog.extensionDirPath}
609615
entry={dialog.entry}
610616
filePath={dialog.props.filePath}

packages/ui/lib/features/bridge/bridge.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ export interface Bridge {
261261
getMountedRoots(): Promise<string[]>;
262262
getAppDirs(): Promise<AppDirs>;
263263
getEnv(): Promise<Record<string, string>>;
264+
debugLog?(message: string): Promise<void>;
264265
openExternal?(url: string): Promise<void>;
265266
};
266267
systemTheme: {

packages/ui/lib/features/commands/builtInCommandContributions.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
COMMANDLINE_EXECUTE,
1111
COMMANDLINE_PASTE,
1212
CURSOR_DOWN,
13+
CURSOR_DOCUMENT_END,
14+
CURSOR_DOCUMENT_START,
1315
CURSOR_END,
1416
CURSOR_HOME,
1517
CURSOR_LEFT,
@@ -22,6 +24,8 @@ import {
2224
DELETE_LEFT,
2325
DELETE_RIGHT,
2426
DOTDIR_CANCEL_NAVIGATION,
27+
DOTDIR_EDITOR_FIND,
28+
DOTDIR_EDITOR_SAVE,
2529
DOTDIR_CLOSE_WINDOW,
2630
DOTDIR_EXIT,
2731
DOTDIR_FOCUS_LEFT_PANEL,
@@ -86,10 +90,12 @@ export const builtInCommandContributions: CommandContribution[] = [
8690
{ command: TOGGLE_PANELS, title: "Toggle Panels", category: "View" },
8791
{ command: RUN_COMMANDS, title: "Run Commands", category: "View", palette: false },
8892
{ command: SHOW_EXTENSIONS, title: "Show Extensions", shortTitle: "Plugins", category: "View" },
89-
{ command: SHOW_FIND_FILES, title: "Find Files", shortTitle: "Find", category: "View" },
93+
{ command: SHOW_FIND_FILES, title: "Find Files", shortTitle: "Find", category: "View", when: "!dialogOpen" },
9094
{ command: SHOW_COMMAND_PALETTE, title: "Show All Commands", category: "View" },
9195
{ command: CLOSE_VIEWER, title: "Close Viewer", category: "View" },
9296
{ command: CLOSE_EDITOR, title: "Close Editor", category: "View" },
97+
{ command: DOTDIR_EDITOR_FIND, title: "Find in Editor", category: "View", when: "focusEditor", palette: false },
98+
{ command: DOTDIR_EDITOR_SAVE, title: "Save File", category: "File", when: "focusEditor", palette: false },
9399

94100
// ── Navigation ────────────────────────────────────────────────────────────
95101
{ command: SWITCH_PANEL, title: "Switch Panel", category: "Navigation" },
@@ -105,6 +111,8 @@ export const builtInCommandContributions: CommandContribution[] = [
105111
{ command: CURSOR_RIGHT, title: "Cursor Right", category: "Navigation" },
106112
{ command: CURSOR_HOME, title: "Cursor to Start", category: "Navigation" },
107113
{ command: CURSOR_END, title: "Cursor to End", category: "Navigation" },
114+
{ command: CURSOR_DOCUMENT_START, title: "Cursor to Document Start", category: "Navigation" },
115+
{ command: CURSOR_DOCUMENT_END, title: "Cursor to Document End", category: "Navigation" },
108116
{ command: CURSOR_PAGE_UP, title: "Cursor Page Up", category: "Navigation" },
109117
{ command: CURSOR_PAGE_DOWN, title: "Cursor Page Down", category: "Navigation" },
110118
{ command: SELECT_UP, title: "Select Up", category: "Navigation" },

packages/ui/lib/features/commands/commandIds.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export const SHOW_FIND_FILES = "showFindFiles";
66
export const SHOW_COMMAND_PALETTE = "showCommandPalette";
77
export const CLOSE_VIEWER = "closeViewer";
88
export const CLOSE_EDITOR = "closeEditor";
9+
export const DOTDIR_EDITOR_FIND = "dotdir.editorFind";
10+
export const DOTDIR_EDITOR_SAVE = "dotdir.editorSave";
911

1012
export const SWITCH_PANEL = "switchPanel";
1113
export const DOTDIR_FOCUS_LEFT_PANEL = "dotdir.focusLeftPanel";
@@ -20,6 +22,8 @@ export const CURSOR_LEFT = "cursorLeft";
2022
export const CURSOR_RIGHT = "cursorRight";
2123
export const CURSOR_HOME = "cursorHome";
2224
export const CURSOR_END = "cursorEnd";
25+
export const CURSOR_DOCUMENT_START = "cursorDocumentStart";
26+
export const CURSOR_DOCUMENT_END = "cursorDocumentEnd";
2327
export const CURSOR_PAGE_UP = "cursorPageUp";
2428
export const CURSOR_PAGE_DOWN = "cursorPageDown";
2529
export const CURSOR_WORD_LEFT = "cursorWordLeft";

packages/ui/lib/features/commands/commands.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,16 @@ export interface KeybindingContribution {
5454
export type KeybindingLayer = "default" | "extension" | "user";
5555

5656
type CommandHandler = (...args: unknown[]) => void | Promise<void>;
57+
type RegisteredCommandHandler = {
58+
handler: CommandHandler;
59+
isActive?: () => boolean;
60+
};
5761
type ContextGetter = () => Record<string, unknown>;
5862
type ResolvedKeybinding = Keybinding & { normalizedKey: string };
5963

6064
export class CommandRegistry {
6165
private contributions = new Map<string, CommandContribution>();
62-
private handlers = new Map<string, CommandHandler[]>();
66+
private handlers = new Map<string, RegisteredCommandHandler[]>();
6367
private keybindingLayers: Record<KeybindingLayer, Keybinding[]> = {
6468
default: [],
6569
extension: [],
@@ -112,18 +116,19 @@ export class CommandRegistry {
112116
};
113117
}
114118

115-
registerCommand(id: string, handler: CommandHandler): () => void {
119+
registerCommand(id: string, handler: CommandHandler, options?: { isActive?: () => boolean }): () => void {
116120
const handlers = this.handlers.get(id);
121+
const entry: RegisteredCommandHandler = { handler, isActive: options?.isActive };
117122
if (handlers) {
118-
handlers.push(handler);
123+
handlers.push(entry);
119124
} else {
120-
this.handlers.set(id, [handler]);
125+
this.handlers.set(id, [entry]);
121126
}
122127
this.notifyListeners();
123128
return () => {
124129
const registered = this.handlers.get(id);
125130
if (!registered) return;
126-
const idx = registered.indexOf(handler);
131+
const idx = registered.indexOf(entry);
127132
if (idx < 0) return;
128133
registered.splice(idx, 1);
129134
if (registered.length === 0) {
@@ -169,12 +174,20 @@ export class CommandRegistry {
169174
return;
170175
}
171176

172-
const selected = registrations[registrations.length - 1];
177+
const selected =
178+
[...registrations].reverse().find((entry) => {
179+
if (!entry.isActive) return false;
180+
try {
181+
return entry.isActive();
182+
} catch {
183+
return false;
184+
}
185+
}) ?? registrations[registrations.length - 1];
173186
if (!selected) return;
174187

175188
console.log("[dotdir:command]", id, ...args);
176189
try {
177-
await selected(...args);
190+
await selected.handler(...args);
178191
} catch (err) {
179192
console.error(`Command ${id} failed:`, err);
180193
}

packages/ui/lib/features/commands/registerKeybindings.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Keybinding, KeybindingLayer } from "@/features/commands/commands";
2+
import { MONACO_QUICK_COMMAND_ACTION } from "@/features/extensions/builtins/monacoCommandBridge";
23
import {
34
ACCEPT,
45
CANCEL,
@@ -9,6 +10,8 @@ import {
910
COMMANDLINE_CUT,
1011
COMMANDLINE_EXECUTE,
1112
COMMANDLINE_PASTE,
13+
CURSOR_DOCUMENT_END,
14+
CURSOR_DOCUMENT_START,
1215
CURSOR_DOWN,
1316
CURSOR_END,
1417
CURSOR_HOME,
@@ -22,6 +25,7 @@ import {
2225
DELETE_LEFT,
2326
DELETE_RIGHT,
2427
DOTDIR_CLOSE_WINDOW,
28+
DOTDIR_EDITOR_SAVE,
2529
DOTDIR_EXIT,
2630
DOTDIR_NEW_WINDOW,
2731
DOTDIR_OPEN_LEFT_PANEL_MENU,
@@ -60,8 +64,8 @@ import {
6064
SELECT_WORD_LEFT,
6165
SELECT_WORD_RIGHT,
6266
SHOW_COMMAND_PALETTE,
63-
SHOW_FIND_FILES,
6467
SHOW_EXTENSIONS,
68+
SHOW_FIND_FILES,
6569
SWITCH_PANEL,
6670
TOGGLE_HIDDEN_FILES,
6771
TOGGLE_PANELS,
@@ -82,7 +86,7 @@ const appBuiltInKeybindings: Keybinding[] = [
8286
{ command: TOGGLE_HIDDEN_FILES, key: "ctrl+.", mac: "cmd+." },
8387
{ command: TOGGLE_PANELS, key: "ctrl+o", mac: "cmd+o", when: "!terminalCommandRunning" },
8488
{ command: SHOW_EXTENSIONS, key: "f11" },
85-
{ command: SHOW_FIND_FILES, key: "alt+f7" },
89+
{ command: SHOW_FIND_FILES, key: "alt+f7", when: "!dialogOpen" },
8690
{ command: DOTDIR_OPEN_LEFT_PANEL_MENU, key: "alt+f1", when: "!dialogOpen" },
8791
{ command: DOTDIR_OPEN_RIGHT_PANEL_MENU, key: "alt+f2", when: "!dialogOpen" },
8892
{ command: DOTDIR_NEW_WINDOW, key: "ctrl+n", mac: "cmd+n", when: "supportsWindowManagement && !dialogOpen" },
@@ -105,12 +109,36 @@ const appBuiltInKeybindings: Keybinding[] = [
105109
{ command: LIST_MAKE_DIR, key: "f7", when: "focusPanel" },
106110

107111
// Command palette
108-
{ command: SHOW_COMMAND_PALETTE, key: "cmd+shift+p" },
109-
{ command: SHOW_COMMAND_PALETTE, key: "cmd+p" },
112+
{ command: SHOW_COMMAND_PALETTE, key: "f1" },
113+
{ command: MONACO_QUICK_COMMAND_ACTION, key: "ctrl+f1", mac: "cmd+f1", when: "focusEditor" },
110114

111115
// Close viewer/editor commands
112116
{ command: CLOSE_VIEWER, key: "escape", when: "focusViewer" },
113117
{ command: CLOSE_EDITOR, key: "escape", when: "focusEditor" },
118+
{ command: DOTDIR_EDITOR_SAVE, key: "ctrl+s", mac: "cmd+s", when: "focusEditor" },
119+
{ command: CURSOR_UP, key: "up", when: "focusEditor" },
120+
{ command: CURSOR_DOWN, key: "down", when: "focusEditor" },
121+
{ command: CURSOR_LEFT, key: "left", when: "focusEditor" },
122+
{ command: CURSOR_RIGHT, key: "right", when: "focusEditor" },
123+
{ command: CURSOR_HOME, key: "home", mac: "cmd+left", when: "focusEditor" },
124+
{ command: CURSOR_END, key: "end", mac: "cmd+right", when: "focusEditor" },
125+
{ command: CURSOR_DOCUMENT_START, key: "ctrl+home", mac: "alt+home", when: "focusEditor" },
126+
{ command: CURSOR_DOCUMENT_END, key: "ctrl+end", mac: "alt+end", when: "focusEditor" },
127+
{ command: CURSOR_PAGE_UP, key: "pageup", when: "focusEditor" },
128+
{ command: CURSOR_PAGE_DOWN, key: "pagedown", when: "focusEditor" },
129+
{ command: CURSOR_WORD_LEFT, key: "ctrl+left", mac: "alt+left", when: "focusEditor" },
130+
{ command: CURSOR_WORD_RIGHT, key: "ctrl+right", mac: "alt+right", when: "focusEditor" },
131+
{ command: SELECT_UP, key: "shift+up", when: "focusEditor" },
132+
{ command: SELECT_DOWN, key: "shift+down", when: "focusEditor" },
133+
{ command: SELECT_LEFT, key: "shift+left", when: "focusEditor" },
134+
{ command: SELECT_RIGHT, key: "shift+right", when: "focusEditor" },
135+
{ command: SELECT_HOME, key: "shift+home", mac: "cmd+shift+left", when: "focusEditor" },
136+
{ command: SELECT_END, key: "shift+end", mac: "cmd+shift+right", when: "focusEditor" },
137+
{ command: SELECT_PAGE_UP, key: "shift+pageup", when: "focusEditor" },
138+
{ command: SELECT_PAGE_DOWN, key: "shift+pagedown", when: "focusEditor" },
139+
{ command: SELECT_WORD_LEFT, key: "ctrl+shift+left", mac: "alt+shift+left", when: "focusEditor" },
140+
{ command: SELECT_WORD_RIGHT, key: "ctrl+shift+right", mac: "alt+shift+right", when: "focusEditor" },
141+
{ command: SELECT_ALL, key: "ctrl+a", mac: "cmd+a", when: "focusEditor" },
114142

115143
// Exit command
116144
{ command: DOTDIR_CLOSE_WINDOW, key: "f10", when: "supportsWindowManagement" },

0 commit comments

Comments
 (0)