@code-yeongyu/senpi 2026.6.10-2 → 2026.6.12-2
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/CHANGELOG.md +22 -0
- package/dist/cli/startup-ui.d.ts +10 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +72 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +31 -7
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +20 -5
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +3 -5
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +38 -34
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/tail-window.d.ts +15 -0
- package/dist/core/tools/tail-window.d.ts.map +1 -0
- package/dist/core/tools/tail-window.js +75 -0
- package/dist/core/tools/tail-window.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +8 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.js +101 -0
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +45 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +12 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/settings.md +2 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +92 -227
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +140 -247
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +12 -5
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts +4 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js +54 -8
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +80 -7
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +72 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-stream.js","sourceRoot":"","sources":["../../src/utils/event-stream.ts"],"names":[],"mappings":"AAEA,iDAAiD;AACjD,MAAM,OAAO,WAAW;
|
|
1
|
+
{"version":3,"file":"event-stream.js","sourceRoot":"","sources":["../../src/utils/event-stream.ts"],"names":[],"mappings":"AAEA,iDAAiD;AACjD,MAAM,OAAO,WAAW;IACvB,MAAM,CAAW;IACjB,UAAU,CAAK;IAGf,OAAO,CAAS;IAChB,MAAM,CAAU;IAOhB,YAAY,UAAiC,EAAE,aAA8B;QAZ7E,WAAM,GAAQ,EAAE,CAAC;QACjB,eAAU,GAAG,CAAC,CAAC;QACP,YAAO,GAA6F,EAAE,CAAC;QACvG,SAAI,GAAG,KAAK,CAAC;QACrB,YAAO,GAAG,KAAK,CAAC;QASf,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,kBAAkB,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACzD,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC;YAClC,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,QAAQ,CAAC,KAAQ;QAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,QAAQ;QACP,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACzE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACjD,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,YAAY;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,KAAQ;QACZ,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QAEtB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,0CAA0C;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACF,CAAC;IAED,GAAG,CAAC,MAAU;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QACD,+CAA+C;QAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,MAAM;gBAAE,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC;IAED,IAAI,CAAC,KAAc;QAClB,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,MAAM;gBAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC5B,OAAO,IAAI,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,CAAC;iBAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACzB,MAAM,IAAI,CAAC,MAAM,CAAC;YACnB,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACtB,OAAO;YACR,CAAC;iBAAM,CAAC;gBACP,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CACtC,CAAC;gBACF,IAAI,MAAM,CAAC,IAAI;oBAAE,OAAO;gBACxB,MAAM,MAAM,CAAC,KAAK,CAAC;YACpB,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAC,kBAAkB,CAAC;IAChC,CAAC;CACD;AAED,MAAM,OAAO,2BAA4B,SAAQ,WAAoD;IACpG;QACC,KAAK,CACJ,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAC1D,CAAC,KAAK,EAAE,EAAE;YACT,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;YACtB,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACnC,OAAO,KAAK,CAAC,KAAK,CAAC;YACpB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC3D,CAAC,CACD,CAAC;IACH,CAAC;CACD;AAED,+EAA+E;AAC/E,MAAM,UAAU,iCAAiC;IAChD,OAAO,IAAI,2BAA2B,EAAE,CAAC;AAC1C,CAAC","sourcesContent":["import type { AssistantMessage, AssistantMessageEvent } from \"../types.ts\";\n\n// Generic event stream class for async iteration\nexport class EventStream<T, R = T> implements AsyncIterable<T> {\n\t#queue: T[] = [];\n\t#queueHead = 0;\n\tprivate waiting: Array<{ resolve: (value: IteratorResult<T>) => void; reject: (error: unknown) => void }> = [];\n\tprivate done = false;\n\t#failed = false;\n\t#error: unknown;\n\tprivate finalResultPromise: Promise<R>;\n\tprivate resolveFinalResult!: (result: R) => void;\n\tprivate rejectFinalResult!: (error: unknown) => void;\n\tprivate isComplete: (event: T) => boolean;\n\tprivate extractResult: (event: T) => R;\n\n\tconstructor(isComplete: (event: T) => boolean, extractResult: (event: T) => R) {\n\t\tthis.isComplete = isComplete;\n\t\tthis.extractResult = extractResult;\n\t\tthis.finalResultPromise = new Promise((resolve, reject) => {\n\t\t\tthis.resolveFinalResult = resolve;\n\t\t\tthis.rejectFinalResult = reject;\n\t\t});\n\t\tthis.finalResultPromise.catch(() => {});\n\t}\n\n\tget queue(): T[] {\n\t\treturn this.#queue.slice(this.#queueHead);\n\t}\n\n\t#enqueue(event: T): void {\n\t\tthis.#queue.push(event);\n\t}\n\n\t#dequeue(): T {\n\t\tconst event = this.#queue[this.#queueHead];\n\t\tif (event === undefined) {\n\t\t\tthrow new Error(\"EventStream queue underflow\");\n\t\t}\n\t\tthis.#queueHead++;\n\t\tif (this.#queueHead > 1024 && this.#queueHead * 2 >= this.#queue.length) {\n\t\t\tthis.#queue = this.#queue.slice(this.#queueHead);\n\t\t\tthis.#queueHead = 0;\n\t\t}\n\t\treturn event;\n\t}\n\n\tget #queueLength(): number {\n\t\treturn this.#queue.length - this.#queueHead;\n\t}\n\n\tpush(event: T): void {\n\t\tif (this.done) return;\n\n\t\tif (this.isComplete(event)) {\n\t\t\tthis.done = true;\n\t\t\tthis.resolveFinalResult(this.extractResult(event));\n\t\t}\n\n\t\t// Deliver to waiting consumer or queue it\n\t\tconst waiter = this.waiting.shift();\n\t\tif (waiter) {\n\t\t\twaiter.resolve({ value: event, done: false });\n\t\t} else {\n\t\t\tthis.#enqueue(event);\n\t\t}\n\t}\n\n\tend(result?: R): void {\n\t\tthis.done = true;\n\t\tif (result !== undefined) {\n\t\t\tthis.resolveFinalResult(result);\n\t\t}\n\t\t// Notify all waiting consumers that we're done\n\t\twhile (this.waiting.length > 0) {\n\t\t\tconst waiter = this.waiting.shift();\n\t\t\tif (waiter) waiter.resolve({ value: undefined, done: true });\n\t\t}\n\t}\n\n\tfail(error: unknown): void {\n\t\tif (this.done) return;\n\t\tthis.done = true;\n\t\tthis.#failed = true;\n\t\tthis.#error = error;\n\t\tthis.rejectFinalResult(error);\n\t\twhile (this.waiting.length > 0) {\n\t\t\tconst waiter = this.waiting.shift();\n\t\t\tif (waiter) waiter.reject(error);\n\t\t}\n\t}\n\n\tasync *[Symbol.asyncIterator](): AsyncIterator<T> {\n\t\twhile (true) {\n\t\t\tif (this.#queueLength > 0) {\n\t\t\t\tyield this.#dequeue();\n\t\t\t} else if (this.#failed) {\n\t\t\t\tthrow this.#error;\n\t\t\t} else if (this.done) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst result = await new Promise<IteratorResult<T>>((resolve, reject) =>\n\t\t\t\t\tthis.waiting.push({ resolve, reject }),\n\t\t\t\t);\n\t\t\t\tif (result.done) return;\n\t\t\t\tyield result.value;\n\t\t\t}\n\t\t}\n\t}\n\n\tresult(): Promise<R> {\n\t\treturn this.finalResultPromise;\n\t}\n}\n\nexport class AssistantMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> {\n\tconstructor() {\n\t\tsuper(\n\t\t\t(event) => event.type === \"done\" || event.type === \"error\",\n\t\t\t(event) => {\n\t\t\t\tif (event.type === \"done\") {\n\t\t\t\t\treturn event.message;\n\t\t\t\t} else if (event.type === \"error\") {\n\t\t\t\t\treturn event.error;\n\t\t\t\t}\n\t\t\t\tthrow new Error(\"Unexpected event type for final result\");\n\t\t\t},\n\t\t);\n\t}\n}\n\n/** Factory function for AssistantMessageEventStream (for use in extensions) */\nexport function createAssistantMessageEventStream(): AssistantMessageEventStream {\n\treturn new AssistantMessageEventStream();\n}\n"]}
|
|
@@ -66,6 +66,7 @@ export declare class Editor implements Component, Focusable {
|
|
|
66
66
|
private preferredVisualCol;
|
|
67
67
|
private snappedFromCursorCol;
|
|
68
68
|
private undoStack;
|
|
69
|
+
private wrappedLineCache;
|
|
69
70
|
onSubmit?: (text: string) => void;
|
|
70
71
|
onChange?: (text: string) => void;
|
|
71
72
|
disableSubmit: boolean;
|
|
@@ -91,6 +92,7 @@ export declare class Editor implements Component, Focusable {
|
|
|
91
92
|
/** Internal setText that doesn't reset history state - used by navigateHistory */
|
|
92
93
|
private setTextInternal;
|
|
93
94
|
invalidate(): void;
|
|
95
|
+
private getWrappedLineChunks;
|
|
94
96
|
render(width: number): string[];
|
|
95
97
|
handleInput(data: string): void;
|
|
96
98
|
private layoutText;
|
|
@@ -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;AAIxF,OAAO,EAAE,KAAK,SAAS,EAAiB,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/components/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { decodePrintableKey, matchesKey } from "../keys.js";
|
|
|
3
3
|
import { KillRing } from "../kill-ring.js";
|
|
4
4
|
import { CURSOR_MARKER } from "../tui.js";
|
|
5
5
|
import { UndoStack } from "../undo-stack.js";
|
|
6
|
-
import { getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, truncateToWidth, visibleWidth } from "../utils.js";
|
|
6
|
+
import { cjkBreakRegex, getGraphemeSegmenter, getWordSegmenter, isWhitespaceChar, truncateToWidth, visibleWidth, } from "../utils.js";
|
|
7
7
|
import { findWordBackward, findWordForward } from "../word-navigation.js";
|
|
8
8
|
import { SelectList } from "./select-list.js";
|
|
9
9
|
const graphemeSegmenter = getGraphemeSegmenter();
|
|
@@ -68,6 +68,49 @@ function segmentWithMarkers(text, baseSegmenter, validIds) {
|
|
|
68
68
|
}
|
|
69
69
|
return result;
|
|
70
70
|
}
|
|
71
|
+
function isPrintableAsciiText(text) {
|
|
72
|
+
for (let i = 0; i < text.length; i++) {
|
|
73
|
+
const code = text.charCodeAt(i);
|
|
74
|
+
if (code < 0x20 || code > 0x7e)
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
function wordWrapAsciiLine(line, maxWidth) {
|
|
80
|
+
if (line.length <= maxWidth) {
|
|
81
|
+
return [{ text: line, startIndex: 0, endIndex: line.length }];
|
|
82
|
+
}
|
|
83
|
+
const chunks = [];
|
|
84
|
+
let chunkStart = 0;
|
|
85
|
+
while (chunkStart < line.length) {
|
|
86
|
+
let chunkEnd = Math.min(line.length, chunkStart + maxWidth);
|
|
87
|
+
if (chunkEnd < line.length) {
|
|
88
|
+
let breakAt = -1;
|
|
89
|
+
for (let i = chunkEnd; i > chunkStart; i--) {
|
|
90
|
+
const code = line.charCodeAt(i - 1);
|
|
91
|
+
if (code === 0x20 || code === 0x09) {
|
|
92
|
+
breakAt = i - 1;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (breakAt > chunkStart)
|
|
97
|
+
chunkEnd = breakAt;
|
|
98
|
+
}
|
|
99
|
+
const raw = line.slice(chunkStart, chunkEnd);
|
|
100
|
+
const text = raw.trimEnd();
|
|
101
|
+
if (text || chunks.length === 0) {
|
|
102
|
+
chunks.push({ text, startIndex: chunkStart, endIndex: chunkStart + raw.length });
|
|
103
|
+
}
|
|
104
|
+
chunkStart = chunkEnd;
|
|
105
|
+
while (chunkStart < line.length) {
|
|
106
|
+
const code = line.charCodeAt(chunkStart);
|
|
107
|
+
if (code !== 0x20 && code !== 0x09)
|
|
108
|
+
break;
|
|
109
|
+
chunkStart++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return chunks.length > 0 ? chunks : [{ text: "", startIndex: 0, endIndex: 0 }];
|
|
113
|
+
}
|
|
71
114
|
/**
|
|
72
115
|
* Split a line into word-wrapped chunks.
|
|
73
116
|
* Wraps at word boundaries when possible, falling back to character-level
|
|
@@ -83,6 +126,9 @@ export function wordWrapLine(line, maxWidth, preSegmented) {
|
|
|
83
126
|
if (!line || maxWidth <= 0) {
|
|
84
127
|
return [{ text: "", startIndex: 0, endIndex: 0 }];
|
|
85
128
|
}
|
|
129
|
+
if (preSegmented === undefined && !/\s/.test(line) && !line.includes("[paste #") && isPrintableAsciiText(line)) {
|
|
130
|
+
return wordWrapAsciiLine(line, maxWidth);
|
|
131
|
+
}
|
|
86
132
|
const lineWidth = visibleWidth(line);
|
|
87
133
|
if (lineWidth <= maxWidth) {
|
|
88
134
|
return [{ text: line, startIndex: 0, endIndex: line.length }];
|
|
@@ -140,14 +186,23 @@ export function wordWrapLine(line, maxWidth, preSegmented) {
|
|
|
140
186
|
}
|
|
141
187
|
// Advance.
|
|
142
188
|
currentWidth += gWidth;
|
|
143
|
-
// Record wrap opportunity: whitespace followed by non-whitespace
|
|
144
|
-
//
|
|
145
|
-
//
|
|
189
|
+
// Record wrap opportunity: whitespace followed by non-whitespace
|
|
190
|
+
// (multiple spaces join; the break point is after the last space),
|
|
191
|
+
// or at a boundary where either side is CJK (CJK allows breaking
|
|
192
|
+
// between any adjacent characters).
|
|
146
193
|
const next = segments[i + 1];
|
|
147
194
|
if (isWs && next && (isPasteMarker(next.segment) || !isWhitespaceChar(next.segment))) {
|
|
148
195
|
wrapOppIndex = next.index;
|
|
149
196
|
wrapOppWidth = currentWidth;
|
|
150
197
|
}
|
|
198
|
+
else if (!isWs && next && !isWhitespaceChar(next.segment)) {
|
|
199
|
+
const isCjk = !isPasteMarker(grapheme) && cjkBreakRegex.test(grapheme);
|
|
200
|
+
const nextIsCjk = !isPasteMarker(next.segment) && cjkBreakRegex.test(next.segment);
|
|
201
|
+
if (isCjk || nextIsCjk) {
|
|
202
|
+
wrapOppIndex = next.index;
|
|
203
|
+
wrapOppWidth = currentWidth;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
151
206
|
}
|
|
152
207
|
// Push final chunk.
|
|
153
208
|
chunks.push({ text: line.slice(chunkStart), startIndex: chunkStart, endIndex: line.length });
|
|
@@ -217,6 +272,7 @@ export class Editor {
|
|
|
217
272
|
this.snappedFromCursorCol = null;
|
|
218
273
|
// Undo support
|
|
219
274
|
this.undoStack = new UndoStack();
|
|
275
|
+
this.wrappedLineCache = new Map();
|
|
220
276
|
this.disableSubmit = false;
|
|
221
277
|
this.tui = tui;
|
|
222
278
|
this.theme = theme;
|
|
@@ -335,7 +391,24 @@ export class Editor {
|
|
|
335
391
|
}
|
|
336
392
|
}
|
|
337
393
|
invalidate() {
|
|
338
|
-
|
|
394
|
+
this.wrappedLineCache.clear();
|
|
395
|
+
}
|
|
396
|
+
getWrappedLineChunks(line, contentWidth) {
|
|
397
|
+
if (line.includes("[paste #")) {
|
|
398
|
+
return wordWrapLine(line, contentWidth, [...this.segment(line, "grapheme")]);
|
|
399
|
+
}
|
|
400
|
+
const key = `${contentWidth}\x00${line}`;
|
|
401
|
+
const cached = this.wrappedLineCache.get(key);
|
|
402
|
+
if (cached)
|
|
403
|
+
return cached;
|
|
404
|
+
const chunks = wordWrapLine(line, contentWidth);
|
|
405
|
+
if (this.wrappedLineCache.size >= 256) {
|
|
406
|
+
const oldest = this.wrappedLineCache.keys().next().value;
|
|
407
|
+
if (oldest !== undefined)
|
|
408
|
+
this.wrappedLineCache.delete(oldest);
|
|
409
|
+
}
|
|
410
|
+
this.wrappedLineCache.set(key, chunks);
|
|
411
|
+
return chunks;
|
|
339
412
|
}
|
|
340
413
|
render(width) {
|
|
341
414
|
const maxPadding = Math.max(0, Math.floor((width - 1) / 2));
|
|
@@ -736,7 +809,7 @@ export class Editor {
|
|
|
736
809
|
}
|
|
737
810
|
else {
|
|
738
811
|
// Line needs wrapping - use word-aware wrapping
|
|
739
|
-
const chunks =
|
|
812
|
+
const chunks = this.getWrappedLineChunks(line, contentWidth);
|
|
740
813
|
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
741
814
|
const chunk = chunks[chunkIndex];
|
|
742
815
|
if (!chunk)
|
|
@@ -1408,7 +1481,7 @@ export class Editor {
|
|
|
1408
1481
|
}
|
|
1409
1482
|
else {
|
|
1410
1483
|
// Line needs wrapping - use word-aware wrapping
|
|
1411
|
-
const chunks =
|
|
1484
|
+
const chunks = this.getWrappedLineChunks(line, width);
|
|
1412
1485
|
for (const chunk of chunks) {
|
|
1413
1486
|
visualLines.push({
|
|
1414
1487
|
logicalLine: i,
|