@m4ike1/ion-tui 0.1.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 +114 -0
- package/dist/alt-screen-search.d.ts +46 -0
- package/dist/alt-screen-search.d.ts.map +1 -0
- package/dist/alt-screen-search.js +282 -0
- package/dist/alt-screen-search.js.map +1 -0
- package/dist/autocomplete.d.ts +75 -0
- package/dist/autocomplete.d.ts.map +1 -0
- package/dist/autocomplete.js +749 -0
- package/dist/autocomplete.js.map +1 -0
- package/dist/components/alt-screen-flash.d.ts +13 -0
- package/dist/components/alt-screen-flash.d.ts.map +1 -0
- package/dist/components/alt-screen-flash.js +37 -0
- package/dist/components/alt-screen-flash.js.map +1 -0
- package/dist/components/box.d.ts +24 -0
- package/dist/components/box.d.ts.map +1 -0
- package/dist/components/box.js +133 -0
- package/dist/components/box.js.map +1 -0
- package/dist/components/cancellable-loader.d.ts +22 -0
- package/dist/components/cancellable-loader.d.ts.map +1 -0
- package/dist/components/cancellable-loader.js +35 -0
- package/dist/components/cancellable-loader.js.map +1 -0
- package/dist/components/editor.d.ts +266 -0
- package/dist/components/editor.d.ts.map +1 -0
- package/dist/components/editor.js +2087 -0
- package/dist/components/editor.js.map +1 -0
- package/dist/components/h-stack.d.ts +7 -0
- package/dist/components/h-stack.d.ts.map +1 -0
- package/dist/components/h-stack.js +43 -0
- package/dist/components/h-stack.js.map +1 -0
- package/dist/components/image.d.ts +28 -0
- package/dist/components/image.d.ts.map +1 -0
- package/dist/components/image.js +90 -0
- package/dist/components/image.js.map +1 -0
- package/dist/components/input.d.ts +48 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/components/input.js +417 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/loader.d.ts +33 -0
- package/dist/components/loader.d.ts.map +1 -0
- package/dist/components/loader.js +76 -0
- package/dist/components/loader.js.map +1 -0
- package/dist/components/markdown.d.ts +103 -0
- package/dist/components/markdown.d.ts.map +1 -0
- package/dist/components/markdown.js +858 -0
- package/dist/components/markdown.js.map +1 -0
- package/dist/components/mouse-region.d.ts +12 -0
- package/dist/components/mouse-region.d.ts.map +1 -0
- package/dist/components/mouse-region.js +21 -0
- package/dist/components/mouse-region.js.map +1 -0
- package/dist/components/scroll-view.d.ts +68 -0
- package/dist/components/scroll-view.d.ts.map +1 -0
- package/dist/components/scroll-view.js +199 -0
- package/dist/components/scroll-view.js.map +1 -0
- package/dist/components/select-list.d.ts +53 -0
- package/dist/components/select-list.d.ts.map +1 -0
- package/dist/components/select-list.js +206 -0
- package/dist/components/select-list.js.map +1 -0
- package/dist/components/settings-list.d.ts +60 -0
- package/dist/components/settings-list.d.ts.map +1 -0
- package/dist/components/settings-list.js +252 -0
- package/dist/components/settings-list.js.map +1 -0
- package/dist/components/spacer.d.ts +12 -0
- package/dist/components/spacer.d.ts.map +1 -0
- package/dist/components/spacer.js +23 -0
- package/dist/components/spacer.js.map +1 -0
- package/dist/components/stack.d.ts +32 -0
- package/dist/components/stack.d.ts.map +1 -0
- package/dist/components/stack.js +111 -0
- package/dist/components/stack.js.map +1 -0
- package/dist/components/text.d.ts +19 -0
- package/dist/components/text.d.ts.map +1 -0
- package/dist/components/text.js +90 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/truncated-text.d.ts +13 -0
- package/dist/components/truncated-text.d.ts.map +1 -0
- package/dist/components/truncated-text.js +51 -0
- package/dist/components/truncated-text.js.map +1 -0
- package/dist/components/v-stack.d.ts +8 -0
- package/dist/components/v-stack.d.ts.map +1 -0
- package/dist/components/v-stack.js +26 -0
- package/dist/components/v-stack.js.map +1 -0
- package/dist/components/virtual-list.d.ts +51 -0
- package/dist/components/virtual-list.d.ts.map +1 -0
- package/dist/components/virtual-list.js +170 -0
- package/dist/components/virtual-list.js.map +1 -0
- package/dist/editor-component.d.ts +39 -0
- package/dist/editor-component.d.ts.map +1 -0
- package/dist/editor-component.js +2 -0
- package/dist/editor-component.js.map +1 -0
- package/dist/fuzzy.d.ts +16 -0
- package/dist/fuzzy.d.ts.map +1 -0
- package/dist/fuzzy.js +110 -0
- package/dist/fuzzy.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/keybindings.d.ts +366 -0
- package/dist/keybindings.d.ts.map +1 -0
- package/dist/keybindings.js +331 -0
- package/dist/keybindings.js.map +1 -0
- package/dist/keys.d.ts +184 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +1174 -0
- package/dist/keys.js.map +1 -0
- package/dist/kill-ring.d.ts +28 -0
- package/dist/kill-ring.d.ts.map +1 -0
- package/dist/kill-ring.js +44 -0
- package/dist/kill-ring.js.map +1 -0
- package/dist/latex.d.ts +10 -0
- package/dist/latex.d.ts.map +1 -0
- package/dist/latex.js +1285 -0
- package/dist/latex.js.map +1 -0
- package/dist/layout-node.d.ts +59 -0
- package/dist/layout-node.d.ts.map +1 -0
- package/dist/layout-node.js +12 -0
- package/dist/layout-node.js.map +1 -0
- package/dist/layout.d.ts +42 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +404 -0
- package/dist/layout.js.map +1 -0
- package/dist/native-modifiers.d.ts +4 -0
- package/dist/native-modifiers.d.ts.map +1 -0
- package/dist/native-modifiers.js +13 -0
- package/dist/native-modifiers.js.map +1 -0
- package/dist/native-module-path.d.ts +7 -0
- package/dist/native-module-path.d.ts.map +1 -0
- package/dist/native-module-path.js +19 -0
- package/dist/native-module-path.js.map +1 -0
- package/dist/native-platform.d.ts +18 -0
- package/dist/native-platform.d.ts.map +1 -0
- package/dist/native-platform.js +42 -0
- package/dist/native-platform.js.map +1 -0
- package/dist/pty-host.d.ts +224 -0
- package/dist/pty-host.d.ts.map +1 -0
- package/dist/pty-host.js +347 -0
- package/dist/pty-host.js.map +1 -0
- package/dist/stdin-buffer.d.ts +56 -0
- package/dist/stdin-buffer.d.ts.map +1 -0
- package/dist/stdin-buffer.js +366 -0
- package/dist/stdin-buffer.js.map +1 -0
- package/dist/terminal-colors.d.ts +10 -0
- package/dist/terminal-colors.d.ts.map +1 -0
- package/dist/terminal-colors.js +59 -0
- package/dist/terminal-colors.js.map +1 -0
- package/dist/terminal-image.d.ts +118 -0
- package/dist/terminal-image.d.ts.map +1 -0
- package/dist/terminal-image.js +550 -0
- package/dist/terminal-image.js.map +1 -0
- package/dist/terminal.d.ts +123 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +442 -0
- package/dist/terminal.js.map +1 -0
- package/dist/tui-alt-screen.d.ts +165 -0
- package/dist/tui-alt-screen.d.ts.map +1 -0
- package/dist/tui-alt-screen.js +1515 -0
- package/dist/tui-alt-screen.js.map +1 -0
- package/dist/tui-main-screen.d.ts +39 -0
- package/dist/tui-main-screen.d.ts.map +1 -0
- package/dist/tui-main-screen.js +594 -0
- package/dist/tui-main-screen.js.map +1 -0
- package/dist/tui.d.ts +431 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +1142 -0
- package/dist/tui.js.map +1 -0
- package/dist/undo-stack.d.ts +17 -0
- package/dist/undo-stack.d.ts.map +1 -0
- package/dist/undo-stack.js +25 -0
- package/dist/undo-stack.js.map +1 -0
- package/dist/utils.d.ts +98 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +1200 -0
- package/dist/utils.js.map +1 -0
- package/dist/word-navigation.d.ts +25 -0
- package/dist/word-navigation.d.ts.map +1 -0
- package/dist/word-navigation.js +96 -0
- package/dist/word-navigation.js.map +1 -0
- package/native/clipboard.h +170 -0
- package/native/darwin/README.md +22 -0
- package/native/darwin/build.sh +69 -0
- package/native/darwin/prebuilds/darwin-arm64/darwin-platform.node +0 -0
- package/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
- package/native/darwin/src/darwin-platform.m +93 -0
- package/native/linux/README.md +23 -0
- package/native/linux/build.sh +65 -0
- package/native/linux/prebuilds/linux-arm64/linux-platform-x11.node +0 -0
- package/native/linux/prebuilds/linux-x64/linux-platform-x11.node +0 -0
- package/native/linux/src/clipboard-worker.h +70 -0
- package/native/linux/src/linux-platform-x11.c +274 -0
- package/native/napi.h +89 -0
- package/native/win32/README.md +31 -0
- package/native/win32/build.mjs +232 -0
- package/native/win32/prebuilds/win32-arm64/win32-platform.node +0 -0
- package/native/win32/prebuilds/win32-x64/win32-platform.node +0 -0
- package/native/win32/src/win32-platform.c +241 -0
- package/package.json +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-list.d.ts","sourceRoot":"","sources":["../../src/components/virtual-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAc/E;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAY,YAAW,SAAS,EAAE,kBAAkB;IAChE,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,OAAO,CAAgD;IAC/D,OAAO,CAAC,QAAQ,CAAkC;IAElD,YAAY,KAAK,GAAE,SAAS,SAAS,EAAO,EAM3C;IAED,YAAY,IAAI,MAAM,CAErB;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAIhC;IAED,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIpC;IAED,2CAA2C;IAC3C,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAMvC;IAED,oEAAoE;IACpE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAIjD;IAED;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGrC;IAED,KAAK,IAAI,IAAI,CAKZ;IAED,OAAO,CAAC,QAAQ;IAMhB,0EAA0E;IAC1E,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAUjD;IAED,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOpC;IAED,8DAA8D;IAC9D,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvC;IAED,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlE;IAED,0EAA0E;IAC1E,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWpD;IAED,OAAO,CAAC,cAAc;IAetB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9B;IAED,UAAU,IAAI,IAAI,CAIjB;IAED,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS,CAEjE;IAED,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS,CAe3F;CACD","sourcesContent":["import type { VirtualizedContent } from \"../layout-node.ts\";\nimport type { Component, TuiMouseEvent, TuiMouseEventResult } from \"../tui.ts\";\n\ninterface VirtualListCacheEntry {\n\twidth: number;\n\tversion: number;\n\tlines: string[];\n}\n\ninterface VirtualListAssembly {\n\twidth: number;\n\tlines: string[];\n\toffsets: number[];\n}\n\n/**\n * Windowed transcript list with a versioned per-message render cache.\n *\n * Each item renders independently and its output is cached by (width,\n * version). Mutating a message in place never invalidates its siblings: hosts\n * bump exactly one slot via notifyItemChanged/setItem, so streaming appends\n * re-render only the appending message.\n *\n * For viewport-budgeted paint this list must be the direct child of a\n * ScrollView. The layout then paints only the visible rows plus the scroll\n * view overscan (O(viewport) per frame after a one-time O(session) measure),\n * while search and selection keep operating on the full per-message model.\n * In any other position render() assembles all cached rows, like Container.\n */\nexport class VirtualList implements Component, VirtualizedContent {\n\tprivate items: Component[] = [];\n\tprivate versions: number[] = [];\n\tprivate entries: Array<VirtualListCacheEntry | undefined> = [];\n\tprivate assembly: VirtualListAssembly | undefined;\n\n\tconstructor(items: readonly Component[] = []) {\n\t\tfor (const item of items) {\n\t\t\tthis.items.push(item);\n\t\t\tthis.versions.push(0);\n\t\t\tthis.entries.push(undefined);\n\t\t}\n\t}\n\n\tgetItemCount(): number {\n\t\treturn this.items.length;\n\t}\n\n\tgetItem(index: number): Component {\n\t\tconst item = this.items[index];\n\t\tif (item === undefined) throw new Error(`VirtualList item index out of range: ${index}`);\n\t\treturn item;\n\t}\n\n\tgetItemVersion(index: number): number {\n\t\tconst version = this.versions[index];\n\t\tif (version === undefined) throw new Error(`VirtualList item index out of range: ${index}`);\n\t\treturn version;\n\t}\n\n\t/** Append a message; returns its index. */\n\tappendItem(component: Component): number {\n\t\tthis.items.push(component);\n\t\tthis.versions.push(0);\n\t\tthis.entries.push(undefined);\n\t\tthis.assembly = undefined;\n\t\treturn this.items.length - 1;\n\t}\n\n\t/** Replace the message at `index` and invalidate only that slot. */\n\tsetItem(index: number, component: Component): void {\n\t\tthis.getItem(index);\n\t\tthis.items[index] = component;\n\t\tthis.bumpItem(index);\n\t}\n\n\t/**\n\t * Invalidate only the message at `index` after an in-place mutation\n\t * (e.g. Markdown.setText during streaming). Siblings reuse their caches.\n\t */\n\tnotifyItemChanged(index: number): void {\n\t\tthis.getItem(index);\n\t\tthis.bumpItem(index);\n\t}\n\n\tclear(): void {\n\t\tthis.items = [];\n\t\tthis.versions = [];\n\t\tthis.entries = [];\n\t\tthis.assembly = undefined;\n\t}\n\n\tprivate bumpItem(index: number): void {\n\t\tthis.versions[index] = (this.versions[index] ?? 0) + 1;\n\t\tthis.entries[index] = undefined;\n\t\tthis.assembly = undefined;\n\t}\n\n\t/** Render one message, reusing its cache when width and version match. */\n\trenderItem(index: number, width: number): string[] {\n\t\tconst item = this.getItem(index);\n\t\tconst version = this.versions[index] ?? 0;\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tconst cached = this.entries[index];\n\t\tif (cached && cached.width === safeWidth && cached.version === version) return cached.lines;\n\t\tconst lines = item.render(safeWidth);\n\t\tthis.entries[index] = { width: safeWidth, version, lines };\n\t\tthis.assembly = undefined;\n\t\treturn lines;\n\t}\n\n\tgetTotalHeight(width: number): number {\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tlet total = 0;\n\t\tfor (let index = 0; index < this.items.length; index++) {\n\t\t\ttotal += this.renderItem(index, safeWidth).length;\n\t\t}\n\t\treturn total;\n\t}\n\n\t/** All content rows assembled from the per-message caches. */\n\tgetContentLines(width: number): string[] {\n\t\treturn this.ensureAssembly(Math.max(1, Math.floor(width))).lines;\n\t}\n\n\tgetWindowLines(width: number, start: number, end: number): string[] {\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tconst lines = this.ensureAssembly(safeWidth).lines;\n\t\tconst from = Math.max(0, Math.min(lines.length, Math.floor(start)));\n\t\tconst to = Math.max(from, Math.min(lines.length, Math.ceil(end)));\n\t\treturn lines.slice(from, to);\n\t}\n\n\t/** Index of the message owning content `row`, or -1 when out of range. */\n\tgetItemIndexAtRow(row: number, width: number): number {\n\t\tconst assembly = this.ensureAssembly(Math.max(1, Math.floor(width)));\n\t\tif (row < 0 || row >= assembly.lines.length || assembly.offsets.length === 0) return -1;\n\t\tlet low = 0;\n\t\tlet high = assembly.offsets.length - 1;\n\t\twhile (low < high) {\n\t\t\tconst middle = low + Math.floor((high - low + 1) / 2);\n\t\t\tif ((assembly.offsets[middle] ?? 0) <= row) low = middle;\n\t\t\telse high = middle - 1;\n\t\t}\n\t\treturn low;\n\t}\n\n\tprivate ensureAssembly(width: number): VirtualListAssembly {\n\t\tconst cached = this.assembly;\n\t\tif (cached && cached.width === width) return cached;\n\t\tconst lines: string[] = [];\n\t\tconst offsets: number[] = [];\n\t\tfor (let index = 0; index < this.items.length; index++) {\n\t\t\toffsets.push(lines.length);\n\t\t\tconst itemLines = this.renderItem(index, width);\n\t\t\tfor (const line of itemLines) lines.push(line);\n\t\t}\n\t\tconst assembly = { width, lines, offsets };\n\t\tthis.assembly = assembly;\n\t\treturn assembly;\n\t}\n\n\trender(width: number): string[] {\n\t\treturn this.getContentLines(width);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.entries = this.items.map(() => undefined);\n\t\tthis.assembly = undefined;\n\t\tfor (const item of this.items) item.invalidate?.();\n\t}\n\n\thandleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\treturn this.handleWindowMouseEvent(0, event);\n\t}\n\n\thandleWindowMouseEvent(start: number, event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\tconst safeWidth = Math.max(1, Math.floor(event.width));\n\t\tconst row = Math.floor(start) + event.y;\n\t\tconst index = this.getItemIndexAtRow(row, safeWidth);\n\t\tif (index < 0) return undefined;\n\t\tconst item = this.items[index];\n\t\tif (typeof item?.handleMouse !== \"function\") return undefined;\n\t\tconst assembly = this.ensureAssembly(safeWidth);\n\t\tconst itemTop = assembly.offsets[index] ?? 0;\n\t\tconst nextTop = index + 1 < assembly.offsets.length ? (assembly.offsets[index + 1] ?? 0) : assembly.lines.length;\n\t\treturn item.handleMouse({\n\t\t\t...event,\n\t\t\ty: row - itemTop,\n\t\t\theight: Math.max(0, nextTop - itemTop),\n\t\t});\n\t}\n}\n"]}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windowed transcript list with a versioned per-message render cache.
|
|
3
|
+
*
|
|
4
|
+
* Each item renders independently and its output is cached by (width,
|
|
5
|
+
* version). Mutating a message in place never invalidates its siblings: hosts
|
|
6
|
+
* bump exactly one slot via notifyItemChanged/setItem, so streaming appends
|
|
7
|
+
* re-render only the appending message.
|
|
8
|
+
*
|
|
9
|
+
* For viewport-budgeted paint this list must be the direct child of a
|
|
10
|
+
* ScrollView. The layout then paints only the visible rows plus the scroll
|
|
11
|
+
* view overscan (O(viewport) per frame after a one-time O(session) measure),
|
|
12
|
+
* while search and selection keep operating on the full per-message model.
|
|
13
|
+
* In any other position render() assembles all cached rows, like Container.
|
|
14
|
+
*/
|
|
15
|
+
export class VirtualList {
|
|
16
|
+
items = [];
|
|
17
|
+
versions = [];
|
|
18
|
+
entries = [];
|
|
19
|
+
assembly;
|
|
20
|
+
constructor(items = []) {
|
|
21
|
+
for (const item of items) {
|
|
22
|
+
this.items.push(item);
|
|
23
|
+
this.versions.push(0);
|
|
24
|
+
this.entries.push(undefined);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
getItemCount() {
|
|
28
|
+
return this.items.length;
|
|
29
|
+
}
|
|
30
|
+
getItem(index) {
|
|
31
|
+
const item = this.items[index];
|
|
32
|
+
if (item === undefined)
|
|
33
|
+
throw new Error(`VirtualList item index out of range: ${index}`);
|
|
34
|
+
return item;
|
|
35
|
+
}
|
|
36
|
+
getItemVersion(index) {
|
|
37
|
+
const version = this.versions[index];
|
|
38
|
+
if (version === undefined)
|
|
39
|
+
throw new Error(`VirtualList item index out of range: ${index}`);
|
|
40
|
+
return version;
|
|
41
|
+
}
|
|
42
|
+
/** Append a message; returns its index. */
|
|
43
|
+
appendItem(component) {
|
|
44
|
+
this.items.push(component);
|
|
45
|
+
this.versions.push(0);
|
|
46
|
+
this.entries.push(undefined);
|
|
47
|
+
this.assembly = undefined;
|
|
48
|
+
return this.items.length - 1;
|
|
49
|
+
}
|
|
50
|
+
/** Replace the message at `index` and invalidate only that slot. */
|
|
51
|
+
setItem(index, component) {
|
|
52
|
+
this.getItem(index);
|
|
53
|
+
this.items[index] = component;
|
|
54
|
+
this.bumpItem(index);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Invalidate only the message at `index` after an in-place mutation
|
|
58
|
+
* (e.g. Markdown.setText during streaming). Siblings reuse their caches.
|
|
59
|
+
*/
|
|
60
|
+
notifyItemChanged(index) {
|
|
61
|
+
this.getItem(index);
|
|
62
|
+
this.bumpItem(index);
|
|
63
|
+
}
|
|
64
|
+
clear() {
|
|
65
|
+
this.items = [];
|
|
66
|
+
this.versions = [];
|
|
67
|
+
this.entries = [];
|
|
68
|
+
this.assembly = undefined;
|
|
69
|
+
}
|
|
70
|
+
bumpItem(index) {
|
|
71
|
+
this.versions[index] = (this.versions[index] ?? 0) + 1;
|
|
72
|
+
this.entries[index] = undefined;
|
|
73
|
+
this.assembly = undefined;
|
|
74
|
+
}
|
|
75
|
+
/** Render one message, reusing its cache when width and version match. */
|
|
76
|
+
renderItem(index, width) {
|
|
77
|
+
const item = this.getItem(index);
|
|
78
|
+
const version = this.versions[index] ?? 0;
|
|
79
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
80
|
+
const cached = this.entries[index];
|
|
81
|
+
if (cached && cached.width === safeWidth && cached.version === version)
|
|
82
|
+
return cached.lines;
|
|
83
|
+
const lines = item.render(safeWidth);
|
|
84
|
+
this.entries[index] = { width: safeWidth, version, lines };
|
|
85
|
+
this.assembly = undefined;
|
|
86
|
+
return lines;
|
|
87
|
+
}
|
|
88
|
+
getTotalHeight(width) {
|
|
89
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
90
|
+
let total = 0;
|
|
91
|
+
for (let index = 0; index < this.items.length; index++) {
|
|
92
|
+
total += this.renderItem(index, safeWidth).length;
|
|
93
|
+
}
|
|
94
|
+
return total;
|
|
95
|
+
}
|
|
96
|
+
/** All content rows assembled from the per-message caches. */
|
|
97
|
+
getContentLines(width) {
|
|
98
|
+
return this.ensureAssembly(Math.max(1, Math.floor(width))).lines;
|
|
99
|
+
}
|
|
100
|
+
getWindowLines(width, start, end) {
|
|
101
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
102
|
+
const lines = this.ensureAssembly(safeWidth).lines;
|
|
103
|
+
const from = Math.max(0, Math.min(lines.length, Math.floor(start)));
|
|
104
|
+
const to = Math.max(from, Math.min(lines.length, Math.ceil(end)));
|
|
105
|
+
return lines.slice(from, to);
|
|
106
|
+
}
|
|
107
|
+
/** Index of the message owning content `row`, or -1 when out of range. */
|
|
108
|
+
getItemIndexAtRow(row, width) {
|
|
109
|
+
const assembly = this.ensureAssembly(Math.max(1, Math.floor(width)));
|
|
110
|
+
if (row < 0 || row >= assembly.lines.length || assembly.offsets.length === 0)
|
|
111
|
+
return -1;
|
|
112
|
+
let low = 0;
|
|
113
|
+
let high = assembly.offsets.length - 1;
|
|
114
|
+
while (low < high) {
|
|
115
|
+
const middle = low + Math.floor((high - low + 1) / 2);
|
|
116
|
+
if ((assembly.offsets[middle] ?? 0) <= row)
|
|
117
|
+
low = middle;
|
|
118
|
+
else
|
|
119
|
+
high = middle - 1;
|
|
120
|
+
}
|
|
121
|
+
return low;
|
|
122
|
+
}
|
|
123
|
+
ensureAssembly(width) {
|
|
124
|
+
const cached = this.assembly;
|
|
125
|
+
if (cached && cached.width === width)
|
|
126
|
+
return cached;
|
|
127
|
+
const lines = [];
|
|
128
|
+
const offsets = [];
|
|
129
|
+
for (let index = 0; index < this.items.length; index++) {
|
|
130
|
+
offsets.push(lines.length);
|
|
131
|
+
const itemLines = this.renderItem(index, width);
|
|
132
|
+
for (const line of itemLines)
|
|
133
|
+
lines.push(line);
|
|
134
|
+
}
|
|
135
|
+
const assembly = { width, lines, offsets };
|
|
136
|
+
this.assembly = assembly;
|
|
137
|
+
return assembly;
|
|
138
|
+
}
|
|
139
|
+
render(width) {
|
|
140
|
+
return this.getContentLines(width);
|
|
141
|
+
}
|
|
142
|
+
invalidate() {
|
|
143
|
+
this.entries = this.items.map(() => undefined);
|
|
144
|
+
this.assembly = undefined;
|
|
145
|
+
for (const item of this.items)
|
|
146
|
+
item.invalidate?.();
|
|
147
|
+
}
|
|
148
|
+
handleMouse(event) {
|
|
149
|
+
return this.handleWindowMouseEvent(0, event);
|
|
150
|
+
}
|
|
151
|
+
handleWindowMouseEvent(start, event) {
|
|
152
|
+
const safeWidth = Math.max(1, Math.floor(event.width));
|
|
153
|
+
const row = Math.floor(start) + event.y;
|
|
154
|
+
const index = this.getItemIndexAtRow(row, safeWidth);
|
|
155
|
+
if (index < 0)
|
|
156
|
+
return undefined;
|
|
157
|
+
const item = this.items[index];
|
|
158
|
+
if (typeof item?.handleMouse !== "function")
|
|
159
|
+
return undefined;
|
|
160
|
+
const assembly = this.ensureAssembly(safeWidth);
|
|
161
|
+
const itemTop = assembly.offsets[index] ?? 0;
|
|
162
|
+
const nextTop = index + 1 < assembly.offsets.length ? (assembly.offsets[index + 1] ?? 0) : assembly.lines.length;
|
|
163
|
+
return item.handleMouse({
|
|
164
|
+
...event,
|
|
165
|
+
y: row - itemTop,
|
|
166
|
+
height: Math.max(0, nextTop - itemTop),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=virtual-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-list.js","sourceRoot":"","sources":["../../src/components/virtual-list.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,WAAW;IACf,KAAK,GAAgB,EAAE,CAAC;IACxB,QAAQ,GAAa,EAAE,CAAC;IACxB,OAAO,GAA6C,EAAE,CAAC;IACvD,QAAQ,CAAkC;IAElD,YAAY,KAAK,GAAyB,EAAE,EAAE;QAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,CAAC;IAAA,CACD;IAED,YAAY,GAAW;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAAA,CACzB;IAED,OAAO,CAAC,KAAa,EAAa;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,KAAK,EAAE,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC;IAAA,CACZ;IAED,cAAc,CAAC,KAAa,EAAU;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,KAAK,EAAE,CAAC,CAAC;QAC5F,OAAO,OAAO,CAAC;IAAA,CACf;IAED,2CAA2C;IAC3C,UAAU,CAAC,SAAoB,EAAU;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAAA,CAC7B;IAED,oEAAoE;IACpE,OAAO,CAAC,KAAa,EAAE,SAAoB,EAAQ;QAClD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAAA,CACrB;IAED;;;OAGG;IACH,iBAAiB,CAAC,KAAa,EAAQ;QACtC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAAA,CACrB;IAED,KAAK,GAAS;QACb,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAAA,CAC1B;IAEO,QAAQ,CAAC,KAAa,EAAQ;QACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAAA,CAC1B;IAED,0EAA0E;IAC1E,UAAU,CAAC,KAAa,EAAE,KAAa,EAAY;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC3D,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,OAAO,KAAK,CAAC;IAAA,CACb;IAED,cAAc,CAAC,KAAa,EAAU;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACxD,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC;QACnD,CAAC;QACD,OAAO,KAAK,CAAC;IAAA,CACb;IAED,8DAA8D;IAC9D,eAAe,CAAC,KAAa,EAAY;QACxC,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAAA,CACjE;IAED,cAAc,CAAC,KAAa,EAAE,KAAa,EAAE,GAAW,EAAY;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClE,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAAA,CAC7B;IAED,0EAA0E;IAC1E,iBAAiB,CAAC,GAAW,EAAE,KAAa,EAAU;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrE,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC;QACxF,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACvC,OAAO,GAAG,GAAG,IAAI,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACtD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG;gBAAE,GAAG,GAAG,MAAM,CAAC;;gBACpD,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,CAAC;IAAA,CACX;IAEO,cAAc,CAAC,KAAa,EAAuB;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK;YAAE,OAAO,MAAM,CAAC;QACpD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChD,KAAK,MAAM,IAAI,IAAI,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,OAAO,QAAQ,CAAC;IAAA,CAChB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAAA,CACnC;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;IAAA,CACnD;IAED,WAAW,CAAC,KAAoB,EAAmC;QAClE,OAAO,IAAI,CAAC,sBAAsB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAAA,CAC7C;IAED,sBAAsB,CAAC,KAAa,EAAE,KAAoB,EAAmC;QAC5F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrD,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,OAAO,IAAI,EAAE,WAAW,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;QACjH,OAAO,IAAI,CAAC,WAAW,CAAC;YACvB,GAAG,KAAK;YACR,CAAC,EAAE,GAAG,GAAG,OAAO;YAChB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;SACtC,CAAC,CAAC;IAAA,CACH;CACD","sourcesContent":["import type { VirtualizedContent } from \"../layout-node.ts\";\nimport type { Component, TuiMouseEvent, TuiMouseEventResult } from \"../tui.ts\";\n\ninterface VirtualListCacheEntry {\n\twidth: number;\n\tversion: number;\n\tlines: string[];\n}\n\ninterface VirtualListAssembly {\n\twidth: number;\n\tlines: string[];\n\toffsets: number[];\n}\n\n/**\n * Windowed transcript list with a versioned per-message render cache.\n *\n * Each item renders independently and its output is cached by (width,\n * version). Mutating a message in place never invalidates its siblings: hosts\n * bump exactly one slot via notifyItemChanged/setItem, so streaming appends\n * re-render only the appending message.\n *\n * For viewport-budgeted paint this list must be the direct child of a\n * ScrollView. The layout then paints only the visible rows plus the scroll\n * view overscan (O(viewport) per frame after a one-time O(session) measure),\n * while search and selection keep operating on the full per-message model.\n * In any other position render() assembles all cached rows, like Container.\n */\nexport class VirtualList implements Component, VirtualizedContent {\n\tprivate items: Component[] = [];\n\tprivate versions: number[] = [];\n\tprivate entries: Array<VirtualListCacheEntry | undefined> = [];\n\tprivate assembly: VirtualListAssembly | undefined;\n\n\tconstructor(items: readonly Component[] = []) {\n\t\tfor (const item of items) {\n\t\t\tthis.items.push(item);\n\t\t\tthis.versions.push(0);\n\t\t\tthis.entries.push(undefined);\n\t\t}\n\t}\n\n\tgetItemCount(): number {\n\t\treturn this.items.length;\n\t}\n\n\tgetItem(index: number): Component {\n\t\tconst item = this.items[index];\n\t\tif (item === undefined) throw new Error(`VirtualList item index out of range: ${index}`);\n\t\treturn item;\n\t}\n\n\tgetItemVersion(index: number): number {\n\t\tconst version = this.versions[index];\n\t\tif (version === undefined) throw new Error(`VirtualList item index out of range: ${index}`);\n\t\treturn version;\n\t}\n\n\t/** Append a message; returns its index. */\n\tappendItem(component: Component): number {\n\t\tthis.items.push(component);\n\t\tthis.versions.push(0);\n\t\tthis.entries.push(undefined);\n\t\tthis.assembly = undefined;\n\t\treturn this.items.length - 1;\n\t}\n\n\t/** Replace the message at `index` and invalidate only that slot. */\n\tsetItem(index: number, component: Component): void {\n\t\tthis.getItem(index);\n\t\tthis.items[index] = component;\n\t\tthis.bumpItem(index);\n\t}\n\n\t/**\n\t * Invalidate only the message at `index` after an in-place mutation\n\t * (e.g. Markdown.setText during streaming). Siblings reuse their caches.\n\t */\n\tnotifyItemChanged(index: number): void {\n\t\tthis.getItem(index);\n\t\tthis.bumpItem(index);\n\t}\n\n\tclear(): void {\n\t\tthis.items = [];\n\t\tthis.versions = [];\n\t\tthis.entries = [];\n\t\tthis.assembly = undefined;\n\t}\n\n\tprivate bumpItem(index: number): void {\n\t\tthis.versions[index] = (this.versions[index] ?? 0) + 1;\n\t\tthis.entries[index] = undefined;\n\t\tthis.assembly = undefined;\n\t}\n\n\t/** Render one message, reusing its cache when width and version match. */\n\trenderItem(index: number, width: number): string[] {\n\t\tconst item = this.getItem(index);\n\t\tconst version = this.versions[index] ?? 0;\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tconst cached = this.entries[index];\n\t\tif (cached && cached.width === safeWidth && cached.version === version) return cached.lines;\n\t\tconst lines = item.render(safeWidth);\n\t\tthis.entries[index] = { width: safeWidth, version, lines };\n\t\tthis.assembly = undefined;\n\t\treturn lines;\n\t}\n\n\tgetTotalHeight(width: number): number {\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tlet total = 0;\n\t\tfor (let index = 0; index < this.items.length; index++) {\n\t\t\ttotal += this.renderItem(index, safeWidth).length;\n\t\t}\n\t\treturn total;\n\t}\n\n\t/** All content rows assembled from the per-message caches. */\n\tgetContentLines(width: number): string[] {\n\t\treturn this.ensureAssembly(Math.max(1, Math.floor(width))).lines;\n\t}\n\n\tgetWindowLines(width: number, start: number, end: number): string[] {\n\t\tconst safeWidth = Math.max(1, Math.floor(width));\n\t\tconst lines = this.ensureAssembly(safeWidth).lines;\n\t\tconst from = Math.max(0, Math.min(lines.length, Math.floor(start)));\n\t\tconst to = Math.max(from, Math.min(lines.length, Math.ceil(end)));\n\t\treturn lines.slice(from, to);\n\t}\n\n\t/** Index of the message owning content `row`, or -1 when out of range. */\n\tgetItemIndexAtRow(row: number, width: number): number {\n\t\tconst assembly = this.ensureAssembly(Math.max(1, Math.floor(width)));\n\t\tif (row < 0 || row >= assembly.lines.length || assembly.offsets.length === 0) return -1;\n\t\tlet low = 0;\n\t\tlet high = assembly.offsets.length - 1;\n\t\twhile (low < high) {\n\t\t\tconst middle = low + Math.floor((high - low + 1) / 2);\n\t\t\tif ((assembly.offsets[middle] ?? 0) <= row) low = middle;\n\t\t\telse high = middle - 1;\n\t\t}\n\t\treturn low;\n\t}\n\n\tprivate ensureAssembly(width: number): VirtualListAssembly {\n\t\tconst cached = this.assembly;\n\t\tif (cached && cached.width === width) return cached;\n\t\tconst lines: string[] = [];\n\t\tconst offsets: number[] = [];\n\t\tfor (let index = 0; index < this.items.length; index++) {\n\t\t\toffsets.push(lines.length);\n\t\t\tconst itemLines = this.renderItem(index, width);\n\t\t\tfor (const line of itemLines) lines.push(line);\n\t\t}\n\t\tconst assembly = { width, lines, offsets };\n\t\tthis.assembly = assembly;\n\t\treturn assembly;\n\t}\n\n\trender(width: number): string[] {\n\t\treturn this.getContentLines(width);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.entries = this.items.map(() => undefined);\n\t\tthis.assembly = undefined;\n\t\tfor (const item of this.items) item.invalidate?.();\n\t}\n\n\thandleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\treturn this.handleWindowMouseEvent(0, event);\n\t}\n\n\thandleWindowMouseEvent(start: number, event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\tconst safeWidth = Math.max(1, Math.floor(event.width));\n\t\tconst row = Math.floor(start) + event.y;\n\t\tconst index = this.getItemIndexAtRow(row, safeWidth);\n\t\tif (index < 0) return undefined;\n\t\tconst item = this.items[index];\n\t\tif (typeof item?.handleMouse !== \"function\") return undefined;\n\t\tconst assembly = this.ensureAssembly(safeWidth);\n\t\tconst itemTop = assembly.offsets[index] ?? 0;\n\t\tconst nextTop = index + 1 < assembly.offsets.length ? (assembly.offsets[index + 1] ?? 0) : assembly.lines.length;\n\t\treturn item.handleMouse({\n\t\t\t...event,\n\t\t\ty: row - itemTop,\n\t\t\theight: Math.max(0, nextTop - itemTop),\n\t\t});\n\t}\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AutocompleteProvider } from "./autocomplete.ts";
|
|
2
|
+
import type { Component } from "./tui.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Interface for custom editor components.
|
|
5
|
+
*
|
|
6
|
+
* This allows extensions to provide their own editor implementation
|
|
7
|
+
* (e.g., vim mode, emacs mode, custom keybindings) while maintaining
|
|
8
|
+
* compatibility with the core application.
|
|
9
|
+
*/
|
|
10
|
+
export interface EditorComponent extends Component {
|
|
11
|
+
/** Get the current text content */
|
|
12
|
+
getText(): string;
|
|
13
|
+
/** Set the text content */
|
|
14
|
+
setText(text: string): void;
|
|
15
|
+
/** Handle raw terminal input (key presses, paste sequences, etc.) */
|
|
16
|
+
handleInput(data: string): void;
|
|
17
|
+
/** Called when user submits (e.g., Enter key) */
|
|
18
|
+
onSubmit?: (text: string) => void;
|
|
19
|
+
/** Called when text changes */
|
|
20
|
+
onChange?: (text: string) => void;
|
|
21
|
+
/** Add text to history for up/down navigation */
|
|
22
|
+
addToHistory?(text: string): void;
|
|
23
|
+
/** Insert text at current cursor position */
|
|
24
|
+
insertTextAtCursor?(text: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get text with any markers expanded (e.g., paste markers).
|
|
27
|
+
* Falls back to getText() if not implemented.
|
|
28
|
+
*/
|
|
29
|
+
getExpandedText?(): string;
|
|
30
|
+
/** Set the autocomplete provider */
|
|
31
|
+
setAutocompleteProvider?(provider: AutocompleteProvider): void;
|
|
32
|
+
/** Border color function */
|
|
33
|
+
borderColor?: (str: string) => string;
|
|
34
|
+
/** Set horizontal padding */
|
|
35
|
+
setPaddingX?(padding: number): void;
|
|
36
|
+
/** Set max visible items in autocomplete dropdown */
|
|
37
|
+
setAutocompleteMaxVisible?(maxVisible: number): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=editor-component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-component.d.ts","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAKjD,mCAAmC;IACnC,OAAO,IAAI,MAAM,CAAC;IAElB,2BAA2B;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,qEAAqE;IACrE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMhC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAMlC,iDAAiD;IACjD,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMlC,6CAA6C;IAC7C,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,eAAe,CAAC,IAAI,MAAM,CAAC;IAM3B,oCAAoC;IACpC,uBAAuB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAM/D,4BAA4B;IAC5B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtC,6BAA6B;IAC7B,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpC,qDAAqD;IACrD,yBAAyB,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACrD","sourcesContent":["import type { AutocompleteProvider } from \"./autocomplete.ts\";\nimport type { Component } from \"./tui.ts\";\n\n/**\n * Interface for custom editor components.\n *\n * This allows extensions to provide their own editor implementation\n * (e.g., vim mode, emacs mode, custom keybindings) while maintaining\n * compatibility with the core application.\n */\nexport interface EditorComponent extends Component {\n\t// =========================================================================\n\t// Core text access (required)\n\t// =========================================================================\n\n\t/** Get the current text content */\n\tgetText(): string;\n\n\t/** Set the text content */\n\tsetText(text: string): void;\n\n\t/** Handle raw terminal input (key presses, paste sequences, etc.) */\n\thandleInput(data: string): void;\n\n\t// =========================================================================\n\t// Callbacks (required)\n\t// =========================================================================\n\n\t/** Called when user submits (e.g., Enter key) */\n\tonSubmit?: (text: string) => void;\n\n\t/** Called when text changes */\n\tonChange?: (text: string) => void;\n\n\t// =========================================================================\n\t// History support (optional)\n\t// =========================================================================\n\n\t/** Add text to history for up/down navigation */\n\taddToHistory?(text: string): void;\n\n\t// =========================================================================\n\t// Advanced text manipulation (optional)\n\t// =========================================================================\n\n\t/** Insert text at current cursor position */\n\tinsertTextAtCursor?(text: string): void;\n\n\t/**\n\t * Get text with any markers expanded (e.g., paste markers).\n\t * Falls back to getText() if not implemented.\n\t */\n\tgetExpandedText?(): string;\n\n\t// =========================================================================\n\t// Autocomplete support (optional)\n\t// =========================================================================\n\n\t/** Set the autocomplete provider */\n\tsetAutocompleteProvider?(provider: AutocompleteProvider): void;\n\n\t// =========================================================================\n\t// Appearance (optional)\n\t// =========================================================================\n\n\t/** Border color function */\n\tborderColor?: (str: string) => string;\n\n\t/** Set horizontal padding */\n\tsetPaddingX?(padding: number): void;\n\n\t/** Set max visible items in autocomplete dropdown */\n\tsetAutocompleteMaxVisible?(maxVisible: number): void;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-component.js","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutocompleteProvider } from \"./autocomplete.ts\";\nimport type { Component } from \"./tui.ts\";\n\n/**\n * Interface for custom editor components.\n *\n * This allows extensions to provide their own editor implementation\n * (e.g., vim mode, emacs mode, custom keybindings) while maintaining\n * compatibility with the core application.\n */\nexport interface EditorComponent extends Component {\n\t// =========================================================================\n\t// Core text access (required)\n\t// =========================================================================\n\n\t/** Get the current text content */\n\tgetText(): string;\n\n\t/** Set the text content */\n\tsetText(text: string): void;\n\n\t/** Handle raw terminal input (key presses, paste sequences, etc.) */\n\thandleInput(data: string): void;\n\n\t// =========================================================================\n\t// Callbacks (required)\n\t// =========================================================================\n\n\t/** Called when user submits (e.g., Enter key) */\n\tonSubmit?: (text: string) => void;\n\n\t/** Called when text changes */\n\tonChange?: (text: string) => void;\n\n\t// =========================================================================\n\t// History support (optional)\n\t// =========================================================================\n\n\t/** Add text to history for up/down navigation */\n\taddToHistory?(text: string): void;\n\n\t// =========================================================================\n\t// Advanced text manipulation (optional)\n\t// =========================================================================\n\n\t/** Insert text at current cursor position */\n\tinsertTextAtCursor?(text: string): void;\n\n\t/**\n\t * Get text with any markers expanded (e.g., paste markers).\n\t * Falls back to getText() if not implemented.\n\t */\n\tgetExpandedText?(): string;\n\n\t// =========================================================================\n\t// Autocomplete support (optional)\n\t// =========================================================================\n\n\t/** Set the autocomplete provider */\n\tsetAutocompleteProvider?(provider: AutocompleteProvider): void;\n\n\t// =========================================================================\n\t// Appearance (optional)\n\t// =========================================================================\n\n\t/** Border color function */\n\tborderColor?: (str: string) => string;\n\n\t/** Set horizontal padding */\n\tsetPaddingX?(padding: number): void;\n\n\t/** Set max visible items in autocomplete dropdown */\n\tsetAutocompleteMaxVisible?(maxVisible: number): void;\n}\n"]}
|
package/dist/fuzzy.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy matching utilities.
|
|
3
|
+
* Matches if all query characters appear in order (not necessarily consecutive).
|
|
4
|
+
* Lower score = better match.
|
|
5
|
+
*/
|
|
6
|
+
export interface FuzzyMatch {
|
|
7
|
+
matches: boolean;
|
|
8
|
+
score: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function fuzzyMatch(query: string, text: string): FuzzyMatch;
|
|
11
|
+
/**
|
|
12
|
+
* Filter and sort items by fuzzy match quality (best matches first).
|
|
13
|
+
* Supports whitespace- and slash-separated tokens: all tokens must match.
|
|
14
|
+
*/
|
|
15
|
+
export declare function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[];
|
|
16
|
+
//# sourceMappingURL=fuzzy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzy.d.ts","sourceRoot":"","sources":["../src/fuzzy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAiFlE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,CAAC,EAAE,CAsC3F","sourcesContent":["/**\n * Fuzzy matching utilities.\n * Matches if all query characters appear in order (not necessarily consecutive).\n * Lower score = better match.\n */\n\nexport interface FuzzyMatch {\n\tmatches: boolean;\n\tscore: number;\n}\n\nexport function fuzzyMatch(query: string, text: string): FuzzyMatch {\n\tconst queryLower = query.toLowerCase();\n\tconst textLower = text.toLowerCase();\n\n\tconst matchQuery = (normalizedQuery: string): FuzzyMatch => {\n\t\tif (normalizedQuery.length === 0) {\n\t\t\treturn { matches: true, score: 0 };\n\t\t}\n\n\t\tif (normalizedQuery.length > textLower.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\tlet queryIndex = 0;\n\t\tlet score = 0;\n\t\tlet lastMatchIndex = -1;\n\t\tlet consecutiveMatches = 0;\n\n\t\tfor (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {\n\t\t\tif (textLower[i] === normalizedQuery[queryIndex]) {\n\t\t\t\tconst isWordBoundary = i === 0 || /[\\s\\-_./:]/.test(textLower[i - 1]!);\n\n\t\t\t\t// Reward consecutive matches\n\t\t\t\tif (lastMatchIndex === i - 1) {\n\t\t\t\t\tconsecutiveMatches++;\n\t\t\t\t\tscore -= consecutiveMatches * 5;\n\t\t\t\t} else {\n\t\t\t\t\tconsecutiveMatches = 0;\n\t\t\t\t\t// Penalize gaps\n\t\t\t\t\tif (lastMatchIndex >= 0) {\n\t\t\t\t\t\tscore += (i - lastMatchIndex - 1) * 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reward word boundary matches\n\t\t\t\tif (isWordBoundary) {\n\t\t\t\t\tscore -= 10;\n\t\t\t\t}\n\n\t\t\t\t// Slight penalty for later matches\n\t\t\t\tscore += i * 0.1;\n\n\t\t\t\tlastMatchIndex = i;\n\t\t\t\tqueryIndex++;\n\t\t\t}\n\t\t}\n\n\t\tif (queryIndex < normalizedQuery.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\tif (normalizedQuery === textLower) {\n\t\t\tscore -= 100;\n\t\t}\n\n\t\treturn { matches: true, score };\n\t};\n\n\tconst primaryMatch = matchQuery(queryLower);\n\tif (primaryMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);\n\tconst numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);\n\tconst swappedQuery = alphaNumericMatch\n\t\t? `${alphaNumericMatch.groups?.digits ?? \"\"}${alphaNumericMatch.groups?.letters ?? \"\"}`\n\t\t: numericAlphaMatch\n\t\t\t? `${numericAlphaMatch.groups?.letters ?? \"\"}${numericAlphaMatch.groups?.digits ?? \"\"}`\n\t\t\t: \"\";\n\n\tif (!swappedQuery) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst swappedMatch = matchQuery(swappedQuery);\n\tif (!swappedMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\treturn { matches: true, score: swappedMatch.score + 5 };\n}\n\n/**\n * Filter and sort items by fuzzy match quality (best matches first).\n * Supports whitespace- and slash-separated tokens: all tokens must match.\n */\nexport function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {\n\tif (!query.trim()) {\n\t\treturn items;\n\t}\n\n\tconst tokens = query\n\t\t.trim()\n\t\t.split(/[\\s/]+/)\n\t\t.filter((t) => t.length > 0);\n\n\tif (tokens.length === 0) {\n\t\treturn items;\n\t}\n\n\tconst results: { item: T; totalScore: number }[] = [];\n\n\tfor (const item of items) {\n\t\tconst text = getText(item);\n\t\tlet totalScore = 0;\n\t\tlet allMatch = true;\n\n\t\tfor (const token of tokens) {\n\t\t\tconst match = fuzzyMatch(token, text);\n\t\t\tif (match.matches) {\n\t\t\t\ttotalScore += match.score;\n\t\t\t} else {\n\t\t\t\tallMatch = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (allMatch) {\n\t\t\tresults.push({ item, totalScore });\n\t\t}\n\t}\n\n\tresults.sort((a, b) => a.totalScore - b.totalScore);\n\treturn results.map((r) => r.item);\n}\n"]}
|
package/dist/fuzzy.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy matching utilities.
|
|
3
|
+
* Matches if all query characters appear in order (not necessarily consecutive).
|
|
4
|
+
* Lower score = better match.
|
|
5
|
+
*/
|
|
6
|
+
export function fuzzyMatch(query, text) {
|
|
7
|
+
const queryLower = query.toLowerCase();
|
|
8
|
+
const textLower = text.toLowerCase();
|
|
9
|
+
const matchQuery = (normalizedQuery) => {
|
|
10
|
+
if (normalizedQuery.length === 0) {
|
|
11
|
+
return { matches: true, score: 0 };
|
|
12
|
+
}
|
|
13
|
+
if (normalizedQuery.length > textLower.length) {
|
|
14
|
+
return { matches: false, score: 0 };
|
|
15
|
+
}
|
|
16
|
+
let queryIndex = 0;
|
|
17
|
+
let score = 0;
|
|
18
|
+
let lastMatchIndex = -1;
|
|
19
|
+
let consecutiveMatches = 0;
|
|
20
|
+
for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {
|
|
21
|
+
if (textLower[i] === normalizedQuery[queryIndex]) {
|
|
22
|
+
const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]);
|
|
23
|
+
// Reward consecutive matches
|
|
24
|
+
if (lastMatchIndex === i - 1) {
|
|
25
|
+
consecutiveMatches++;
|
|
26
|
+
score -= consecutiveMatches * 5;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
consecutiveMatches = 0;
|
|
30
|
+
// Penalize gaps
|
|
31
|
+
if (lastMatchIndex >= 0) {
|
|
32
|
+
score += (i - lastMatchIndex - 1) * 2;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Reward word boundary matches
|
|
36
|
+
if (isWordBoundary) {
|
|
37
|
+
score -= 10;
|
|
38
|
+
}
|
|
39
|
+
// Slight penalty for later matches
|
|
40
|
+
score += i * 0.1;
|
|
41
|
+
lastMatchIndex = i;
|
|
42
|
+
queryIndex++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (queryIndex < normalizedQuery.length) {
|
|
46
|
+
return { matches: false, score: 0 };
|
|
47
|
+
}
|
|
48
|
+
if (normalizedQuery === textLower) {
|
|
49
|
+
score -= 100;
|
|
50
|
+
}
|
|
51
|
+
return { matches: true, score };
|
|
52
|
+
};
|
|
53
|
+
const primaryMatch = matchQuery(queryLower);
|
|
54
|
+
if (primaryMatch.matches) {
|
|
55
|
+
return primaryMatch;
|
|
56
|
+
}
|
|
57
|
+
const alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);
|
|
58
|
+
const numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);
|
|
59
|
+
const swappedQuery = alphaNumericMatch
|
|
60
|
+
? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}`
|
|
61
|
+
: numericAlphaMatch
|
|
62
|
+
? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}`
|
|
63
|
+
: "";
|
|
64
|
+
if (!swappedQuery) {
|
|
65
|
+
return primaryMatch;
|
|
66
|
+
}
|
|
67
|
+
const swappedMatch = matchQuery(swappedQuery);
|
|
68
|
+
if (!swappedMatch.matches) {
|
|
69
|
+
return primaryMatch;
|
|
70
|
+
}
|
|
71
|
+
return { matches: true, score: swappedMatch.score + 5 };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Filter and sort items by fuzzy match quality (best matches first).
|
|
75
|
+
* Supports whitespace- and slash-separated tokens: all tokens must match.
|
|
76
|
+
*/
|
|
77
|
+
export function fuzzyFilter(items, query, getText) {
|
|
78
|
+
if (!query.trim()) {
|
|
79
|
+
return items;
|
|
80
|
+
}
|
|
81
|
+
const tokens = query
|
|
82
|
+
.trim()
|
|
83
|
+
.split(/[\s/]+/)
|
|
84
|
+
.filter((t) => t.length > 0);
|
|
85
|
+
if (tokens.length === 0) {
|
|
86
|
+
return items;
|
|
87
|
+
}
|
|
88
|
+
const results = [];
|
|
89
|
+
for (const item of items) {
|
|
90
|
+
const text = getText(item);
|
|
91
|
+
let totalScore = 0;
|
|
92
|
+
let allMatch = true;
|
|
93
|
+
for (const token of tokens) {
|
|
94
|
+
const match = fuzzyMatch(token, text);
|
|
95
|
+
if (match.matches) {
|
|
96
|
+
totalScore += match.score;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
allMatch = false;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (allMatch) {
|
|
104
|
+
results.push({ item, totalScore });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
results.sort((a, b) => a.totalScore - b.totalScore);
|
|
108
|
+
return results.map((r) => r.item);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=fuzzy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzy.js","sourceRoot":"","sources":["../src/fuzzy.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Fuzzy matching utilities.\n * Matches if all query characters appear in order (not necessarily consecutive).\n * Lower score = better match.\n */\n\nexport interface FuzzyMatch {\n\tmatches: boolean;\n\tscore: number;\n}\n\nexport function fuzzyMatch(query: string, text: string): FuzzyMatch {\n\tconst queryLower = query.toLowerCase();\n\tconst textLower = text.toLowerCase();\n\n\tconst matchQuery = (normalizedQuery: string): FuzzyMatch => {\n\t\tif (normalizedQuery.length === 0) {\n\t\t\treturn { matches: true, score: 0 };\n\t\t}\n\n\t\tif (normalizedQuery.length > textLower.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\tlet queryIndex = 0;\n\t\tlet score = 0;\n\t\tlet lastMatchIndex = -1;\n\t\tlet consecutiveMatches = 0;\n\n\t\tfor (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {\n\t\t\tif (textLower[i] === normalizedQuery[queryIndex]) {\n\t\t\t\tconst isWordBoundary = i === 0 || /[\\s\\-_./:]/.test(textLower[i - 1]!);\n\n\t\t\t\t// Reward consecutive matches\n\t\t\t\tif (lastMatchIndex === i - 1) {\n\t\t\t\t\tconsecutiveMatches++;\n\t\t\t\t\tscore -= consecutiveMatches * 5;\n\t\t\t\t} else {\n\t\t\t\t\tconsecutiveMatches = 0;\n\t\t\t\t\t// Penalize gaps\n\t\t\t\t\tif (lastMatchIndex >= 0) {\n\t\t\t\t\t\tscore += (i - lastMatchIndex - 1) * 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reward word boundary matches\n\t\t\t\tif (isWordBoundary) {\n\t\t\t\t\tscore -= 10;\n\t\t\t\t}\n\n\t\t\t\t// Slight penalty for later matches\n\t\t\t\tscore += i * 0.1;\n\n\t\t\t\tlastMatchIndex = i;\n\t\t\t\tqueryIndex++;\n\t\t\t}\n\t\t}\n\n\t\tif (queryIndex < normalizedQuery.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\tif (normalizedQuery === textLower) {\n\t\t\tscore -= 100;\n\t\t}\n\n\t\treturn { matches: true, score };\n\t};\n\n\tconst primaryMatch = matchQuery(queryLower);\n\tif (primaryMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);\n\tconst numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);\n\tconst swappedQuery = alphaNumericMatch\n\t\t? `${alphaNumericMatch.groups?.digits ?? \"\"}${alphaNumericMatch.groups?.letters ?? \"\"}`\n\t\t: numericAlphaMatch\n\t\t\t? `${numericAlphaMatch.groups?.letters ?? \"\"}${numericAlphaMatch.groups?.digits ?? \"\"}`\n\t\t\t: \"\";\n\n\tif (!swappedQuery) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst swappedMatch = matchQuery(swappedQuery);\n\tif (!swappedMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\treturn { matches: true, score: swappedMatch.score + 5 };\n}\n\n/**\n * Filter and sort items by fuzzy match quality (best matches first).\n * Supports whitespace- and slash-separated tokens: all tokens must match.\n */\nexport function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {\n\tif (!query.trim()) {\n\t\treturn items;\n\t}\n\n\tconst tokens = query\n\t\t.trim()\n\t\t.split(/[\\s/]+/)\n\t\t.filter((t) => t.length > 0);\n\n\tif (tokens.length === 0) {\n\t\treturn items;\n\t}\n\n\tconst results: { item: T; totalScore: number }[] = [];\n\n\tfor (const item of items) {\n\t\tconst text = getText(item);\n\t\tlet totalScore = 0;\n\t\tlet allMatch = true;\n\n\t\tfor (const token of tokens) {\n\t\t\tconst match = fuzzyMatch(token, text);\n\t\t\tif (match.matches) {\n\t\t\t\ttotalScore += match.score;\n\t\t\t} else {\n\t\t\t\tallMatch = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (allMatch) {\n\t\t\tresults.push({ item, totalScore });\n\t\t}\n\t}\n\n\tresults.sort((a, b) => a.totalScore - b.totalScore);\n\treturn results.map((r) => r.item);\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { Marked, type Token, type Tokens } from "marked";
|
|
2
|
+
export { type AutocompleteItem, type AutocompleteProvider, type AutocompleteSuggestions, CombinedAutocompleteProvider, type SkillCompletion, type SlashCommand, } from "./autocomplete.ts";
|
|
3
|
+
export { Box } from "./components/box.ts";
|
|
4
|
+
export { CancellableLoader } from "./components/cancellable-loader.ts";
|
|
5
|
+
export { Editor, type EditorOptions, type EditorTheme } from "./components/editor.ts";
|
|
6
|
+
export { HStack } from "./components/h-stack.ts";
|
|
7
|
+
export { Image, type ImageOptions, type ImageTheme } from "./components/image.ts";
|
|
8
|
+
export { Input } from "./components/input.ts";
|
|
9
|
+
export { Loader, type LoaderIndicatorOptions } from "./components/loader.ts";
|
|
10
|
+
export { type DefaultTextStyle, Markdown, type MarkdownOptions, type MarkdownTheme } from "./components/markdown.ts";
|
|
11
|
+
export { MouseRegion, type MouseRegionHandler } from "./components/mouse-region.ts";
|
|
12
|
+
export { DEFAULT_SCROLL_VIEW_OVERSCAN, ScrollView, type ScrollViewOptions, type ScrollViewScrollbar, type ScrollViewScrollToOptions, } from "./components/scroll-view.ts";
|
|
13
|
+
export { type SelectItem, SelectList, type SelectListLayoutOptions, type SelectListTheme, type SelectListTruncatePrimaryContext, } from "./components/select-list.ts";
|
|
14
|
+
export { type SettingItem, SettingsList, type SettingsListTheme } from "./components/settings-list.ts";
|
|
15
|
+
export { Spacer } from "./components/spacer.ts";
|
|
16
|
+
export { Text } from "./components/text.ts";
|
|
17
|
+
export { TruncatedText } from "./components/truncated-text.ts";
|
|
18
|
+
export { type StackChild, type StackEntry, type StackEntryOptions, type StackOptions, VStack, } from "./components/v-stack.ts";
|
|
19
|
+
export { VirtualList } from "./components/virtual-list.ts";
|
|
20
|
+
export type { EditorComponent } from "./editor-component.ts";
|
|
21
|
+
export { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from "./fuzzy.ts";
|
|
22
|
+
export { getKeybindings, type Keybinding, type KeybindingConflict, type KeybindingContext, type KeybindingContextConflict, type KeybindingDefinition, type KeybindingDefinitions, type Keybindings, type KeybindingsConfig, KeybindingsManager, setKeybindings, TUI_KEYBINDINGS, } from "./keybindings.ts";
|
|
23
|
+
export { decodeKittyPrintable, isKeyRelease, isKeyRepeat, isKittyProtocolActive, Key, type KeyEventType, type KeyId, matchesKey, parseKey, setKittyProtocolActive, } from "./keys.ts";
|
|
24
|
+
export { type RenderLatexOptions, renderLatex } from "./latex.ts";
|
|
25
|
+
export { getNativeClipboard, type NativeClipboard } from "./native-platform.ts";
|
|
26
|
+
export { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from "./stdin-buffer.ts";
|
|
27
|
+
export { ProcessTerminal, type Terminal } from "./terminal.ts";
|
|
28
|
+
export { parseOsc11BackgroundColor, parseTerminalColorSchemeReport, type RgbColor, type TerminalColorScheme, } from "./terminal-colors.ts";
|
|
29
|
+
export { allocateImageId, type CellDimensions, calculateImageRows, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, hyperlink, type ImageDimensions, type ImageProtocol, type ImageRenderOptions, imageFallback, renderImage, resetCapabilitiesCache, setCapabilities, setCapabilityOverrides, setCellDimensions, type TerminalCapabilities, } from "./terminal-image.ts";
|
|
30
|
+
export { type AutocompleteHost, type Component, Container, CURSOR_MARKER, compositeTuiLine, type Focusable, type FocusTransition, type FocusTransitionOptions, isAutocompleteHost, isFocusable, isViewportTUI, type OverlayAnchor, type OverlayBounds, type OverlayHandle, type OverlayMargin, type OverlayOptions, type OverlayUnfocusOptions, type SizeValue, type TUI, type TuiInputListener, type TuiInputListenerResult, type TuiMode, type TuiMouseButton, type TuiMouseEvent, type TuiMouseEventResult, type TuiMouseEventType, type TuiStopOptions, type ViewportTUI, } from "./tui.ts";
|
|
31
|
+
export { TuiAltScreen, type TuiAltScreenOptions } from "./tui-alt-screen.ts";
|
|
32
|
+
export { TuiMainScreen, type TuiMainScreenRenderState } from "./tui-main-screen.ts";
|
|
33
|
+
export { getOsc8LinkAtColumn, sliceByColumn, stripTerminalSequences, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "./utils.ts";
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Core TUI interfaces and classes\n\nexport { Marked, type Token, type Tokens } from \"marked\";\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SkillCompletion,\n\ttype SlashCommand,\n} from \"./autocomplete.ts\";\n// Components\nexport { Box } from \"./components/box.ts\";\nexport { CancellableLoader } from \"./components/cancellable-loader.ts\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.ts\";\nexport { HStack } from \"./components/h-stack.ts\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.ts\";\nexport { Input } from \"./components/input.ts\";\nexport { Loader, type LoaderIndicatorOptions } from \"./components/loader.ts\";\nexport { type DefaultTextStyle, Markdown, type MarkdownOptions, type MarkdownTheme } from \"./components/markdown.ts\";\nexport { MouseRegion, type MouseRegionHandler } from \"./components/mouse-region.ts\";\nexport {\n\tDEFAULT_SCROLL_VIEW_OVERSCAN,\n\tScrollView,\n\ttype ScrollViewOptions,\n\ttype ScrollViewScrollbar,\n\ttype ScrollViewScrollToOptions,\n} from \"./components/scroll-view.ts\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.ts\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.ts\";\nexport { Spacer } from \"./components/spacer.ts\";\nexport { Text } from \"./components/text.ts\";\nexport { TruncatedText } from \"./components/truncated-text.ts\";\nexport {\n\ttype StackChild,\n\ttype StackEntry,\n\ttype StackEntryOptions,\n\ttype StackOptions,\n\tVStack,\n} from \"./components/v-stack.ts\";\nexport { VirtualList } from \"./components/virtual-list.ts\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.ts\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.ts\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingContext,\n\ttype KeybindingContextConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.ts\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.ts\";\n// LaTeX rendering\nexport { type RenderLatexOptions, renderLatex } from \"./latex.ts\";\n// Native platform integration\nexport { getNativeClipboard, type NativeClipboard } from \"./native-platform.ts\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.ts\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.ts\";\n// Terminal colors\nexport {\n\tparseOsc11BackgroundColor,\n\tparseTerminalColorSchemeReport,\n\ttype RgbColor,\n\ttype TerminalColorScheme,\n} from \"./terminal-colors.ts\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\thyperlink,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCapabilities,\n\tsetCapabilityOverrides,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.ts\";\nexport {\n\ttype AutocompleteHost,\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\tcompositeTuiLine,\n\ttype Focusable,\n\ttype FocusTransition,\n\ttype FocusTransitionOptions,\n\tisAutocompleteHost,\n\tisFocusable,\n\tisViewportTUI,\n\ttype OverlayAnchor,\n\ttype OverlayBounds,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype OverlayUnfocusOptions,\n\ttype SizeValue,\n\ttype TUI,\n\ttype TuiInputListener,\n\ttype TuiInputListenerResult,\n\ttype TuiMode,\n\ttype TuiMouseButton,\n\ttype TuiMouseEvent,\n\ttype TuiMouseEventResult,\n\ttype TuiMouseEventType,\n\ttype TuiStopOptions,\n\ttype ViewportTUI,\n} from \"./tui.ts\";\nexport { TuiAltScreen, type TuiAltScreenOptions } from \"./tui-alt-screen.ts\";\nexport { TuiMainScreen, type TuiMainScreenRenderState } from \"./tui-main-screen.ts\";\n// Utilities\nexport {\n\tgetOsc8LinkAtColumn,\n\tsliceByColumn,\n\tstripTerminalSequences,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"./utils.ts\";\n"]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Core TUI interfaces and classes
|
|
2
|
+
export { Marked } from "marked";
|
|
3
|
+
// Autocomplete support
|
|
4
|
+
export { CombinedAutocompleteProvider, } from "./autocomplete.js";
|
|
5
|
+
// Components
|
|
6
|
+
export { Box } from "./components/box.js";
|
|
7
|
+
export { CancellableLoader } from "./components/cancellable-loader.js";
|
|
8
|
+
export { Editor } from "./components/editor.js";
|
|
9
|
+
export { HStack } from "./components/h-stack.js";
|
|
10
|
+
export { Image } from "./components/image.js";
|
|
11
|
+
export { Input } from "./components/input.js";
|
|
12
|
+
export { Loader } from "./components/loader.js";
|
|
13
|
+
export { Markdown } from "./components/markdown.js";
|
|
14
|
+
export { MouseRegion } from "./components/mouse-region.js";
|
|
15
|
+
export { DEFAULT_SCROLL_VIEW_OVERSCAN, ScrollView, } from "./components/scroll-view.js";
|
|
16
|
+
export { SelectList, } from "./components/select-list.js";
|
|
17
|
+
export { SettingsList } from "./components/settings-list.js";
|
|
18
|
+
export { Spacer } from "./components/spacer.js";
|
|
19
|
+
export { Text } from "./components/text.js";
|
|
20
|
+
export { TruncatedText } from "./components/truncated-text.js";
|
|
21
|
+
export { VStack, } from "./components/v-stack.js";
|
|
22
|
+
export { VirtualList } from "./components/virtual-list.js";
|
|
23
|
+
// Fuzzy matching
|
|
24
|
+
export { fuzzyFilter, fuzzyMatch } from "./fuzzy.js";
|
|
25
|
+
// Keybindings
|
|
26
|
+
export { getKeybindings, KeybindingsManager, setKeybindings, TUI_KEYBINDINGS, } from "./keybindings.js";
|
|
27
|
+
// Keyboard input handling
|
|
28
|
+
export { decodeKittyPrintable, isKeyRelease, isKeyRepeat, isKittyProtocolActive, Key, matchesKey, parseKey, setKittyProtocolActive, } from "./keys.js";
|
|
29
|
+
// LaTeX rendering
|
|
30
|
+
export { renderLatex } from "./latex.js";
|
|
31
|
+
// Native platform integration
|
|
32
|
+
export { getNativeClipboard } from "./native-platform.js";
|
|
33
|
+
// Input buffering for batch splitting
|
|
34
|
+
export { StdinBuffer } from "./stdin-buffer.js";
|
|
35
|
+
// Terminal interface and implementations
|
|
36
|
+
export { ProcessTerminal } from "./terminal.js";
|
|
37
|
+
// Terminal colors
|
|
38
|
+
export { parseOsc11BackgroundColor, parseTerminalColorSchemeReport, } from "./terminal-colors.js";
|
|
39
|
+
// Terminal image support
|
|
40
|
+
export { allocateImageId, calculateImageRows, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, hyperlink, imageFallback, renderImage, resetCapabilitiesCache, setCapabilities, setCapabilityOverrides, setCellDimensions, } from "./terminal-image.js";
|
|
41
|
+
export { Container, CURSOR_MARKER, compositeTuiLine, isAutocompleteHost, isFocusable, isViewportTUI, } from "./tui.js";
|
|
42
|
+
export { TuiAltScreen } from "./tui-alt-screen.js";
|
|
43
|
+
export { TuiMainScreen } from "./tui-main-screen.js";
|
|
44
|
+
// Utilities
|
|
45
|
+
export { getOsc8LinkAtColumn, sliceByColumn, stripTerminalSequences, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "./utils.js";
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Core TUI interfaces and classes\n\nexport { Marked, type Token, type Tokens } from \"marked\";\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SkillCompletion,\n\ttype SlashCommand,\n} from \"./autocomplete.ts\";\n// Components\nexport { Box } from \"./components/box.ts\";\nexport { CancellableLoader } from \"./components/cancellable-loader.ts\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.ts\";\nexport { HStack } from \"./components/h-stack.ts\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.ts\";\nexport { Input } from \"./components/input.ts\";\nexport { Loader, type LoaderIndicatorOptions } from \"./components/loader.ts\";\nexport { type DefaultTextStyle, Markdown, type MarkdownOptions, type MarkdownTheme } from \"./components/markdown.ts\";\nexport { MouseRegion, type MouseRegionHandler } from \"./components/mouse-region.ts\";\nexport {\n\tDEFAULT_SCROLL_VIEW_OVERSCAN,\n\tScrollView,\n\ttype ScrollViewOptions,\n\ttype ScrollViewScrollbar,\n\ttype ScrollViewScrollToOptions,\n} from \"./components/scroll-view.ts\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.ts\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.ts\";\nexport { Spacer } from \"./components/spacer.ts\";\nexport { Text } from \"./components/text.ts\";\nexport { TruncatedText } from \"./components/truncated-text.ts\";\nexport {\n\ttype StackChild,\n\ttype StackEntry,\n\ttype StackEntryOptions,\n\ttype StackOptions,\n\tVStack,\n} from \"./components/v-stack.ts\";\nexport { VirtualList } from \"./components/virtual-list.ts\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.ts\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.ts\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingContext,\n\ttype KeybindingContextConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.ts\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.ts\";\n// LaTeX rendering\nexport { type RenderLatexOptions, renderLatex } from \"./latex.ts\";\n// Native platform integration\nexport { getNativeClipboard, type NativeClipboard } from \"./native-platform.ts\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.ts\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.ts\";\n// Terminal colors\nexport {\n\tparseOsc11BackgroundColor,\n\tparseTerminalColorSchemeReport,\n\ttype RgbColor,\n\ttype TerminalColorScheme,\n} from \"./terminal-colors.ts\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\thyperlink,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCapabilities,\n\tsetCapabilityOverrides,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.ts\";\nexport {\n\ttype AutocompleteHost,\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\tcompositeTuiLine,\n\ttype Focusable,\n\ttype FocusTransition,\n\ttype FocusTransitionOptions,\n\tisAutocompleteHost,\n\tisFocusable,\n\tisViewportTUI,\n\ttype OverlayAnchor,\n\ttype OverlayBounds,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype OverlayUnfocusOptions,\n\ttype SizeValue,\n\ttype TUI,\n\ttype TuiInputListener,\n\ttype TuiInputListenerResult,\n\ttype TuiMode,\n\ttype TuiMouseButton,\n\ttype TuiMouseEvent,\n\ttype TuiMouseEventResult,\n\ttype TuiMouseEventType,\n\ttype TuiStopOptions,\n\ttype ViewportTUI,\n} from \"./tui.ts\";\nexport { TuiAltScreen, type TuiAltScreenOptions } from \"./tui-alt-screen.ts\";\nexport { TuiMainScreen, type TuiMainScreenRenderState } from \"./tui-main-screen.ts\";\n// Utilities\nexport {\n\tgetOsc8LinkAtColumn,\n\tsliceByColumn,\n\tstripTerminalSequences,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"./utils.ts\";\n"]}
|