@tooee/view 0.10.3 → 0.12.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/dist/components/subviews/markdown-subview.d.ts +3 -1
- package/dist/components/subviews/markdown-subview.d.ts.map +1 -1
- package/dist/components/subviews/markdown-subview.js +36 -7
- package/dist/components/subviews/markdown-subview.js.map +1 -1
- package/dist/components/view-screen.d.ts +3 -1
- package/dist/components/view-screen.d.ts.map +1 -1
- package/dist/components/view-screen.js +2 -2
- package/dist/components/view-screen.js.map +1 -1
- package/dist/folds/fold-decorations.d.ts +8 -0
- package/dist/folds/fold-decorations.d.ts.map +1 -0
- package/dist/folds/fold-decorations.js +24 -0
- package/dist/folds/fold-decorations.js.map +1 -0
- package/dist/folds/fold-model.d.ts +41 -0
- package/dist/folds/fold-model.d.ts.map +1 -0
- package/dist/folds/fold-model.js +60 -0
- package/dist/folds/fold-model.js.map +1 -0
- package/dist/folds/markdown-heading-folds.d.ts +13 -0
- package/dist/folds/markdown-heading-folds.d.ts.map +1 -0
- package/dist/folds/markdown-heading-folds.js +45 -0
- package/dist/folds/markdown-heading-folds.js.map +1 -0
- package/dist/folds/use-folds.d.ts +59 -0
- package/dist/folds/use-folds.d.ts.map +1 -0
- package/dist/folds/use-folds.js +126 -0
- package/dist/folds/use-folds.js.map +1 -0
- package/dist/launch.d.ts +2 -0
- package/dist/launch.d.ts.map +1 -1
- package/dist/launch.js.map +1 -1
- package/dist/outline/markdown-outline.d.ts +24 -0
- package/dist/outline/markdown-outline.d.ts.map +1 -0
- package/dist/outline/markdown-outline.js +25 -0
- package/dist/outline/markdown-outline.js.map +1 -0
- package/dist/outline/outline-panel.d.ts +17 -0
- package/dist/outline/outline-panel.d.ts.map +1 -0
- package/dist/outline/outline-panel.js +106 -0
- package/dist/outline/outline-panel.js.map +1 -0
- package/dist/outline/use-outline.d.ts +53 -0
- package/dist/outline/use-outline.d.ts.map +1 -0
- package/dist/outline/use-outline.js +131 -0
- package/dist/outline/use-outline.js.map +1 -0
- package/dist/standalone-router.d.ts.map +1 -1
- package/dist/standalone-router.js +1 -1
- package/dist/standalone-router.js.map +1 -1
- package/dist/view.d.ts +3 -1
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +2 -2
- package/dist/view.js.map +1 -1
- package/package.json +14 -13
- package/src/components/subviews/markdown-subview.tsx +46 -8
- package/src/components/view-screen.tsx +4 -0
- package/src/folds/fold-decorations.ts +30 -0
- package/src/folds/fold-model.ts +99 -0
- package/src/folds/markdown-heading-folds.ts +55 -0
- package/src/folds/use-folds.ts +203 -0
- package/src/launch.tsx +2 -0
- package/src/outline/markdown-outline.ts +45 -0
- package/src/outline/outline-panel.tsx +171 -0
- package/src/outline/use-outline.ts +188 -0
- package/src/standalone-router.tsx +1 -0
- package/src/view.tsx +4 -0
|
@@ -6,7 +6,9 @@ interface MarkdownSubviewProps extends SubviewProps {
|
|
|
6
6
|
content: MarkdownContent;
|
|
7
7
|
codeBlockRenderers?: Record<string, CodeBlockRenderer>;
|
|
8
8
|
onLinkActivate?: MarkdownLinkActivateHandler;
|
|
9
|
+
/** Open the heading outline beside the document at start. */
|
|
10
|
+
outline?: boolean;
|
|
9
11
|
}
|
|
10
|
-
export declare const MarkdownSubview: ({ content, codeBlockRenderers, onLinkActivate, decorations, actions, ...screen }: MarkdownSubviewProps) => ReactNode;
|
|
12
|
+
export declare const MarkdownSubview: ({ content, codeBlockRenderers, onLinkActivate, outline: initialOutline, decorations, actions, ...screen }: MarkdownSubviewProps) => ReactNode;
|
|
11
13
|
export {};
|
|
12
14
|
//# sourceMappingURL=markdown-subview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-subview.d.ts","sourceRoot":"","sources":["../../../src/components/subviews/markdown-subview.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdown-subview.d.ts","sourceRoot":"","sources":["../../../src/components/subviews/markdown-subview.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAa,MAAM,kBAAkB,CAAC;AAGrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,KAAK,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAEnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,UAAU,oBAAqB,SAAQ,YAAY;IACjD,OAAO,EAAE,eAAe,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACvD,cAAc,CAAC,EAAE,2BAA2B,CAAC;IAC7C,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAuBD,eAAO,MAAM,eAAe,8GAQzB,oBAAoB,KAAG,SAgGzB,CAAC"}
|
|
@@ -1,31 +1,60 @@
|
|
|
1
1
|
import { jsx as _jsx } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { useTerminalDimensions } from "@opentui/react";
|
|
2
3
|
import { useBuildCommandContext, useCommand } from "@tooee/commands";
|
|
3
4
|
import { MarkdownView, flattenMarkdown, getFlatBlockText } from "@tooee/renderers";
|
|
4
5
|
import { useMemo, useRef } from "react";
|
|
6
|
+
import { markdownHeadingFoldRanges } from "../../folds/markdown-heading-folds.js";
|
|
7
|
+
import { useFoldActions, useFoldCommands, useFoldState } from "../../folds/use-folds.js";
|
|
5
8
|
import { useContentDocument } from "../../hooks/use-content-document.js";
|
|
9
|
+
import { OutlinePanel } from "../../outline/outline-panel.js";
|
|
10
|
+
import { useMarkdownOutline } from "../../outline/use-outline.js";
|
|
6
11
|
import { ViewScreen } from "../view-screen.js";
|
|
7
12
|
/** Columns moved per h/l press when scrolling a wide block horizontally. */
|
|
8
13
|
const BLOCK_HSCROLL_STEP = 4;
|
|
9
14
|
/**
|
|
10
15
|
* Blocks are the row unit. `getFlatBlockText` keeps search/copy in step with the
|
|
11
16
|
* source mapping (notably for synthetic bullet rows), and `getSource` projects
|
|
12
|
-
* each block's Markdown provenance onto the controller's anchors.
|
|
17
|
+
* each block's Markdown provenance onto the controller's anchors. The key is
|
|
18
|
+
* the block's index in the full flattened document, so it stays the same when
|
|
19
|
+
* folds hide the blocks around it.
|
|
13
20
|
*/
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
const markdownBlockAdapter = function markdownBlockAdapter(blocks) {
|
|
22
|
+
const indices = new Map(blocks.map((block, index) => [block, index]));
|
|
23
|
+
return {
|
|
24
|
+
getKey: (block, index) => indices.get(block) ?? index,
|
|
25
|
+
getSource: (block) => block.source,
|
|
26
|
+
getText: (block) => getFlatBlockText(block),
|
|
27
|
+
};
|
|
17
28
|
};
|
|
18
|
-
export const MarkdownSubview = function MarkdownSubview({ content, codeBlockRenderers, onLinkActivate, decorations, actions, ...screen }) {
|
|
29
|
+
export const MarkdownSubview = function MarkdownSubview({ content, codeBlockRenderers, onLinkActivate, outline: initialOutline = false, decorations, actions, ...screen }) {
|
|
19
30
|
const textContent = content.markdown;
|
|
20
31
|
const lineCount = useMemo(() => textContent.split("\n").length, [textContent]);
|
|
21
32
|
const blocks = useMemo(() => flattenMarkdown(content.markdown), [content.markdown]);
|
|
22
|
-
const
|
|
33
|
+
const adapter = useMemo(() => markdownBlockAdapter(blocks), [blocks]);
|
|
34
|
+
const foldRanges = useMemo(() => markdownHeadingFoldRanges(blocks), [blocks]);
|
|
35
|
+
// Closed heading folds filter `blocks`; `folds.rows` is the one array both
|
|
36
|
+
// the controller and the renderer see.
|
|
37
|
+
const folds = useFoldState(blocks, foldRanges, decorations);
|
|
38
|
+
const { document, showLineNumbers, statusItems } = useContentDocument(folds.rows, adapter, { actions, content, decorations: folds.decorations, textContent }, {
|
|
23
39
|
multiSelect: true,
|
|
40
|
+
preserveCursorByKey: true,
|
|
24
41
|
statusItems: [
|
|
25
42
|
{ label: "Format:", value: content.format },
|
|
26
43
|
{ label: "Lines:", value: String(lineCount) },
|
|
27
44
|
],
|
|
28
45
|
});
|
|
46
|
+
const foldActions = useFoldActions(folds, document.navigation);
|
|
47
|
+
useFoldCommands(folds, foldActions, document.navigation);
|
|
48
|
+
// Declared after the controller, so its jump effect runs after the
|
|
49
|
+
// controller has taken the new rows.
|
|
50
|
+
const outline = useMarkdownOutline({
|
|
51
|
+
blocks,
|
|
52
|
+
folds,
|
|
53
|
+
initialOpen: initialOutline,
|
|
54
|
+
navigation: document.navigation,
|
|
55
|
+
revealRow: document.revealRow,
|
|
56
|
+
});
|
|
57
|
+
const { width: terminalWidth } = useTerminalDimensions();
|
|
29
58
|
const buildCommandContext = useBuildCommandContext();
|
|
30
59
|
const handleLinkActivate = onLinkActivate
|
|
31
60
|
? (href) => onLinkActivate(href, buildCommandContext())
|
|
@@ -60,6 +89,6 @@ export const MarkdownSubview = function MarkdownSubview({ content, codeBlockRend
|
|
|
60
89
|
title: "Scroll block right",
|
|
61
90
|
when: () => cursorScrollable() !== undefined,
|
|
62
91
|
});
|
|
63
|
-
return (_jsx(ViewScreen, { content: content, controller: document, actions: actions, statusItems: statusItems, ...screen, children: _jsx(MarkdownView, { content: content.markdown, blocks:
|
|
92
|
+
return (_jsx(ViewScreen, { content: content, controller: document, actions: actions, statusItems: statusItems, aside: _jsx(OutlinePanel, { outline: outline, foldActions: foldActions }), ...screen, children: _jsx(MarkdownView, { content: content.markdown, blocks: folds.rows, rowNumbers: folds.rowNumbers, foldedBlocks: folds.view.hiddenCounts, showLineNumbers: showLineNumbers, document: document, hScrollableBlocksRef: hScrollableBlocksRef, codeBlockRenderers: codeBlockRenderers, onLinkActivate: handleLinkActivate, imageBasePath: content.imageBasePath, width: outline.visible ? terminalWidth - outline.width : undefined }) }));
|
|
64
93
|
};
|
|
65
94
|
//# sourceMappingURL=markdown-subview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-subview.js","sourceRoot":"","sources":["../../../src/components/subviews/markdown-subview.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGnF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAGxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown-subview.js","sourceRoot":"","sources":["../../../src/components/subviews/markdown-subview.tsx"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,8 @@ export interface ViewScreenProps<T> {
|
|
|
17
17
|
setMarkSet: (set: MarkSet) => void;
|
|
18
18
|
clearMarkNamespace: (namespace: string) => void;
|
|
19
19
|
clearAllUserMarks: () => void;
|
|
20
|
+
/** Optional side region beside the content, such as the Markdown outline. */
|
|
21
|
+
aside?: ReactNode;
|
|
20
22
|
children: ReactNode;
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
@@ -24,5 +26,5 @@ export interface ViewScreenProps<T> {
|
|
|
24
26
|
* (theme/quit commands, actions, `ctx.document`, layout, standard status) plus
|
|
25
27
|
* the content-only `ctx.view` slice that viewers contribute on top.
|
|
26
28
|
*/
|
|
27
|
-
export declare const ViewScreen: <T>({ content, controller, streaming, actions, statusItems, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, children, }: ViewScreenProps<T>) => ReactNode;
|
|
29
|
+
export declare const ViewScreen: <T>({ content, controller, streaming, actions, statusItems, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, aside, children, }: ViewScreenProps<T>) => ReactNode;
|
|
28
30
|
//# sourceMappingURL=view-screen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-screen.d.ts","sourceRoot":"","sources":["../../src/components/view-screen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAuB,CAAC,
|
|
1
|
+
{"version":3,"file":"view-screen.d.ts","sourceRoot":"","sources":["../../src/components/view-screen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAuB,CAAC,mKAc5C,eAAe,CAAC,CAAC,CAAC,KAAG,SAkCvB,CAAC"}
|
|
@@ -6,7 +6,7 @@ import { useProvideViewCommandContext } from "../hooks/use-view-command-context.
|
|
|
6
6
|
* (theme/quit commands, actions, `ctx.document`, layout, standard status) plus
|
|
7
7
|
* the content-only `ctx.view` slice that viewers contribute on top.
|
|
8
8
|
*/
|
|
9
|
-
export const ViewScreen = function ViewScreen({ content, controller, streaming, actions, statusItems, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, children, }) {
|
|
9
|
+
export const ViewScreen = function ViewScreen({ content, controller, streaming, actions, statusItems, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, aside, children, }) {
|
|
10
10
|
useProvideViewCommandContext({
|
|
11
11
|
content,
|
|
12
12
|
marks: {
|
|
@@ -24,6 +24,6 @@ export const ViewScreen = function ViewScreen({ content, controller, streaming,
|
|
|
24
24
|
];
|
|
25
25
|
return (_jsx(DocumentScreen, { controller: controller, titleBar: content.title !== undefined && content.title !== ""
|
|
26
26
|
? { subtitle: content.format, title: content.title }
|
|
27
|
-
: { title: content.format }, statusItems: items, actions: actions, context: { kind: content.format, reload, title: content.title }, children: children }));
|
|
27
|
+
: { title: content.format }, statusItems: items, actions: actions, context: { kind: content.format, reload, title: content.title }, aside: aside, children: children }));
|
|
28
28
|
};
|
|
29
29
|
//# sourceMappingURL=view-screen.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-screen.js","sourceRoot":"","sources":["../../src/components/view-screen.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"view-screen.js","sourceRoot":"","sources":["../../src/components/view-screen.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAqBpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,UAAU,CAAI,EAC/C,OAAO,EACP,UAAU,EACV,SAAS,EACT,OAAO,EACP,WAAW,EACX,MAAM,EACN,aAAa,EACb,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,EACL,QAAQ,GACW;IACnB,4BAA4B,CAAC;QAC3B,OAAO;QACP,KAAK,EAAE;YACL,QAAQ,EAAE,iBAAiB;YAC3B,cAAc,EAAE,kBAAkB;YAClC,aAAa;YACb,UAAU;YACV,SAAS;SACV;QACD,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,KAAK,GAAoB;QAC7B,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QACtB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;IAEF,OAAO,CACL,KAAC,cAAc,IACb,UAAU,EAAE,UAAU,EACtB,QAAQ,EACN,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,EAAE;YACjD,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;YACpD,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,EAE/B,WAAW,EAAE,KAAK,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAC/D,KAAK,EAAE,KAAK,YAEX,QAAQ,GACM,CAClB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DecorationLayer } from "@tooee/renderers";
|
|
2
|
+
import type { FoldView } from "./fold-model.js";
|
|
3
|
+
/**
|
|
4
|
+
* Map decoration layers written against full-array rows onto the visible rows
|
|
5
|
+
* of `view`. Decorations on rows that a closed fold hides are dropped.
|
|
6
|
+
*/
|
|
7
|
+
export declare const projectDecorationLayers: (layers: readonly DecorationLayer[], view: FoldView) => DecorationLayer[];
|
|
8
|
+
//# sourceMappingURL=fold-decorations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-decorations.d.ts","sourceRoot":"","sources":["../../src/folds/fold-decorations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,kBAAkB,CAAC;AAEvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,WAC1B,SAAS,eAAe,EAAE,QAC5B,QAAQ,KACb,eAAe,EAkBjB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map decoration layers written against full-array rows onto the visible rows
|
|
3
|
+
* of `view`. Decorations on rows that a closed fold hides are dropped.
|
|
4
|
+
*/
|
|
5
|
+
export const projectDecorationLayers = function projectDecorationLayers(layers, view) {
|
|
6
|
+
const { visibleToSource, sourceToVisible } = view;
|
|
7
|
+
return layers.map((layer) => ({
|
|
8
|
+
*forVisibleRows(from, to) {
|
|
9
|
+
const sourceFrom = visibleToSource[from];
|
|
10
|
+
const sourceTo = visibleToSource[Math.min(to, visibleToSource.length - 1)];
|
|
11
|
+
if (sourceFrom === undefined || sourceTo === undefined) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
for (const decoration of layer.forVisibleRows(sourceFrom, sourceTo)) {
|
|
15
|
+
const row = sourceToVisible[decoration.row] ?? -1;
|
|
16
|
+
if (row !== -1) {
|
|
17
|
+
yield { ...decoration, row };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
priority: layer.priority,
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=fold-decorations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-decorations.js","sourceRoot":"","sources":["../../src/folds/fold-decorations.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,SAAS,uBAAuB,CACrE,MAAkC,EAClC,IAAc;IAEd,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,CAAC;QAC7C,CAAC,cAAc,CAAC,IAAY,EAAE,EAAU;YACtC,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3E,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACvD,OAAO;YACT,CAAC;YACD,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACpE,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACf,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,EAAE,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;QACD,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Key } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A foldable range of rows. `start` is the header row that stays visible;
|
|
4
|
+
* `start + 1 ..= end` are the rows a closed fold hides. Indices point into the
|
|
5
|
+
* full row array, and `key` is the header row's key, so closed state survives
|
|
6
|
+
* row changes that keep keys stable.
|
|
7
|
+
*/
|
|
8
|
+
export interface FoldRange {
|
|
9
|
+
key: Key;
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
}
|
|
13
|
+
/** The visible projection of a full row array under a set of closed folds. */
|
|
14
|
+
export interface FoldView {
|
|
15
|
+
/** Full-array index of each visible row, in order. */
|
|
16
|
+
visibleToSource: readonly number[];
|
|
17
|
+
/** Visible index of each full-array row, or `-1` when a closed fold hides it. */
|
|
18
|
+
sourceToVisible: readonly number[];
|
|
19
|
+
/** Hidden row count for each closed header, keyed by the header's visible index. */
|
|
20
|
+
hiddenCounts: ReadonlyMap<number, number>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Project `rowCount` rows through the closed folds. A closed range hides its
|
|
24
|
+
* body even when it sits inside another closed range; the outermost header
|
|
25
|
+
* shown carries the count of every row hidden below it.
|
|
26
|
+
*/
|
|
27
|
+
export declare const computeFoldView: (rowCount: number, ranges: readonly FoldRange[], closedKeys: ReadonlySet<Key>) => FoldView;
|
|
28
|
+
/** Ranges that contain `row` (header included), innermost first. */
|
|
29
|
+
export declare const foldsAt: (ranges: readonly FoldRange[], row: number) => readonly FoldRange[];
|
|
30
|
+
/**
|
|
31
|
+
* Keys of the closed ranges that hide `row`: closed ranges whose body
|
|
32
|
+
* (`start + 1 ..= end`) contains it. Opening them all makes `row` visible.
|
|
33
|
+
*/
|
|
34
|
+
export declare const closedFoldsHiding: (ranges: readonly FoldRange[], closedKeys: ReadonlySet<Key>, row: number) => Key[];
|
|
35
|
+
/**
|
|
36
|
+
* The full-array row the cursor should rest on once `view` applies: `row`
|
|
37
|
+
* itself when it stays visible, otherwise the nearest visible row before it,
|
|
38
|
+
* which is the header of the outermost closed fold that hides it.
|
|
39
|
+
*/
|
|
40
|
+
export declare const visibleAnchorRow: (view: FoldView, row: number) => number;
|
|
41
|
+
//# sourceMappingURL=fold-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-model.d.ts","sourceRoot":"","sources":["../../src/folds/fold-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,8EAA8E;AAC9E,MAAM,WAAW,QAAQ;IACvB,sDAAsD;IACtD,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,iFAAiF;IACjF,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oFAAoF;IACpF,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,aAChB,MAAM,UACR,SAAS,SAAS,EAAE,cAChB,WAAW,CAAC,GAAG,CAAC,KAC3B,QA2BF,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,OAAO,WACV,SAAS,SAAS,EAAE,OACvB,MAAM,KACV,SAAS,SAAS,EAIpB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WACpB,SAAS,SAAS,EAAE,cAChB,WAAW,CAAC,GAAG,CAAC,OACvB,MAAM,KACV,GAAG,EAIL,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,SAAmC,QAAQ,OAAO,MAAM,KAAG,MAOvF,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project `rowCount` rows through the closed folds. A closed range hides its
|
|
3
|
+
* body even when it sits inside another closed range; the outermost header
|
|
4
|
+
* shown carries the count of every row hidden below it.
|
|
5
|
+
*/
|
|
6
|
+
export const computeFoldView = function computeFoldView(rowCount, ranges, closedKeys) {
|
|
7
|
+
const closedEnds = new Map();
|
|
8
|
+
for (const range of ranges) {
|
|
9
|
+
if (range.end > range.start && closedKeys.has(range.key)) {
|
|
10
|
+
closedEnds.set(range.start, Math.max(closedEnds.get(range.start) ?? range.end, range.end));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const visibleToSource = [];
|
|
14
|
+
const sourceToVisible = Array.from({ length: rowCount }, () => -1);
|
|
15
|
+
const hiddenCounts = new Map();
|
|
16
|
+
let hiddenUntil = -1;
|
|
17
|
+
for (let index = 0; index < rowCount; index += 1) {
|
|
18
|
+
if (index <= hiddenUntil) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const visibleIndex = visibleToSource.length;
|
|
22
|
+
visibleToSource.push(index);
|
|
23
|
+
sourceToVisible[index] = visibleIndex;
|
|
24
|
+
const end = closedEnds.get(index);
|
|
25
|
+
if (end !== undefined) {
|
|
26
|
+
hiddenUntil = Math.min(end, rowCount - 1);
|
|
27
|
+
hiddenCounts.set(visibleIndex, hiddenUntil - index);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { hiddenCounts, sourceToVisible, visibleToSource };
|
|
31
|
+
};
|
|
32
|
+
/** Ranges that contain `row` (header included), innermost first. */
|
|
33
|
+
export const foldsAt = function foldsAt(ranges, row) {
|
|
34
|
+
return ranges
|
|
35
|
+
.filter((range) => range.end > range.start && range.start <= row && row <= range.end)
|
|
36
|
+
.toSorted((left, right) => right.start - left.start || left.end - right.end);
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Keys of the closed ranges that hide `row`: closed ranges whose body
|
|
40
|
+
* (`start + 1 ..= end`) contains it. Opening them all makes `row` visible.
|
|
41
|
+
*/
|
|
42
|
+
export const closedFoldsHiding = function closedFoldsHiding(ranges, closedKeys, row) {
|
|
43
|
+
return ranges
|
|
44
|
+
.filter((range) => closedKeys.has(range.key) && range.start < row && row <= range.end)
|
|
45
|
+
.map((range) => range.key);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The full-array row the cursor should rest on once `view` applies: `row`
|
|
49
|
+
* itself when it stays visible, otherwise the nearest visible row before it,
|
|
50
|
+
* which is the header of the outermost closed fold that hides it.
|
|
51
|
+
*/
|
|
52
|
+
export const visibleAnchorRow = function visibleAnchorRow(view, row) {
|
|
53
|
+
for (let index = Math.min(row, view.sourceToVisible.length - 1); index >= 0; index -= 1) {
|
|
54
|
+
if ((view.sourceToVisible[index] ?? -1) !== -1) {
|
|
55
|
+
return index;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return row;
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=fold-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-model.js","sourceRoot":"","sources":["../../src/folds/fold-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FlatBlock } from "@tooee/renderers";
|
|
2
|
+
import type { Tokens } from "marked";
|
|
3
|
+
import type { FoldRange } from "./fold-model.js";
|
|
4
|
+
/** The Marked heading token of a flattened block, or `null` when the block is not a heading. */
|
|
5
|
+
export declare const headingToken: (block: FlatBlock) => Tokens.Heading | null;
|
|
6
|
+
/**
|
|
7
|
+
* Heading fold ranges over flattened Markdown blocks. A heading at depth `d`
|
|
8
|
+
* folds every following block up to the next heading of depth `d` or less, or
|
|
9
|
+
* the end of the document. A heading with no body yields no range. Keys are
|
|
10
|
+
* the heading's block index, the same key the Markdown row adapter uses.
|
|
11
|
+
*/
|
|
12
|
+
export declare const markdownHeadingFoldRanges: (blocks: readonly FlatBlock[]) => FoldRange[];
|
|
13
|
+
//# sourceMappingURL=markdown-heading-folds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-heading-folds.d.ts","sourceRoot":"","sources":["../../src/folds/markdown-heading-folds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,gGAAgG;AAChG,eAAO,MAAM,YAAY,UAAgC,SAAS,KAAG,MAAM,CAAC,OAAO,GAAG,IAOrF,CAAC;AAMF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,WAC5B,SAAS,SAAS,EAAE,KAC3B,SAAS,EA2BX,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** The Marked heading token of a flattened block, or `null` when the block is not a heading. */
|
|
2
|
+
export const headingToken = function headingToken(block) {
|
|
3
|
+
if (block.token.type !== "heading") {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
// SAFETY: Marked creates a Heading token for the checked "heading" discriminator.
|
|
7
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Marked's Generic fallback prevents discriminator narrowing
|
|
8
|
+
return block.token;
|
|
9
|
+
};
|
|
10
|
+
const headingDepth = function headingDepth(block) {
|
|
11
|
+
return headingToken(block)?.depth ?? null;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Heading fold ranges over flattened Markdown blocks. A heading at depth `d`
|
|
15
|
+
* folds every following block up to the next heading of depth `d` or less, or
|
|
16
|
+
* the end of the document. A heading with no body yields no range. Keys are
|
|
17
|
+
* the heading's block index, the same key the Markdown row adapter uses.
|
|
18
|
+
*/
|
|
19
|
+
export const markdownHeadingFoldRanges = function markdownHeadingFoldRanges(blocks) {
|
|
20
|
+
const ranges = [];
|
|
21
|
+
const open = [];
|
|
22
|
+
const close = (start, end) => {
|
|
23
|
+
if (end > start) {
|
|
24
|
+
ranges.push({ end, key: start, start });
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
for (const [index, block] of blocks.entries()) {
|
|
28
|
+
const depth = headingDepth(block);
|
|
29
|
+
if (depth === null) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
while (open.length > 0 && (open.at(-1)?.depth ?? 0) >= depth) {
|
|
33
|
+
const finished = open.pop();
|
|
34
|
+
if (finished) {
|
|
35
|
+
close(finished.start, index - 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
open.push({ depth, start: index });
|
|
39
|
+
}
|
|
40
|
+
for (const finished of open) {
|
|
41
|
+
close(finished.start, blocks.length - 1);
|
|
42
|
+
}
|
|
43
|
+
return ranges.toSorted((left, right) => left.start - right.start);
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=markdown-heading-folds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-heading-folds.js","sourceRoot":"","sources":["../../src/folds/markdown-heading-folds.ts"],"names":[],"mappings":"AAKA,gGAAgG;AAChG,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,YAAY,CAAC,KAAgB;IAChE,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kFAAkF;IAClF,6HAA6H;IAC7H,OAAO,KAAK,CAAC,KAAuB,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,SAAS,YAAY,CAAC,KAAgB;IACzD,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;AAC5C,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,SAAS,yBAAyB,CACzE,MAA4B;IAE5B,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAuC,EAAE,CAAC;IACpD,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,EAAE;QAC3C,IAAI,GAAG,GAAG,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,SAAS;QACX,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AACpE,CAAC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ActionDefinition } from "@tooee/commands";
|
|
2
|
+
import type { DecorationLayer } from "@tooee/renderers";
|
|
3
|
+
import type { NavigationState } from "@tooee/shell";
|
|
4
|
+
import type { Key } from "react";
|
|
5
|
+
import type { FoldRange, FoldView } from "./fold-model.js";
|
|
6
|
+
/** Fold state over a full row array and the visible projection it produces. */
|
|
7
|
+
export interface FoldState<T> {
|
|
8
|
+
/** The visible rows: pass this array to the document controller and the renderer. */
|
|
9
|
+
rows: readonly T[];
|
|
10
|
+
/** The full-array row count. */
|
|
11
|
+
rowCount: number;
|
|
12
|
+
ranges: readonly FoldRange[];
|
|
13
|
+
view: FoldView;
|
|
14
|
+
closedKeys: ReadonlySet<Key>;
|
|
15
|
+
setClosedKeys: (keys: ReadonlySet<Key>) => void;
|
|
16
|
+
/** External decoration layers projected onto the visible rows. */
|
|
17
|
+
decorations: DecorationLayer[];
|
|
18
|
+
/** One-based full-array row number for each visible row, or `undefined` when nothing is hidden. */
|
|
19
|
+
rowNumbers: readonly number[] | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Hold the closed fold keys for `rows` and project the rows, decorations and
|
|
23
|
+
* gutter numbers onto what stays visible. `ranges` and `decorations` use
|
|
24
|
+
* full-array row indices. With no closed fold, `rows` and `decorations` pass
|
|
25
|
+
* through unchanged.
|
|
26
|
+
*/
|
|
27
|
+
export declare const useFoldState: <T>(rows: readonly T[], ranges: readonly FoldRange[], decorations: DecorationLayer[]) => FoldState<T>;
|
|
28
|
+
/** Fold operations. Row arguments are full-array row indices. */
|
|
29
|
+
export interface FoldActions {
|
|
30
|
+
/** Toggle the innermost fold that contains `row`. Returns false when no fold contains it. */
|
|
31
|
+
toggle: (row: number) => boolean;
|
|
32
|
+
/** Close the innermost open fold that contains `row`. Returns false when there is none. */
|
|
33
|
+
close: (row: number) => boolean;
|
|
34
|
+
/** Open the innermost closed fold that contains `row`. Returns false when there is none. */
|
|
35
|
+
open: (row: number) => boolean;
|
|
36
|
+
/** Open a fold at `row` when one is closed, else close the innermost open fold. */
|
|
37
|
+
toggleBlock: (row: number) => boolean;
|
|
38
|
+
closeAll: () => void;
|
|
39
|
+
openAll: () => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Fold operations over a fold state. Any change that hides the document
|
|
43
|
+
* cursor row first moves the cursor to the header of the outermost closed
|
|
44
|
+
* fold that hides it, and key preservation keeps it there. This holds for
|
|
45
|
+
* every target row, so a fold closed from the outline also keeps the cursor
|
|
46
|
+
* visible.
|
|
47
|
+
*/
|
|
48
|
+
export declare const useFoldActions: <T>(folds: FoldState<T>, navigation: Pick<NavigationState, "cursor" | "setCursor">) => FoldActions;
|
|
49
|
+
/**
|
|
50
|
+
* The Vim fold commands (`z a`, `z c`, `z o`, `z z`, `z shift+m`,
|
|
51
|
+
* `z shift+r`) as action definitions. The row commands act on `targetRow()`:
|
|
52
|
+
* the document cursor row on the root surface, or the selected heading in the
|
|
53
|
+
* outline. `idPrefix` keeps the ids apart on each surface, and `noFoldMessage`
|
|
54
|
+
* is the warning when no fold contains the target row.
|
|
55
|
+
*/
|
|
56
|
+
export declare const foldActionDefinitions: (actions: FoldActions, targetRow: () => number | undefined, idPrefix: string, noFoldMessage: string) => ActionDefinition[];
|
|
57
|
+
/** Register the fold commands on the current surface, acting on the document cursor row. */
|
|
58
|
+
export declare const useFoldCommands: <T>(folds: FoldState<T>, actions: FoldActions, navigation: Pick<NavigationState, "cursor">) => void;
|
|
59
|
+
//# sourceMappingURL=use-folds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-folds.d.ts","sourceRoot":"","sources":["../../src/folds/use-folds.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAkC,MAAM,iBAAiB,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAIjC,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAI3D,+EAA+E;AAC/E,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,qFAAqF;IACrF,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;IACnB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAChD,kEAAkE;IAClE,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,mGAAmG;IACnG,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAyB,CAAC,QAC3C,SAAS,CAAC,EAAE,UACV,SAAS,SAAS,EAAE,eACf,eAAe,EAAE,KAC7B,SAAS,CAAC,CAAC,CAqCb,CAAC;AAEF,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,6FAA6F;IAC7F,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,2FAA2F;IAC3F,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,4FAA4F;IAC5F,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/B,mFAAmF;IACnF,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAA2B,CAAC,SAC9C,SAAS,CAAC,CAAC,CAAC,cACP,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,WAAW,CAAC,KACxD,WAiDF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,YACvB,WAAW,aACT,MAAM,MAAM,GAAG,SAAS,YACzB,MAAM,iBACD,MAAM,KACpB,gBAAgB,EAyBlB,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,eAAe,GAA4B,CAAC,SAChD,SAAS,CAAC,CAAC,CAAC,WACV,WAAW,cACR,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,KAC1C,IAKF,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { useActions, useCommandGroup } from "@tooee/commands";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
import { projectDecorationLayers } from "./fold-decorations.js";
|
|
4
|
+
import { computeFoldView, foldsAt, visibleAnchorRow } from "./fold-model.js";
|
|
5
|
+
const EMPTY_KEYS = new Set();
|
|
6
|
+
/**
|
|
7
|
+
* Hold the closed fold keys for `rows` and project the rows, decorations and
|
|
8
|
+
* gutter numbers onto what stays visible. `ranges` and `decorations` use
|
|
9
|
+
* full-array row indices. With no closed fold, `rows` and `decorations` pass
|
|
10
|
+
* through unchanged.
|
|
11
|
+
*/
|
|
12
|
+
export const useFoldState = function useFoldState(rows, ranges, decorations) {
|
|
13
|
+
const [closedKeys, setClosedKeys] = useState(EMPTY_KEYS);
|
|
14
|
+
const view = useMemo(() => computeFoldView(rows.length, ranges, closedKeys), [rows.length, ranges, closedKeys]);
|
|
15
|
+
const folded = view.visibleToSource.length < rows.length;
|
|
16
|
+
const visibleRows = useMemo(() => folded
|
|
17
|
+
? view.visibleToSource.flatMap((index) => {
|
|
18
|
+
const row = rows[index];
|
|
19
|
+
return row === undefined ? [] : [row];
|
|
20
|
+
})
|
|
21
|
+
: rows, [folded, rows, view]);
|
|
22
|
+
const visibleDecorations = useMemo(() => (folded ? projectDecorationLayers(decorations, view) : decorations), [folded, decorations, view]);
|
|
23
|
+
const rowNumbers = useMemo(() => (folded ? view.visibleToSource.map((index) => index + 1) : undefined), [folded, view]);
|
|
24
|
+
return {
|
|
25
|
+
closedKeys,
|
|
26
|
+
decorations: visibleDecorations,
|
|
27
|
+
ranges,
|
|
28
|
+
rowCount: rows.length,
|
|
29
|
+
rowNumbers,
|
|
30
|
+
rows: visibleRows,
|
|
31
|
+
setClosedKeys,
|
|
32
|
+
view,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Fold operations over a fold state. Any change that hides the document
|
|
37
|
+
* cursor row first moves the cursor to the header of the outermost closed
|
|
38
|
+
* fold that hides it, and key preservation keeps it there. This holds for
|
|
39
|
+
* every target row, so a fold closed from the outline also keeps the cursor
|
|
40
|
+
* visible.
|
|
41
|
+
*/
|
|
42
|
+
export const useFoldActions = function useFoldActions(folds, navigation) {
|
|
43
|
+
const { closedKeys, ranges, rowCount, setClosedKeys, view } = folds;
|
|
44
|
+
const { cursor, setCursor } = navigation;
|
|
45
|
+
const cursorRow = cursor === null ? undefined : view.visibleToSource[cursor];
|
|
46
|
+
const apply = (next) => {
|
|
47
|
+
if (cursorRow !== undefined) {
|
|
48
|
+
const anchor = visibleAnchorRow(computeFoldView(rowCount, ranges, next), cursorRow);
|
|
49
|
+
const anchorIndex = view.sourceToVisible[anchor] ?? -1;
|
|
50
|
+
if (anchor !== cursorRow && anchorIndex !== -1) {
|
|
51
|
+
setCursor(anchorIndex);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
setClosedKeys(next);
|
|
55
|
+
};
|
|
56
|
+
const withKey = (key, closed) => {
|
|
57
|
+
if (key === undefined) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const next = new Set(closedKeys);
|
|
61
|
+
if (closed) {
|
|
62
|
+
next.add(key);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
next.delete(key);
|
|
66
|
+
}
|
|
67
|
+
apply(next);
|
|
68
|
+
return true;
|
|
69
|
+
};
|
|
70
|
+
const close = (row) => withKey(foldsAt(ranges, row).find((range) => !closedKeys.has(range.key))?.key, true);
|
|
71
|
+
const open = (row) => withKey(foldsAt(ranges, row).find((range) => closedKeys.has(range.key))?.key, false);
|
|
72
|
+
return {
|
|
73
|
+
close,
|
|
74
|
+
closeAll: () => {
|
|
75
|
+
apply(new Set(ranges.map((range) => range.key)));
|
|
76
|
+
},
|
|
77
|
+
open,
|
|
78
|
+
openAll: () => {
|
|
79
|
+
apply(EMPTY_KEYS);
|
|
80
|
+
},
|
|
81
|
+
toggle: (row) => {
|
|
82
|
+
const [innermost] = foldsAt(ranges, row);
|
|
83
|
+
return withKey(innermost?.key, innermost !== undefined && !closedKeys.has(innermost.key));
|
|
84
|
+
},
|
|
85
|
+
toggleBlock: (row) => foldsAt(ranges, row).some((range) => closedKeys.has(range.key)) ? open(row) : close(row),
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* The Vim fold commands (`z a`, `z c`, `z o`, `z z`, `z shift+m`,
|
|
90
|
+
* `z shift+r`) as action definitions. The row commands act on `targetRow()`:
|
|
91
|
+
* the document cursor row on the root surface, or the selected heading in the
|
|
92
|
+
* outline. `idPrefix` keeps the ids apart on each surface, and `noFoldMessage`
|
|
93
|
+
* is the warning when no fold contains the target row.
|
|
94
|
+
*/
|
|
95
|
+
export const foldActionDefinitions = function foldActionDefinitions(actions, targetRow, idPrefix, noFoldMessage) {
|
|
96
|
+
const atTarget = (run) => (ctx) => {
|
|
97
|
+
const row = targetRow();
|
|
98
|
+
if (row === undefined || !run(row)) {
|
|
99
|
+
ctx.toast?.toast({ level: "warning", message: noFoldMessage });
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const definitions = [
|
|
103
|
+
["z a", "toggle", "Toggle fold", atTarget(actions.toggle)],
|
|
104
|
+
["z c", "close", "Close fold", atTarget(actions.close)],
|
|
105
|
+
["z o", "open", "Open fold", atTarget(actions.open)],
|
|
106
|
+
["z z", "toggle-block", "Open or close fold", atTarget(actions.toggleBlock)],
|
|
107
|
+
["z shift+m", "close-all", "Close all folds", actions.closeAll],
|
|
108
|
+
["z shift+r", "open-all", "Open all folds", actions.openAll],
|
|
109
|
+
];
|
|
110
|
+
return definitions.map(([hotkey, id, title, handler]) => ({
|
|
111
|
+
category: "Fold",
|
|
112
|
+
handler,
|
|
113
|
+
hotkey,
|
|
114
|
+
id: `${idPrefix}.${id}`,
|
|
115
|
+
modes: ["cursor"],
|
|
116
|
+
title,
|
|
117
|
+
}));
|
|
118
|
+
};
|
|
119
|
+
/** Register the fold commands on the current surface, acting on the document cursor row. */
|
|
120
|
+
export const useFoldCommands = function useFoldCommands(folds, actions, navigation) {
|
|
121
|
+
const { cursor } = navigation;
|
|
122
|
+
const cursorRow = cursor === null ? undefined : folds.view.visibleToSource[cursor];
|
|
123
|
+
useCommandGroup({ id: "fold", prefix: "z", title: "Fold" });
|
|
124
|
+
useActions(foldActionDefinitions(actions, () => cursorRow, "fold", "No fold at cursor"));
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=use-folds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-folds.js","sourceRoot":"","sources":["../../src/folds/use-folds.ts"],"names":[],"mappings":"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"}
|
package/dist/launch.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface ViewLaunchOptions {
|
|
|
16
16
|
* Unmatched types fall back to the default syntax-highlighted code block.
|
|
17
17
|
*/
|
|
18
18
|
codeBlockRenderers?: Record<string, CodeBlockRenderer>;
|
|
19
|
+
/** Open the heading outline beside Markdown content at start. */
|
|
20
|
+
outline?: boolean;
|
|
19
21
|
}
|
|
20
22
|
export interface DirectoryLaunchOptions {
|
|
21
23
|
dirPath: string;
|
package/dist/launch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../src/launch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAM1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,eAAe,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../src/launch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAM1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,eAAe,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACvD,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED,eAAO,MAAM,MAAM,YAAkC,iBAAiB,KAAG,OAAO,CAAC,IAAI,CAiBpF,CAAC;AAEF,eAAO,MAAM,eAAe,YACjB,sBAAsB,KAC9B,OAAO,CAAC,IAAI,CAId,CAAC"}
|