@code-yeongyu/senpi-tui 2026.9.12-3 → 2026.9.12
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 +4 -53
- package/dist/alt-screen-search.d.ts +1 -21
- package/dist/alt-screen-search.d.ts.map +1 -1
- package/dist/alt-screen-search.js +42 -199
- package/dist/alt-screen-search.js.map +1 -1
- package/dist/components/box.d.ts +1 -3
- package/dist/components/box.d.ts.map +1 -1
- package/dist/components/box.js +0 -28
- package/dist/components/box.js.map +1 -1
- package/dist/components/editor.d.ts +1 -6
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +18 -98
- package/dist/components/editor.js.map +1 -1
- package/dist/components/input.d.ts +1 -12
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +6 -40
- package/dist/components/input.js.map +1 -1
- package/dist/components/latex.d.ts.map +1 -1
- package/dist/components/latex.js +0 -7
- package/dist/components/latex.js.map +1 -1
- package/dist/components/loader.d.ts +0 -3
- package/dist/components/loader.d.ts.map +1 -1
- package/dist/components/loader.js +8 -20
- package/dist/components/loader.js.map +1 -1
- package/dist/components/scroll-view.d.ts +3 -6
- package/dist/components/scroll-view.d.ts.map +1 -1
- package/dist/components/scroll-view.js +1 -6
- package/dist/components/scroll-view.js.map +1 -1
- package/dist/components/select-list.d.ts +1 -4
- package/dist/components/select-list.d.ts.map +1 -1
- package/dist/components/select-list.js +2 -48
- package/dist/components/select-list.js.map +1 -1
- package/dist/components/settings-list.d.ts +1 -5
- package/dist/components/settings-list.d.ts.map +1 -1
- package/dist/components/settings-list.js +5 -54
- package/dist/components/settings-list.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +1 -3
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +9 -32
- package/dist/layout.js.map +1 -1
- package/dist/native-modifiers.d.ts +1 -2
- package/dist/native-modifiers.d.ts.map +1 -1
- package/dist/native-modifiers.js +44 -3
- package/dist/native-modifiers.js.map +1 -1
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +20 -2
- package/dist/terminal.js.map +1 -1
- package/dist/tui-alt-screen.d.ts +1 -31
- package/dist/tui-alt-screen.d.ts.map +1 -1
- package/dist/tui-alt-screen.js +41 -335
- package/dist/tui-alt-screen.js.map +1 -1
- package/dist/tui.d.ts +5 -83
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +4 -118
- package/dist/tui.js.map +1 -1
- package/dist/utils.d.ts +0 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +0 -9
- package/dist/utils.js.map +1 -1
- package/native/darwin/README.md +6 -8
- package/native/darwin/build.sh +5 -12
- package/native/darwin/prebuilds/darwin-arm64/{darwin-platform.node → darwin-modifiers.node} +0 -0
- package/native/darwin/prebuilds/darwin-x64/{darwin-platform.node → darwin-modifiers.node} +0 -0
- package/native/darwin/src/darwin-modifiers.c +70 -0
- package/native/win32/README.md +7 -18
- package/native/win32/build.mjs +4 -7
- package/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/native/win32/src/win32-console-mode.c +119 -0
- package/package.json +3 -10
- package/dist/components/mouse-region.d.ts +0 -12
- package/dist/components/mouse-region.d.ts.map +0 -1
- package/dist/components/mouse-region.js +0 -19
- package/dist/components/mouse-region.js.map +0 -1
- package/dist/native-platform.d.ts +0 -18
- package/dist/native-platform.d.ts.map +0 -1
- package/dist/native-platform.js +0 -42
- package/dist/native-platform.js.map +0 -1
- package/native/clipboard.h +0 -170
- package/native/darwin/src/darwin-platform.m +0 -93
- package/native/linux/README.md +0 -23
- package/native/linux/build.sh +0 -65
- 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 +0 -70
- package/native/linux/src/linux-platform-x11.c +0 -274
- package/native/napi.h +0 -89
- 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 +0 -241
package/dist/components/box.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { dispatchMouseEvent } from "../tui.js";
|
|
2
1
|
import { applyBackgroundToLine, visibleWidth } from "../utils.js";
|
|
3
2
|
/**
|
|
4
3
|
* Box component - a container that applies padding and background to all children
|
|
@@ -64,30 +63,6 @@ export class Box {
|
|
|
64
63
|
child.invalidate?.();
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
|
-
handleMouse(event) {
|
|
68
|
-
const contentWidth = Math.max(1, event.width - this.paddingX * 2);
|
|
69
|
-
const contentY = event.y - this.paddingY;
|
|
70
|
-
const contentX = event.x - this.paddingX;
|
|
71
|
-
if (contentY < 0 || contentX < 0 || contentX >= contentWidth)
|
|
72
|
-
return undefined;
|
|
73
|
-
const mouseChildren = this.mouseLayout?.width === contentWidth
|
|
74
|
-
? this.mouseLayout.children
|
|
75
|
-
: this.children.map((component) => ({ component, height: component.render(contentWidth).length }));
|
|
76
|
-
let childY = 0;
|
|
77
|
-
for (const { component: child, height: childHeight } of mouseChildren) {
|
|
78
|
-
if (contentY >= childY && contentY < childY + childHeight) {
|
|
79
|
-
return dispatchMouseEvent(child, {
|
|
80
|
-
...event,
|
|
81
|
-
x: contentX,
|
|
82
|
-
y: contentY - childY,
|
|
83
|
-
width: contentWidth,
|
|
84
|
-
height: childHeight,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
childY += childHeight;
|
|
88
|
-
}
|
|
89
|
-
return undefined;
|
|
90
|
-
}
|
|
91
66
|
render(width) {
|
|
92
67
|
if (this.children.length === 0) {
|
|
93
68
|
return [];
|
|
@@ -96,15 +71,12 @@ export class Box {
|
|
|
96
71
|
const leftPad = " ".repeat(this.paddingX);
|
|
97
72
|
// Render all children
|
|
98
73
|
const childLines = [];
|
|
99
|
-
const mouseChildren = [];
|
|
100
74
|
for (const child of this.children) {
|
|
101
75
|
const lines = child.render(contentWidth);
|
|
102
|
-
mouseChildren.push({ component: child, height: lines.length });
|
|
103
76
|
for (const line of lines) {
|
|
104
77
|
childLines.push(leftPad + line);
|
|
105
78
|
}
|
|
106
79
|
}
|
|
107
|
-
this.mouseLayout = { width: contentWidth, children: mouseChildren };
|
|
108
80
|
if (childLines.length === 0) {
|
|
109
81
|
return [];
|
|
110
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, dispatchMouseEvent, type TuiMouseDispatchResult, type TuiMouseEvent } from \"../tui.ts\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.ts\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\tprivate bgFn?: (text: string) => string;\n\tprivate disposed = false;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\tprivate mouseLayout?: { width: number; children: Array<{ component: Component; height: number }> };\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t\tcomponent.dispose?.();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tfor (const child of this.children) {\n\t\t\tchild.dispose?.();\n\t\t}\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tdetachAll(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tfor (const child of this.children) {\n\t\t\tchild.dispose?.();\n\t\t}\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\thandleMouse(event: TuiMouseEvent): TuiMouseDispatchResult | undefined {\n\t\tconst contentWidth = Math.max(1, event.width - this.paddingX * 2);\n\t\tconst contentY = event.y - this.paddingY;\n\t\tconst contentX = event.x - this.paddingX;\n\t\tif (contentY < 0 || contentX < 0 || contentX >= contentWidth) return undefined;\n\n\t\tconst mouseChildren =\n\t\t\tthis.mouseLayout?.width === contentWidth\n\t\t\t\t? this.mouseLayout.children\n\t\t\t\t: this.children.map((component) => ({ component, height: component.render(contentWidth).length }));\n\t\tlet childY = 0;\n\t\tfor (const { component: child, height: childHeight } of mouseChildren) {\n\t\t\tif (contentY >= childY && contentY < childY + childHeight) {\n\t\t\t\treturn dispatchMouseEvent(child, {\n\t\t\t\t\t...event,\n\t\t\t\t\tx: contentX,\n\t\t\t\t\ty: contentY - childY,\n\t\t\t\t\twidth: contentWidth,\n\t\t\t\t\theight: childHeight,\n\t\t\t\t});\n\t\t\t}\n\t\t\tchildY += childHeight;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tconst mouseChildren: Array<{ component: Component; height: number }> = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tmouseChildren.push({ component: child, height: lines.length });\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\t\tthis.mouseLayout = { width: contentWidth, children: mouseChildren };\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"../tui.ts\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.ts\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\tprivate bgFn?: (text: string) => string;\n\tprivate disposed = false;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t\tcomponent.dispose?.();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tfor (const child of this.children) {\n\t\t\tchild.dispose?.();\n\t\t}\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tdetachAll(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tfor (const child of this.children) {\n\t\t\tchild.dispose?.();\n\t\t}\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AutocompleteProvider } from "../autocomplete.ts";
|
|
2
2
|
import { type EditorImageState } from "../image-markers.ts";
|
|
3
3
|
import { type EditorPasteState } from "../paste-markers.ts";
|
|
4
|
-
import { type Component, type Focusable, type TUI
|
|
4
|
+
import { type Component, type Focusable, type TUI } from "../tui.ts";
|
|
5
5
|
import { type SelectListTheme } from "./select-list.ts";
|
|
6
6
|
/** Which atomic marker family a segment belongs to, if any. */
|
|
7
7
|
export type MarkerKind = "paste" | "image";
|
|
@@ -55,8 +55,6 @@ export declare class Editor implements Component, Focusable {
|
|
|
55
55
|
private terminalPlatform?;
|
|
56
56
|
private terminalSocketExists?;
|
|
57
57
|
private lastWidth;
|
|
58
|
-
private renderedVisibleLineCount;
|
|
59
|
-
private renderedAutocompleteHeight;
|
|
60
58
|
private scrollOffset;
|
|
61
59
|
borderColor: (str: string) => string;
|
|
62
60
|
private autocompleteProvider?;
|
|
@@ -145,10 +143,7 @@ export declare class Editor implements Component, Focusable {
|
|
|
145
143
|
private setTextInternal;
|
|
146
144
|
invalidate(): void;
|
|
147
145
|
private getWrappedLine;
|
|
148
|
-
protected renderTopBorder(width: number, hiddenLineCount: number): string;
|
|
149
|
-
protected renderBottomBorder(width: number, hiddenLineCount: number): string;
|
|
150
146
|
render(width: number): string[];
|
|
151
|
-
handleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined;
|
|
152
147
|
handleInput(data: string): void;
|
|
153
148
|
private layoutText;
|
|
154
149
|
getText(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/components/editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAA2B,MAAM,oBAAoB,CAAC;AACxF,OAAO,EACN,KAAK,gBAAgB,EAOrB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACN,KAAK,gBAAgB,EAKrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/components/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { decodePrintableKey, matchesKey } from "../keys.js";
|
|
|
4
4
|
import { KillRing } from "../kill-ring.js";
|
|
5
5
|
import { isPasteMarker, PasteMarkerRegistry, pasteMarkerId, segmentWithMarkers, } from "../paste-markers.js";
|
|
6
6
|
import { normalizeWarpWslShiftEnterInput } from "../terminal.js";
|
|
7
|
-
import { CURSOR_MARKER
|
|
7
|
+
import { CURSOR_MARKER } from "../tui.js";
|
|
8
8
|
import { UndoStack } from "../undo-stack.js";
|
|
9
9
|
import { cjkBreakRegex, getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, sliceByColumn, visibleWidth, } from "../utils.js";
|
|
10
10
|
import { findWordBackward, findWordForward } from "../word-navigation.js";
|
|
@@ -183,12 +183,6 @@ function buildDebouncePattern(triggerCharacters) {
|
|
|
183
183
|
}
|
|
184
184
|
function createScrollBorder(direction, hiddenLineCount, width) {
|
|
185
185
|
const availableWidth = Math.max(0, width);
|
|
186
|
-
const label = ` ${direction} ${hiddenLineCount} more `;
|
|
187
|
-
const labelWidth = visibleWidth(label);
|
|
188
|
-
if (labelWidth + 2 <= availableWidth) {
|
|
189
|
-
const leftWidth = Math.floor((availableWidth - labelWidth) / 2);
|
|
190
|
-
return "─".repeat(leftWidth) + label + "─".repeat(availableWidth - leftWidth - labelWidth);
|
|
191
|
-
}
|
|
192
186
|
const indicator = `─── ${direction} ${hiddenLineCount} more `;
|
|
193
187
|
const remaining = availableWidth - visibleWidth(indicator);
|
|
194
188
|
if (remaining >= 0)
|
|
@@ -207,10 +201,8 @@ export class Editor {
|
|
|
207
201
|
/** Focusable interface - set by TUI when focus changes */
|
|
208
202
|
this.focused = false;
|
|
209
203
|
this.paddingX = 0;
|
|
210
|
-
// Store last render
|
|
204
|
+
// Store last render width for cursor navigation
|
|
211
205
|
this.lastWidth = 80;
|
|
212
|
-
this.renderedVisibleLineCount = 1;
|
|
213
|
-
this.renderedAutocompleteHeight = 0;
|
|
214
206
|
// Vertical scrolling support
|
|
215
207
|
this.scrollOffset = 0;
|
|
216
208
|
this.autocompleteTriggerCharacters = [...DEFAULT_AUTOCOMPLETE_TRIGGER_CHARACTERS];
|
|
@@ -445,14 +437,6 @@ export class Editor {
|
|
|
445
437
|
this.wrappedLineCache[lineIndex] = wrapped;
|
|
446
438
|
return wrapped;
|
|
447
439
|
}
|
|
448
|
-
renderTopBorder(width, hiddenLineCount) {
|
|
449
|
-
const border = hiddenLineCount > 0 ? createScrollBorder("↑", hiddenLineCount, width) : "─".repeat(width);
|
|
450
|
-
return this.borderColor(border);
|
|
451
|
-
}
|
|
452
|
-
renderBottomBorder(width, hiddenLineCount) {
|
|
453
|
-
const border = hiddenLineCount > 0 ? createScrollBorder("↓", hiddenLineCount, width) : "─".repeat(width);
|
|
454
|
-
return this.borderColor(border);
|
|
455
|
-
}
|
|
456
440
|
render(width) {
|
|
457
441
|
const maxPadding = Math.max(0, Math.floor((width - 1) / 2));
|
|
458
442
|
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
@@ -462,6 +446,7 @@ export class Editor {
|
|
|
462
446
|
const layoutWidth = Math.max(1, contentWidth - (paddingX ? 0 : 1));
|
|
463
447
|
// Store for cursor navigation (must match wrapping width)
|
|
464
448
|
this.lastWidth = layoutWidth;
|
|
449
|
+
const horizontal = this.borderColor("─");
|
|
465
450
|
// Layout the text
|
|
466
451
|
const layoutLines = this.layoutText(layoutWidth);
|
|
467
452
|
// Calculate max visible lines: 30% of terminal height, minimum 5 lines
|
|
@@ -483,12 +468,17 @@ export class Editor {
|
|
|
483
468
|
this.scrollOffset = Math.max(0, Math.min(this.scrollOffset, maxScrollOffset));
|
|
484
469
|
// Get visible lines slice
|
|
485
470
|
const visibleLines = layoutLines.slice(this.scrollOffset, this.scrollOffset + maxVisibleLines);
|
|
486
|
-
this.renderedVisibleLineCount = visibleLines.length;
|
|
487
471
|
const result = [];
|
|
488
472
|
const leftPadding = " ".repeat(paddingX);
|
|
489
473
|
const rightPadding = leftPadding;
|
|
490
474
|
// Render top border (with scroll indicator if scrolled down)
|
|
491
|
-
|
|
475
|
+
if (this.scrollOffset > 0) {
|
|
476
|
+
const border = createScrollBorder("↑", this.scrollOffset, width);
|
|
477
|
+
result.push(this.borderColor(border));
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
result.push(horizontal.repeat(width));
|
|
481
|
+
}
|
|
492
482
|
// Render each visible layout line
|
|
493
483
|
// Emit hardware cursor marker when focused so TUI can position the
|
|
494
484
|
// hardware cursor for IME candidate-window placement even while
|
|
@@ -537,12 +527,16 @@ export class Editor {
|
|
|
537
527
|
}
|
|
538
528
|
// Render bottom border (with scroll indicator if more content below)
|
|
539
529
|
const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length);
|
|
540
|
-
|
|
530
|
+
if (linesBelow > 0) {
|
|
531
|
+
const border = createScrollBorder("↓", linesBelow, width);
|
|
532
|
+
result.push(this.borderColor(border));
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
result.push(horizontal.repeat(width));
|
|
536
|
+
}
|
|
541
537
|
// Add autocomplete list if active
|
|
542
|
-
this.renderedAutocompleteHeight = 0;
|
|
543
538
|
if (this.autocompleteState && this.autocompleteList) {
|
|
544
539
|
const autocompleteResult = this.autocompleteList.render(contentWidth);
|
|
545
|
-
this.renderedAutocompleteHeight = autocompleteResult.length;
|
|
546
540
|
for (const line of autocompleteResult) {
|
|
547
541
|
const lineWidth = visibleWidth(line);
|
|
548
542
|
const linePadding = " ".repeat(Math.max(0, contentWidth - lineWidth));
|
|
@@ -551,67 +545,6 @@ export class Editor {
|
|
|
551
545
|
}
|
|
552
546
|
return result;
|
|
553
547
|
}
|
|
554
|
-
handleMouse(event) {
|
|
555
|
-
const autocompleteStartRow = this.renderedVisibleLineCount + 2;
|
|
556
|
-
if (this.autocompleteState &&
|
|
557
|
-
this.autocompleteList &&
|
|
558
|
-
event.y >= autocompleteStartRow &&
|
|
559
|
-
event.y < autocompleteStartRow + this.renderedAutocompleteHeight) {
|
|
560
|
-
const maxPadding = Math.max(0, Math.floor((event.width - 1) / 2));
|
|
561
|
-
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
562
|
-
const contentWidth = Math.max(1, event.width - paddingX * 2);
|
|
563
|
-
const result = this.autocompleteList.handleMouse?.({
|
|
564
|
-
...event,
|
|
565
|
-
x: event.x - paddingX,
|
|
566
|
-
y: event.y - autocompleteStartRow,
|
|
567
|
-
width: contentWidth,
|
|
568
|
-
height: this.renderedAutocompleteHeight,
|
|
569
|
-
});
|
|
570
|
-
return result ? { ...result, focus: true } : undefined;
|
|
571
|
-
}
|
|
572
|
-
// Leave press/drag/release unhandled so the renderer's screen-level text
|
|
573
|
-
// selection can run over the editor rows (drag to select, release to copy).
|
|
574
|
-
// The renderer synthesizes a click when press and release land on the same
|
|
575
|
-
// cell without movement, which is the gesture that positions the cursor.
|
|
576
|
-
if (event.type !== "click" || event.button !== "left")
|
|
577
|
-
return undefined;
|
|
578
|
-
if (event.y <= 0 || event.y > this.renderedVisibleLineCount)
|
|
579
|
-
return { handled: true, focus: true };
|
|
580
|
-
const visualLines = this.buildVisualLineMap(this.lastWidth);
|
|
581
|
-
const visualLineIndex = this.scrollOffset + event.y - 1;
|
|
582
|
-
const visualLine = visualLines[visualLineIndex];
|
|
583
|
-
if (!visualLine)
|
|
584
|
-
return { handled: true, focus: true };
|
|
585
|
-
const logicalLine = this.state.lines[visualLine.logicalLine] ?? "";
|
|
586
|
-
const chunkEnd = visualLine.startCol + visualLine.length;
|
|
587
|
-
const chunk = logicalLine.slice(visualLine.startCol, chunkEnd);
|
|
588
|
-
const maxPadding = Math.max(0, Math.floor((event.width - 1) / 2));
|
|
589
|
-
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
590
|
-
const targetColumn = Math.max(0, event.x - paddingX);
|
|
591
|
-
let visibleColumn = 0;
|
|
592
|
-
let targetIndex = chunk.length;
|
|
593
|
-
let lastGraphemeIndex = 0;
|
|
594
|
-
for (const grapheme of this.segment(chunk, "grapheme")) {
|
|
595
|
-
const nextColumn = visibleColumn + visibleWidth(grapheme.segment);
|
|
596
|
-
lastGraphemeIndex = grapheme.index;
|
|
597
|
-
if (targetColumn < nextColumn) {
|
|
598
|
-
targetIndex = grapheme.index;
|
|
599
|
-
break;
|
|
600
|
-
}
|
|
601
|
-
visibleColumn = nextColumn;
|
|
602
|
-
}
|
|
603
|
-
const isLastSegment = visualLineIndex === visualLines.length - 1 ||
|
|
604
|
-
visualLines[visualLineIndex + 1]?.logicalLine !== visualLine.logicalLine;
|
|
605
|
-
if (!isLastSegment && targetIndex === chunk.length && chunk.length > 0)
|
|
606
|
-
targetIndex = lastGraphemeIndex;
|
|
607
|
-
this.state.cursorLine = visualLine.logicalLine;
|
|
608
|
-
this.setCursorCol(visualLine.startCol + targetIndex);
|
|
609
|
-
this.lastAction = null;
|
|
610
|
-
this.exitHistoryBrowsing();
|
|
611
|
-
if (this.autocompleteState)
|
|
612
|
-
this.updateAutocomplete();
|
|
613
|
-
return { handled: true, focus: true };
|
|
614
|
-
}
|
|
615
548
|
handleInput(data) {
|
|
616
549
|
data = normalizeWarpWslShiftEnterInput(data, this.terminalEnvironment, this.terminalPlatform, this.terminalSocketExists);
|
|
617
550
|
const kb = getKeybindings();
|
|
@@ -2036,20 +1969,7 @@ export class Editor {
|
|
|
2036
1969
|
}
|
|
2037
1970
|
createAutocompleteList(prefix, items) {
|
|
2038
1971
|
const layout = prefix.startsWith("/") ? SLASH_COMMAND_SELECT_LIST_LAYOUT : undefined;
|
|
2039
|
-
|
|
2040
|
-
list.onSelect = (selected) => {
|
|
2041
|
-
if (!this.autocompleteProvider)
|
|
2042
|
-
return;
|
|
2043
|
-
this.pushUndoSnapshot();
|
|
2044
|
-
this.lastAction = null;
|
|
2045
|
-
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
2046
|
-
this.state.lines = result.lines;
|
|
2047
|
-
this.state.cursorLine = result.cursorLine;
|
|
2048
|
-
this.setCursorCol(result.cursorCol);
|
|
2049
|
-
this.cancelAutocomplete();
|
|
2050
|
-
this.onChange?.(this.getText());
|
|
2051
|
-
};
|
|
2052
|
-
return list;
|
|
1972
|
+
return new SelectList(items, this.autocompleteMaxVisible, this.theme.selectList, layout);
|
|
2053
1973
|
}
|
|
2054
1974
|
tryTriggerAutocomplete(explicitTab = false) {
|
|
2055
1975
|
this.requestAutocomplete({ force: false, explicitTab });
|