@tooee/view 0.1.22 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -12
- package/dist/View.d.ts.map +1 -1
- package/dist/View.js +5 -1
- package/dist/View.js.map +1 -1
- package/dist/components/ViewScreen.d.ts +28 -0
- package/dist/components/ViewScreen.d.ts.map +1 -0
- package/dist/components/ViewScreen.js +29 -0
- package/dist/components/ViewScreen.js.map +1 -0
- package/dist/components/subviews/CodeSubview.d.ts +1 -1
- package/dist/components/subviews/CodeSubview.d.ts.map +1 -1
- package/dist/components/subviews/CodeSubview.js +20 -89
- package/dist/components/subviews/CodeSubview.js.map +1 -1
- package/dist/components/subviews/CustomSubview.d.ts +1 -1
- package/dist/components/subviews/CustomSubview.d.ts.map +1 -1
- package/dist/components/subviews/CustomSubview.js +19 -94
- package/dist/components/subviews/CustomSubview.js.map +1 -1
- package/dist/components/subviews/MarkdownSubview.d.ts +1 -1
- package/dist/components/subviews/MarkdownSubview.d.ts.map +1 -1
- package/dist/components/subviews/MarkdownSubview.js +32 -106
- package/dist/components/subviews/MarkdownSubview.js.map +1 -1
- package/dist/components/subviews/TableSubview.d.ts +1 -1
- package/dist/components/subviews/TableSubview.d.ts.map +1 -1
- package/dist/components/subviews/TableSubview.js +22 -123
- package/dist/components/subviews/TableSubview.js.map +1 -1
- package/dist/components/subviews/index.d.ts +0 -1
- package/dist/components/subviews/index.d.ts.map +1 -1
- package/dist/components/subviews/index.js +0 -1
- package/dist/components/subviews/index.js.map +1 -1
- package/dist/components/subviews/types.d.ts +6 -0
- package/dist/components/subviews/types.d.ts.map +1 -1
- package/dist/default-provider.d.ts +6 -3
- package/dist/default-provider.d.ts.map +1 -1
- package/dist/default-provider.js +24 -34
- package/dist/default-provider.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -3
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -3
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useContentCommands.d.ts +15 -0
- package/dist/hooks/useContentCommands.d.ts.map +1 -0
- package/dist/hooks/useContentCommands.js +21 -0
- package/dist/hooks/useContentCommands.js.map +1 -0
- package/dist/hooks/useViewCommandContext.d.ts +10 -42
- package/dist/hooks/useViewCommandContext.d.ts.map +1 -1
- package/dist/hooks/useViewCommandContext.js +3 -30
- package/dist/hooks/useViewCommandContext.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +15 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +14 -14
- package/src/View.tsx +6 -1
- package/src/components/ViewScreen.tsx +76 -0
- package/src/components/subviews/CodeSubview.tsx +30 -120
- package/src/components/subviews/CustomSubview.tsx +32 -123
- package/src/components/subviews/MarkdownSubview.tsx +49 -130
- package/src/components/subviews/TableSubview.tsx +36 -164
- package/src/components/subviews/index.ts +0 -1
- package/src/components/subviews/types.ts +6 -0
- package/src/default-provider.ts +37 -34
- package/src/hooks/index.ts +2 -7
- package/src/hooks/useContentCommands.ts +29 -0
- package/src/hooks/useViewCommandContext.ts +13 -81
- package/src/index.ts +1 -1
- package/src/types.ts +15 -16
- package/dist/components/SubviewLayout.d.ts +0 -16
- package/dist/components/SubviewLayout.d.ts.map +0 -1
- package/dist/components/SubviewLayout.js +0 -18
- package/dist/components/SubviewLayout.js.map +0 -1
- package/dist/hooks/useMarkState.d.ts +0 -14
- package/dist/hooks/useMarkState.d.ts.map +0 -1
- package/dist/hooks/useMarkState.js +0 -71
- package/dist/hooks/useMarkState.js.map +0 -1
- package/dist/hooks/useViewCommands.d.ts +0 -13
- package/dist/hooks/useViewCommands.d.ts.map +0 -1
- package/dist/hooks/useViewCommands.js +0 -20
- package/dist/hooks/useViewCommands.js.map +0 -1
- package/src/components/SubviewLayout.tsx +0 -48
- package/src/hooks/useMarkState.ts +0 -100
- package/src/hooks/useViewCommands.ts +0 -36
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { useCopyCommand, useToggleLineNumbersCommand } from "@tooee/shell";
|
|
3
|
+
import { useConfig } from "@tooee/config";
|
|
4
|
+
/**
|
|
5
|
+
* The commands a content viewer owns on top of `DocumentScreen`: copying the
|
|
6
|
+
* whole document and toggling the line-number gutter. Theme, quit, actions and
|
|
7
|
+
* every row-level command belong to the document controller and its screen.
|
|
8
|
+
*/
|
|
9
|
+
export function useContentCommands({ content, textContent }) {
|
|
10
|
+
const config = useConfig();
|
|
11
|
+
const [showLineNumbers, setShowLineNumbers] = useState(config.view?.gutter ?? true);
|
|
12
|
+
useCopyCommand({
|
|
13
|
+
getText: () => (content ? textContent : undefined),
|
|
14
|
+
});
|
|
15
|
+
useToggleLineNumbersCommand({
|
|
16
|
+
showLineNumbers,
|
|
17
|
+
onToggle: () => setShowLineNumbers((v) => !v),
|
|
18
|
+
});
|
|
19
|
+
return { showLineNumbers };
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=useContentCommands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useContentCommands.js","sourceRoot":"","sources":["../../src/hooks/useContentCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAQzC;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAE,OAAO,EAAE,WAAW,EAA4B;IACnF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAA;IAEnF,cAAc,CAAC;QACb,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;KACnD,CAAC,CAAA;IACF,2BAA2B,CAAC;QAC1B,eAAe;QACf,QAAQ,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;KAC9C,CAAC,CAAA;IAEF,OAAO,EAAE,eAAe,EAAE,CAAA;AAC5B,CAAC"}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import type { Mode } from "@tooee/commands";
|
|
2
|
-
import type { NavigationState } from "@tooee/shell";
|
|
3
1
|
import type { MarkSet } from "@tooee/marks";
|
|
4
2
|
import type { AnyContent } from "../types.js";
|
|
5
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* The `view` field contributed to the command context (see augmentation below).
|
|
5
|
+
*
|
|
6
|
+
* This slice is content-only. Row state — cursor, selection, active and
|
|
7
|
+
* selected rows — is generic to every row document and lives on `ctx.document`,
|
|
8
|
+
* which `DocumentScreen` provides alongside this.
|
|
9
|
+
*/
|
|
6
10
|
export interface ViewCommandContext {
|
|
7
11
|
content: AnyContent;
|
|
8
12
|
format: string;
|
|
9
13
|
title?: string;
|
|
10
14
|
data?: unknown;
|
|
11
|
-
|
|
12
|
-
selection: {
|
|
13
|
-
start: number;
|
|
14
|
-
end: number;
|
|
15
|
-
} | null;
|
|
16
|
-
mode: Mode;
|
|
17
|
-
toggledIndices: Set<number>;
|
|
15
|
+
/** Reload the content from its provider. */
|
|
18
16
|
reload: () => void;
|
|
19
17
|
marks: {
|
|
20
18
|
setMarkSet: (set: MarkSet) => void;
|
|
@@ -23,15 +21,12 @@ export interface ViewCommandContext {
|
|
|
23
21
|
userMarks: MarkSet[];
|
|
24
22
|
providerMarks: MarkSet[];
|
|
25
23
|
};
|
|
26
|
-
/** Subview extras (e.g. activeRow/selectedRows for tables). */
|
|
27
|
-
[key: string]: unknown;
|
|
28
24
|
}
|
|
29
25
|
declare module "@tooee/commands" {
|
|
30
26
|
interface CommandContext {
|
|
31
27
|
view: ViewCommandContext;
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
|
-
type ViewNavigationContext = Pick<NavigationState, "cursor" | "selection" | "toggledIndices">;
|
|
35
30
|
export interface CreateViewCommandContextOptions {
|
|
36
31
|
/**
|
|
37
32
|
* Content represented by this command context. Custom/headless surfaces may
|
|
@@ -41,37 +36,10 @@ export interface CreateViewCommandContextOptions {
|
|
|
41
36
|
format?: string;
|
|
42
37
|
title?: string;
|
|
43
38
|
data?: unknown;
|
|
44
|
-
nav?: ViewNavigationContext;
|
|
45
|
-
cursor?: number | null;
|
|
46
|
-
selection?: {
|
|
47
|
-
start: number;
|
|
48
|
-
end: number;
|
|
49
|
-
} | null;
|
|
50
|
-
/** Caller-owned mode value. Prefer `useProvideViewCommandContext` in React so this is live. */
|
|
51
|
-
mode: Mode;
|
|
52
|
-
toggledIndices?: Set<number>;
|
|
53
39
|
reload?: () => void;
|
|
54
40
|
marks?: Partial<ViewCommandContext["marks"]>;
|
|
55
|
-
extras?: Record<string, unknown>;
|
|
56
41
|
}
|
|
57
|
-
export type ProvideViewCommandContextOptions =
|
|
58
|
-
|
|
59
|
-
mode?: Mode;
|
|
60
|
-
};
|
|
61
|
-
export declare function createViewCommandContext({ content, format, title, data, nav, cursor, selection, mode, toggledIndices, reload, marks, extras, }: CreateViewCommandContextOptions): ViewCommandContext;
|
|
42
|
+
export type ProvideViewCommandContextOptions = CreateViewCommandContextOptions;
|
|
43
|
+
export declare function createViewCommandContext({ content, format, title, data, reload, marks, }: CreateViewCommandContextOptions): ViewCommandContext;
|
|
62
44
|
export declare function useProvideViewCommandContext(options: ProvideViewCommandContextOptions | (() => ProvideViewCommandContextOptions)): void;
|
|
63
|
-
interface UseViewCommandContextParams {
|
|
64
|
-
content: AnyContent;
|
|
65
|
-
nav: NavigationState;
|
|
66
|
-
reload: () => void;
|
|
67
|
-
providerMarks: MarkSet[];
|
|
68
|
-
userMarks: MarkSet[];
|
|
69
|
-
setMarkSet: (set: MarkSet) => void;
|
|
70
|
-
clearMarkNamespace: (namespace: string) => void;
|
|
71
|
-
clearAllUserMarks: () => void;
|
|
72
|
-
/** Extra fields merged into the view context (e.g. activeRow, selectedRows for table) */
|
|
73
|
-
extras?: Record<string, unknown>;
|
|
74
|
-
}
|
|
75
|
-
export declare function useViewCommandContext({ content, nav, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, extras, }: UseViewCommandContextParams): void;
|
|
76
|
-
export {};
|
|
77
45
|
//# sourceMappingURL=useViewCommandContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useViewCommandContext.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"useViewCommandContext.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,UAAU,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,4CAA4C;IAC5C,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,KAAK,EAAE;QACL,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;QAClC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;QAC3C,QAAQ,EAAE,MAAM,IAAI,CAAA;QACpB,SAAS,EAAE,OAAO,EAAE,CAAA;QACpB,aAAa,EAAE,OAAO,EAAE,CAAA;KACzB,CAAA;CACF;AAED,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,cAAc;QACtB,IAAI,EAAE,kBAAkB,CAAA;KACzB;CACF;AAID,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAA;CAC7C;AAED,MAAM,MAAM,gCAAgC,GAAG,+BAA+B,CAAA;AAE9E,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,GACN,EAAE,+BAA+B,GAAG,kBAAkB,CAwBtD;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,gCAAgC,GAAG,CAAC,MAAM,gCAAgC,CAAC,QAKrF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useProvideCommandContextKey
|
|
1
|
+
import { useProvideCommandContextKey } from "@tooee/commands";
|
|
2
2
|
const noop = () => { };
|
|
3
|
-
export function createViewCommandContext({ content, format, title, data,
|
|
3
|
+
export function createViewCommandContext({ content, format, title, data, reload, marks, }) {
|
|
4
4
|
const resolvedFormat = format ?? content?.format ?? "custom";
|
|
5
5
|
const resolvedContent = content ??
|
|
6
6
|
{
|
|
@@ -9,15 +9,10 @@ export function createViewCommandContext({ content, format, title, data, nav, cu
|
|
|
9
9
|
title,
|
|
10
10
|
};
|
|
11
11
|
return {
|
|
12
|
-
...extras,
|
|
13
12
|
content: resolvedContent,
|
|
14
13
|
format: resolvedFormat,
|
|
15
14
|
title: title ?? content?.title,
|
|
16
15
|
data: data ?? ("data" in resolvedContent ? resolvedContent.data : undefined),
|
|
17
|
-
cursor: cursor ?? nav?.cursor ?? null,
|
|
18
|
-
selection: selection ?? nav?.selection ?? null,
|
|
19
|
-
mode,
|
|
20
|
-
toggledIndices: toggledIndices ?? nav?.toggledIndices ?? new Set(),
|
|
21
16
|
reload: reload ?? noop,
|
|
22
17
|
marks: {
|
|
23
18
|
setMarkSet: marks?.setMarkSet ?? noop,
|
|
@@ -29,28 +24,6 @@ export function createViewCommandContext({ content, format, title, data, nav, cu
|
|
|
29
24
|
};
|
|
30
25
|
}
|
|
31
26
|
export function useProvideViewCommandContext(options) {
|
|
32
|
-
|
|
33
|
-
useProvideCommandContextKey("view", () => {
|
|
34
|
-
const resolvedOptions = typeof options === "function" ? options() : options;
|
|
35
|
-
return createViewCommandContext({
|
|
36
|
-
...resolvedOptions,
|
|
37
|
-
mode: resolvedOptions.mode ?? mode,
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
export function useViewCommandContext({ content, nav, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, extras, }) {
|
|
42
|
-
useProvideViewCommandContext({
|
|
43
|
-
content,
|
|
44
|
-
nav,
|
|
45
|
-
reload,
|
|
46
|
-
marks: {
|
|
47
|
-
setMarkSet,
|
|
48
|
-
clearNamespace: clearMarkNamespace,
|
|
49
|
-
clearAll: clearAllUserMarks,
|
|
50
|
-
userMarks,
|
|
51
|
-
providerMarks,
|
|
52
|
-
},
|
|
53
|
-
extras,
|
|
54
|
-
});
|
|
27
|
+
useProvideCommandContextKey("view", () => createViewCommandContext(typeof options === "function" ? options() : options));
|
|
55
28
|
}
|
|
56
29
|
//# sourceMappingURL=useViewCommandContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useViewCommandContext.js","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,
|
|
1
|
+
{"version":3,"file":"useViewCommandContext.js","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAiC7D,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAiBrB,MAAM,UAAU,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,GAC2B;IAChC,MAAM,cAAc,GAAG,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,QAAQ,CAAA;IAC5D,MAAM,eAAe,GACnB,OAAO;QACN;YACC,MAAM,EAAE,cAAc;YACtB,IAAI;YACJ,KAAK;SACgB,CAAA;IAEzB,OAAO;QACL,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK;QAC9B,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,EAAE,MAAM,IAAI,IAAI;QACtB,KAAK,EAAE;YACL,UAAU,EAAE,KAAK,EAAE,UAAU,IAAI,IAAI;YACrC,cAAc,EAAE,KAAK,EAAE,cAAc,IAAI,IAAI;YAC7C,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,IAAI;YACjC,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE;YACjC,aAAa,EAAE,KAAK,EAAE,aAAa,IAAI,EAAE;SAC1C;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,OAAoF;IAEpF,2BAA2B,CAAC,MAAM,EAAE,GAAG,EAAE,CACvC,wBAAwB,CAAC,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAC9E,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ export { DirectoryView } from "./DirectoryView.js";
|
|
|
3
3
|
export { launch, launchDirectory } from "./launch.js";
|
|
4
4
|
export type { ViewLaunchOptions } from "./launch.js";
|
|
5
5
|
export { createFileProvider, createStdinProvider, createTableFileProvider, createTableStdinProvider, } from "./default-provider.js";
|
|
6
|
+
export type { CreateProviderOptions } from "./default-provider.js";
|
|
6
7
|
export { listDirectoryFiles } from "./directory-provider.js";
|
|
7
8
|
export type { DirectoryEntry } from "./directory-provider.js";
|
|
8
|
-
export { createViewCommandContext, useProvideViewCommandContext,
|
|
9
|
+
export { createViewCommandContext, useProvideViewCommandContext, } from "./hooks/useViewCommandContext.js";
|
|
9
10
|
export type { CreateViewCommandContextOptions, ProvideViewCommandContextOptions, ViewCommandContext, } from "./hooks/useViewCommandContext.js";
|
|
10
11
|
export type { AnyContent, Content, ContentChunk, ContentFormat, ContentProvider, ContentRenderer, ContentRendererProps, CustomContent, ViewContent, ViewContentProvider, ColumnDef, TableRow, } from "./types.js";
|
|
11
12
|
export { getTextContent, isBuiltinContent, isCustomContent } from "./types.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,+BAA+B,EAC/B,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { DirectoryView } from "./DirectoryView.js";
|
|
|
3
3
|
export { launch, launchDirectory } from "./launch.js";
|
|
4
4
|
export { createFileProvider, createStdinProvider, createTableFileProvider, createTableStdinProvider, } from "./default-provider.js";
|
|
5
5
|
export { listDirectoryFiles } from "./directory-provider.js";
|
|
6
|
-
export { createViewCommandContext, useProvideViewCommandContext,
|
|
6
|
+
export { createViewCommandContext, useProvideViewCommandContext, } from "./hooks/useViewCommandContext.js";
|
|
7
7
|
export { getTextContent, isBuiltinContent, isCustomContent } from "./types.js";
|
|
8
8
|
export { CodeBlockChrome } from "@tooee/renderers";
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,kCAAkC,CAAA;AAoBzC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import type { ColumnDef, TableRow } from "@tooee/renderers";
|
|
3
|
-
import type {
|
|
2
|
+
import type { ColumnDef, SourceLineRow, TableRow } from "@tooee/renderers";
|
|
3
|
+
import type { DocumentController } from "@tooee/shell";
|
|
4
|
+
import type { MarkSet } from "@tooee/marks";
|
|
4
5
|
export type Content = MarkdownContent | CodeContent | TextContent | TableContent;
|
|
5
6
|
export type ContentFormat = Content["format"];
|
|
6
7
|
interface BaseContent {
|
|
@@ -35,22 +36,20 @@ export interface CustomContent<T = unknown> {
|
|
|
35
36
|
export type AnyContent = Content | CustomContent;
|
|
36
37
|
export interface ContentRendererProps {
|
|
37
38
|
content: CustomContent;
|
|
38
|
-
lineCount: number;
|
|
39
|
-
cursor?: number;
|
|
40
|
-
selectionStart?: number;
|
|
41
|
-
selectionEnd?: number;
|
|
42
|
-
/** Combined mark state (nav + provider + user marks) */
|
|
43
|
-
marks?: MarkState;
|
|
44
39
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* `
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
40
|
+
* The host's document controller. Its rows are the content's source lines
|
|
41
|
+
* (`SourceLineRow`), which is also the unit navigation, search and copy work
|
|
42
|
+
* in; `row.text` is the plain-text line and `row.source` its provenance.
|
|
43
|
+
*
|
|
44
|
+
* A renderer that owns a `<row-document>` binds the controller directly — it
|
|
45
|
+
* satisfies `DocumentBindings`, so `ref`, `decorations` and `onMouseDown`
|
|
46
|
+
* spread onto the element the way the built-in views wire them. A renderer
|
|
47
|
+
* with its own markup reads `activeIndex` and `navigation.selection` for
|
|
48
|
+
* cursor state and calls `selectRow(index)` from its mouse handlers;
|
|
49
|
+
* `selectRow` stands down while a modal overlay is open, so it can be wired
|
|
50
|
+
* unconditionally.
|
|
52
51
|
*/
|
|
53
|
-
|
|
52
|
+
document: DocumentController<SourceLineRow>;
|
|
54
53
|
}
|
|
55
54
|
export type ContentRenderer = (props: ContentRendererProps) => ReactNode;
|
|
56
55
|
export type AppendableFormat = Extract<ContentFormat, "markdown" | "code" | "text">;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgHA,oBAAoB;AAEpB,MAAM,eAAe,GAAgB,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAEnF,MAAM,UAAU,gBAAgB,CAAC,OAAmB;IAClD,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAmB;IAChD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,cAAc,EAAE,CAAA;IACjC,CAAC;IAED,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,QAAQ,CAAA;QACzB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3E,CAAA;YACD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrD,CAAC;QACD;YACE,OAAO,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACjF,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tooee/view",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Terminal content viewer for markdown, code, text, and tables",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -37,27 +37,27 @@
|
|
|
37
37
|
"typecheck": "tsc --noEmit"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@tooee/commands": "0.
|
|
41
|
-
"@tooee/config": "0.
|
|
42
|
-
"@tooee/layout": "0.
|
|
43
|
-
"@tooee/marks": "0.
|
|
44
|
-
"@tooee/overlays": "0.
|
|
45
|
-
"@tooee/renderers": "0.
|
|
46
|
-
"@tooee/search": "0.
|
|
47
|
-
"@tooee/shell": "0.
|
|
48
|
-
"@tooee/themes": "0.
|
|
40
|
+
"@tooee/commands": "0.2.0",
|
|
41
|
+
"@tooee/config": "0.2.0",
|
|
42
|
+
"@tooee/layout": "0.2.0",
|
|
43
|
+
"@tooee/marks": "0.2.0",
|
|
44
|
+
"@tooee/overlays": "0.2.0",
|
|
45
|
+
"@tooee/renderers": "0.2.0",
|
|
46
|
+
"@tooee/search": "0.2.0",
|
|
47
|
+
"@tooee/shell": "0.2.0",
|
|
48
|
+
"@tooee/themes": "0.2.0",
|
|
49
49
|
"marked": "^17.0.4"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@opentui/core": "^0.
|
|
53
|
-
"@opentui/react": "^0.
|
|
52
|
+
"@opentui/core": "^0.4.3",
|
|
53
|
+
"@opentui/react": "^0.4.3",
|
|
54
54
|
"@types/bun": "^1.3.10",
|
|
55
55
|
"@types/react": "^19.2.14",
|
|
56
56
|
"typescript": "^5.9.3"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@opentui/core": "^0.
|
|
60
|
-
"@opentui/react": "^0.
|
|
59
|
+
"@opentui/core": "^0.4.3",
|
|
60
|
+
"@opentui/react": "^0.4.3",
|
|
61
61
|
"react": "^18.0.0 || ^19.0.0"
|
|
62
62
|
}
|
|
63
63
|
}
|
package/src/View.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useMemo, useState } from "react"
|
|
2
2
|
import { useTheme } from "@tooee/themes"
|
|
3
3
|
import type { ActionDefinition } from "@tooee/commands"
|
|
4
4
|
import type { MarkSet } from "@tooee/marks"
|
|
@@ -50,6 +50,10 @@ export function View({ contentProvider, actions, renderers, codeBlockRenderers }
|
|
|
50
50
|
setUserMarks([])
|
|
51
51
|
}, [])
|
|
52
52
|
|
|
53
|
+
// Mark sets are decoration layers; the controller composes them with the
|
|
54
|
+
// interaction layers it generates, ordered by each set's own priority.
|
|
55
|
+
const decorations = useMemo(() => [...providerMarks, ...userMarks], [providerMarks, userMarks])
|
|
56
|
+
|
|
53
57
|
if (error) {
|
|
54
58
|
return (
|
|
55
59
|
<box style={{ flexDirection: "column" }}>
|
|
@@ -67,6 +71,7 @@ export function View({ contentProvider, actions, renderers, codeBlockRenderers }
|
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
const shared = {
|
|
74
|
+
decorations,
|
|
70
75
|
providerMarks,
|
|
71
76
|
userMarks,
|
|
72
77
|
setMarkSet,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ReactNode } from "react"
|
|
2
|
+
import type { ActionDefinition } from "@tooee/commands"
|
|
3
|
+
import type { StatusBarItem } from "@tooee/layout"
|
|
4
|
+
import type { MarkSet } from "@tooee/marks"
|
|
5
|
+
import { DocumentScreen, type DocumentController } from "@tooee/shell"
|
|
6
|
+
import { useProvideViewCommandContext } from "../hooks/useViewCommandContext.js"
|
|
7
|
+
import type { AnyContent } from "../types.js"
|
|
8
|
+
|
|
9
|
+
export interface ViewScreenProps<T> {
|
|
10
|
+
content: AnyContent
|
|
11
|
+
controller: DocumentController<T>
|
|
12
|
+
streaming: boolean
|
|
13
|
+
actions?: ActionDefinition[]
|
|
14
|
+
/** Content-shaped status (format, line/row counts), rendered before Mode. */
|
|
15
|
+
statusItems?: StatusBarItem[]
|
|
16
|
+
reload: () => void
|
|
17
|
+
providerMarks: MarkSet[]
|
|
18
|
+
userMarks: MarkSet[]
|
|
19
|
+
setMarkSet: (set: MarkSet) => void
|
|
20
|
+
clearMarkNamespace: (namespace: string) => void
|
|
21
|
+
clearAllUserMarks: () => void
|
|
22
|
+
children: ReactNode
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The chrome every subview shares: `DocumentScreen` for the row-document half
|
|
27
|
+
* (theme/quit commands, actions, `ctx.document`, layout, standard status) plus
|
|
28
|
+
* the content-only `ctx.view` slice that viewers contribute on top.
|
|
29
|
+
*/
|
|
30
|
+
export function ViewScreen<T>({
|
|
31
|
+
content,
|
|
32
|
+
controller,
|
|
33
|
+
streaming,
|
|
34
|
+
actions,
|
|
35
|
+
statusItems,
|
|
36
|
+
reload,
|
|
37
|
+
providerMarks,
|
|
38
|
+
userMarks,
|
|
39
|
+
setMarkSet,
|
|
40
|
+
clearMarkNamespace,
|
|
41
|
+
clearAllUserMarks,
|
|
42
|
+
children,
|
|
43
|
+
}: ViewScreenProps<T>) {
|
|
44
|
+
useProvideViewCommandContext({
|
|
45
|
+
content,
|
|
46
|
+
reload,
|
|
47
|
+
marks: {
|
|
48
|
+
setMarkSet,
|
|
49
|
+
clearNamespace: clearMarkNamespace,
|
|
50
|
+
clearAll: clearAllUserMarks,
|
|
51
|
+
userMarks,
|
|
52
|
+
providerMarks,
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const items: StatusBarItem[] = [
|
|
57
|
+
...(statusItems ?? []),
|
|
58
|
+
...(streaming ? [{ label: "Status:", value: "streaming" }] : []),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<DocumentScreen
|
|
63
|
+
controller={controller}
|
|
64
|
+
titleBar={
|
|
65
|
+
content.title
|
|
66
|
+
? { title: content.title, subtitle: content.format }
|
|
67
|
+
: { title: content.format }
|
|
68
|
+
}
|
|
69
|
+
statusItems={items}
|
|
70
|
+
actions={actions}
|
|
71
|
+
context={{ kind: content.format, title: content.title, reload }}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
</DocumentScreen>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
@@ -1,143 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CodeView, type
|
|
3
|
-
import {
|
|
4
|
-
import { useCommandContext } from "@tooee/commands"
|
|
5
|
-
import { useHasModalOverlay } from "@tooee/overlays"
|
|
6
|
-
import { useViewCommandContext } from "../../hooks/useViewCommandContext.js"
|
|
7
|
-
import { actionsToContextMenuEntries, useContextMenu, useCopy, useNavigation } from "@tooee/shell"
|
|
8
|
-
import { findMatchingLines, useSearch } from "@tooee/search"
|
|
1
|
+
import { useMemo } from "react"
|
|
2
|
+
import { CodeView, sourceLines, sourceLineAdapter, type SourceLineRow } from "@tooee/renderers"
|
|
3
|
+
import { actionsToContextMenuEntries, useDocumentController } from "@tooee/shell"
|
|
9
4
|
import type { CodeContent, TextContent } from "../../types.js"
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { SubviewLayout } from "../SubviewLayout.js"
|
|
5
|
+
import { useContentCommands } from "../../hooks/useContentCommands.js"
|
|
6
|
+
import { ViewScreen } from "../ViewScreen.js"
|
|
13
7
|
import type { SubviewProps } from "./types.js"
|
|
14
8
|
|
|
15
9
|
interface CodeSubviewProps extends SubviewProps {
|
|
16
10
|
content: CodeContent | TextContent
|
|
17
11
|
}
|
|
18
12
|
|
|
19
|
-
export function CodeSubview({
|
|
20
|
-
content,
|
|
21
|
-
providerMarks,
|
|
22
|
-
userMarks,
|
|
23
|
-
setMarkSet,
|
|
24
|
-
clearMarkNamespace,
|
|
25
|
-
clearAllUserMarks,
|
|
26
|
-
reload,
|
|
27
|
-
streaming,
|
|
28
|
-
actions,
|
|
29
|
-
}: CodeSubviewProps) {
|
|
30
|
-
const { theme } = useTheme()
|
|
31
|
-
const docRef = useRef<RowDocumentRenderable>(null)
|
|
32
|
-
const hasModalOverlay = useHasModalOverlay()
|
|
33
|
-
const contextMenu = useContextMenu()
|
|
34
|
-
const { invoke } = useCommandContext()
|
|
13
|
+
export function CodeSubview({ content, decorations, actions, ...screen }: CodeSubviewProps) {
|
|
35
14
|
const textContent = content.format === "code" ? content.code : content.text
|
|
36
|
-
|
|
37
|
-
const
|
|
15
|
+
// One navigation row per physical source line; row index is the source line.
|
|
16
|
+
const lineRows = useMemo(() => sourceLines(textContent), [textContent])
|
|
38
17
|
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
multiSelect: true,
|
|
42
|
-
})
|
|
43
|
-
const search = useSearch({
|
|
44
|
-
match: (query) => findMatchingLines(textContent, query),
|
|
45
|
-
onJump: nav.setCursor,
|
|
46
|
-
})
|
|
47
|
-
useCopy({
|
|
48
|
-
getRowText: (index) => lines[index] ?? "",
|
|
49
|
-
cursor: nav.cursor,
|
|
50
|
-
selection: nav.selection,
|
|
51
|
-
toggledIndices: nav.toggledIndices,
|
|
52
|
-
})
|
|
53
|
-
const layoutNav = { ...nav, ...search }
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
if (nav.cursor !== null) {
|
|
57
|
-
docRef.current?.scrollToRow(nav.cursor, "nearest")
|
|
58
|
-
}
|
|
59
|
-
}, [nav.cursor])
|
|
60
|
-
|
|
61
|
-
const { themeName, showLineNumbers } = useViewCommands({ content, textContent, actions })
|
|
62
|
-
|
|
63
|
-
const markState = useMarkState({
|
|
64
|
-
nav,
|
|
65
|
-
search,
|
|
66
|
-
theme,
|
|
67
|
-
providerMarks,
|
|
68
|
-
userMarks,
|
|
69
|
-
})
|
|
18
|
+
const { showLineNumbers } = useContentCommands({ content, textContent })
|
|
19
|
+
const contextMenu = useMemo(() => actionsToContextMenuEntries(actions), [actions])
|
|
70
20
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
setMarkSet,
|
|
78
|
-
clearMarkNamespace,
|
|
79
|
-
clearAllUserMarks,
|
|
21
|
+
const document = useDocumentController<SourceLineRow>({
|
|
22
|
+
rows: lineRows,
|
|
23
|
+
adapter: sourceLineAdapter,
|
|
24
|
+
multiSelect: true,
|
|
25
|
+
decorations,
|
|
26
|
+
contextMenu,
|
|
80
27
|
})
|
|
81
28
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const menuEntries = useMemo(() => actionsToContextMenuEntries(actions), [actions])
|
|
85
|
-
|
|
86
|
-
// Left-click selects the clicked line; right-click selects it and opens the
|
|
87
|
-
// same app-provided action menu as table rows. Both stand down while a modal
|
|
88
|
-
// overlay is up (theme picker, command palette, Ask/Choose), matching the
|
|
89
|
-
// keyboard stand-down and avoiding covered-app mutations.
|
|
90
|
-
const setCursor = nav.setCursor
|
|
91
|
-
const openContextMenu = contextMenu.open
|
|
92
|
-
const handleRowClick = useCallback(
|
|
93
|
-
(index: number) => {
|
|
94
|
-
if (hasModalOverlay) return
|
|
95
|
-
setCursor(index)
|
|
96
|
-
},
|
|
97
|
-
[hasModalOverlay, setCursor],
|
|
98
|
-
)
|
|
99
|
-
const handleRowContextMenu = useCallback(
|
|
100
|
-
(index: number, x: number, y: number) => {
|
|
101
|
-
if (hasModalOverlay) return
|
|
102
|
-
setCursor(index)
|
|
103
|
-
openContextMenu(x, y, menuEntries, invoke)
|
|
104
|
-
},
|
|
105
|
-
[hasModalOverlay, setCursor, openContextMenu, menuEntries, invoke],
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
const extraStatusItems = useMemo(() => {
|
|
109
|
-
const selectionCount = nav.selection != null ? nav.selection.end - nav.selection.start + 1 : 0
|
|
110
|
-
const toggledCount = nav.toggledIndices.size
|
|
111
|
-
const selectionItems =
|
|
112
|
-
toggledCount > 0
|
|
113
|
-
? [{ label: "Selected:", value: String(toggledCount) }]
|
|
114
|
-
: selectionCount > 0
|
|
115
|
-
? [{ label: "Selected:", value: String(selectionCount) }]
|
|
116
|
-
: []
|
|
117
|
-
return [
|
|
29
|
+
const statusItems = useMemo(
|
|
30
|
+
() => [
|
|
118
31
|
{ label: "Format:", value: content.format },
|
|
119
|
-
{ label: "Lines:", value: String(
|
|
120
|
-
|
|
121
|
-
]
|
|
122
|
-
|
|
32
|
+
{ label: "Lines:", value: String(lineRows.length) },
|
|
33
|
+
],
|
|
34
|
+
[content.format, lineRows.length],
|
|
35
|
+
)
|
|
123
36
|
|
|
124
37
|
return (
|
|
125
|
-
<
|
|
38
|
+
<ViewScreen
|
|
126
39
|
content={content}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
40
|
+
controller={document}
|
|
41
|
+
actions={actions}
|
|
42
|
+
statusItems={statusItems}
|
|
43
|
+
{...screen}
|
|
131
44
|
>
|
|
132
45
|
<CodeView
|
|
133
|
-
content={
|
|
46
|
+
content={textContent}
|
|
134
47
|
language={content.format === "code" ? content.language : undefined}
|
|
135
48
|
showLineNumbers={showLineNumbers}
|
|
136
|
-
|
|
137
|
-
docRef={docRef}
|
|
138
|
-
onRowClick={handleRowClick}
|
|
139
|
-
onRowContextMenu={handleRowContextMenu}
|
|
49
|
+
document={document}
|
|
140
50
|
/>
|
|
141
|
-
</
|
|
51
|
+
</ViewScreen>
|
|
142
52
|
)
|
|
143
53
|
}
|