@code-yeongyu/senpi 2026.6.10 → 2026.6.13
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 +68 -1
- package/README.md +21 -21
- 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/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -2
- package/dist/core/agent-session.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/builtin/compaction/degradation-monitor.d.ts +0 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.js +0 -1
- package/dist/core/extensions/builtin/compaction/degradation-monitor.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +4 -4
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.d.ts +0 -5
- package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.js +0 -4
- package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +0 -6
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +0 -3
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +10 -2
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/cli.d.ts +0 -3
- package/dist/core/extensions/builtin/permission-system/cli.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/cli.js +0 -13
- package/dist/core/extensions/builtin/permission-system/cli.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +10 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +12 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.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-registry.d.ts +0 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +3 -3
- package/dist/core/model-registry.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 +43 -6
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/project-trust.js +2 -2
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +0 -4
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +0 -15
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +11 -2
- package/dist/core/session-manager.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/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +0 -7
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/index.d.ts +0 -5
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +0 -67
- package/dist/core/tools/index.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/core/trust-manager.d.ts +8 -3
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +26 -11
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/aborted-error-label.d.ts +2 -0
- package/dist/modes/interactive/aborted-error-label.d.ts.map +1 -0
- package/dist/modes/interactive/aborted-error-label.js +8 -0
- package/dist/modes/interactive/aborted-error-label.js.map +1 -0
- 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/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +4 -4
- package/dist/modes/interactive/components/trust-selector.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 +18 -18
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +0 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +0 -7
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/event-output-buffer.d.ts +10 -0
- package/dist/modes/rpc/event-output-buffer.d.ts.map +1 -0
- package/dist/modes/rpc/event-output-buffer.js +27 -0
- package/dist/modes/rpc/event-output-buffer.js.map +1 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js +9 -11
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +17 -7
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +10 -3
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +14 -0
- package/dist/utils/shell.js.map +1 -1
- package/docs/compaction-guide.md +9 -9
- package/docs/compaction.md +2 -2
- package/docs/containerization.md +22 -22
- package/docs/custom-provider.md +13 -13
- package/docs/development.md +4 -2
- package/docs/extensions.md +18 -19
- package/docs/index.md +4 -4
- package/docs/json.md +21 -15
- package/docs/keybindings.md +6 -3
- package/docs/models.md +6 -6
- package/docs/packages.md +11 -11
- package/docs/prompt-templates.md +2 -2
- package/docs/providers.md +9 -9
- package/docs/rpc.md +14 -13
- package/docs/sdk.md +13 -9
- package/docs/security.md +14 -10
- package/docs/session-format.md +4 -4
- package/docs/sessions.md +14 -14
- package/docs/settings.md +14 -12
- package/docs/skills.md +8 -8
- package/docs/terminal-setup.md +2 -2
- package/docs/termux.md +3 -3
- package/docs/tui.md +4 -4
- package/docs/usage.md +52 -59
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-agent-core/README.md +4 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +0 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js +0 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +7 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/README.md +2 -4
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.js +0 -3
- package/node_modules/@earendil-works/pi-ai/dist/api-registry.js.map +1 -1
- 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 +252 -470
- 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 +533 -740
- 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/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +29 -16
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts +0 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js +0 -13
- package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts +0 -6
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +0 -14
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.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 +59 -19
- package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -5
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -8
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +1 -2
- 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 +93 -9
- 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 +3 -1
- 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 +89 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +15 -8
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +4 -7
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +72 -16
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -4
- 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 -7
- 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 +5 -5
- package/dist/core/experimental.d.ts +0 -2
- package/dist/core/experimental.d.ts.map +0 -1
- package/dist/core/experimental.js +0 -4
- package/dist/core/experimental.js.map +0 -1
- package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts +0 -11
- package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts.map +0 -1
- package/dist/core/extensions/builtin/compaction/overflow-detection.js +0 -40
- package/dist/core/extensions/builtin/compaction/overflow-detection.js.map +0 -1
- package/dist/core/extensions/builtin/system-messages.d.ts +0 -47
- package/dist/core/extensions/builtin/system-messages.d.ts.map +0 -1
- package/dist/core/extensions/builtin/system-messages.js +0 -117
- package/dist/core/extensions/builtin/system-messages.js.map +0 -1
- package/dist/core/index.d.ts +0 -13
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -13
- package/dist/core/index.js.map +0 -1
|
@@ -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 = [];
|
|
220
276
|
this.disableSubmit = false;
|
|
221
277
|
this.tui = tui;
|
|
222
278
|
this.theme = theme;
|
|
@@ -335,7 +391,33 @@ export class Editor {
|
|
|
335
391
|
}
|
|
336
392
|
}
|
|
337
393
|
invalidate() {
|
|
338
|
-
|
|
394
|
+
this.wrappedLineCache.length = 0;
|
|
395
|
+
}
|
|
396
|
+
getWrappedLine(lineIndex, contentWidth) {
|
|
397
|
+
const line = this.state.lines[lineIndex] || "";
|
|
398
|
+
const cached = this.wrappedLineCache[lineIndex];
|
|
399
|
+
if (cached && cached.lineRef === line && cached.contentWidth === contentWidth) {
|
|
400
|
+
return cached;
|
|
401
|
+
}
|
|
402
|
+
const width = isPrintableAsciiText(line) ? line.length : visibleWidth(line);
|
|
403
|
+
if (line.includes("[paste #")) {
|
|
404
|
+
return {
|
|
405
|
+
width,
|
|
406
|
+
chunks: width <= contentWidth
|
|
407
|
+
? [{ text: line, startIndex: 0, endIndex: line.length }]
|
|
408
|
+
: wordWrapLine(line, contentWidth, [...this.segment(line, "grapheme")]),
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
const wrapped = {
|
|
412
|
+
lineRef: line,
|
|
413
|
+
contentWidth,
|
|
414
|
+
width,
|
|
415
|
+
chunks: width <= contentWidth
|
|
416
|
+
? [{ text: line, startIndex: 0, endIndex: line.length }]
|
|
417
|
+
: wordWrapLine(line, contentWidth),
|
|
418
|
+
};
|
|
419
|
+
this.wrappedLineCache[lineIndex] = wrapped;
|
|
420
|
+
return wrapped;
|
|
339
421
|
}
|
|
340
422
|
render(width) {
|
|
341
423
|
const maxPadding = Math.max(0, Math.floor((width - 1) / 2));
|
|
@@ -706,6 +788,7 @@ export class Editor {
|
|
|
706
788
|
const layoutLines = [];
|
|
707
789
|
if (this.state.lines.length === 0 || (this.state.lines.length === 1 && this.state.lines[0] === "")) {
|
|
708
790
|
// Empty editor
|
|
791
|
+
this.wrappedLineCache.length = this.state.lines.length;
|
|
709
792
|
layoutLines.push({
|
|
710
793
|
text: "",
|
|
711
794
|
hasCursor: true,
|
|
@@ -717,8 +800,8 @@ export class Editor {
|
|
|
717
800
|
for (let i = 0; i < this.state.lines.length; i++) {
|
|
718
801
|
const line = this.state.lines[i] || "";
|
|
719
802
|
const isCurrentLine = i === this.state.cursorLine;
|
|
720
|
-
const
|
|
721
|
-
if (
|
|
803
|
+
const wrappedLine = this.getWrappedLine(i, contentWidth);
|
|
804
|
+
if (wrappedLine.width <= contentWidth) {
|
|
722
805
|
// Line fits in one layout line
|
|
723
806
|
if (isCurrentLine) {
|
|
724
807
|
layoutLines.push({
|
|
@@ -736,7 +819,7 @@ export class Editor {
|
|
|
736
819
|
}
|
|
737
820
|
else {
|
|
738
821
|
// Line needs wrapping - use word-aware wrapping
|
|
739
|
-
const chunks =
|
|
822
|
+
const chunks = wrappedLine.chunks;
|
|
740
823
|
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
741
824
|
const chunk = chunks[chunkIndex];
|
|
742
825
|
if (!chunk)
|
|
@@ -783,6 +866,7 @@ export class Editor {
|
|
|
783
866
|
}
|
|
784
867
|
}
|
|
785
868
|
}
|
|
869
|
+
this.wrappedLineCache.length = this.state.lines.length;
|
|
786
870
|
return layoutLines;
|
|
787
871
|
}
|
|
788
872
|
getText() {
|
|
@@ -1408,7 +1492,7 @@ export class Editor {
|
|
|
1408
1492
|
}
|
|
1409
1493
|
else {
|
|
1410
1494
|
// Line needs wrapping - use word-aware wrapping
|
|
1411
|
-
const chunks =
|
|
1495
|
+
const chunks = this.getWrappedLine(i, width).chunks;
|
|
1412
1496
|
for (const chunk of chunks) {
|
|
1413
1497
|
visualLines.push({
|
|
1414
1498
|
logicalLine: i,
|