@linxiraos/pi-tui 1.1.27 → 1.2.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/CHANGELOG.md +47 -463
- package/README.md +7 -5
- package/dist/types/app-keybindings.d.ts +1 -1
- package/dist/types/apps/cleanse-board.d.ts +1 -1
- package/dist/types/apps/debug/log-viewer.d.ts +4 -0
- package/dist/types/apps/debug/raw-sse-buffer.d.ts +2 -0
- package/dist/types/apps/git/git-tui.d.ts +2 -2
- package/dist/types/apps/git/help.d.ts +3 -1
- package/dist/types/apps/if-bench-board.d.ts +2 -2
- package/dist/types/apps/setup-model-picker.d.ts +1 -1
- package/dist/types/autocomplete.d.ts +5 -2
- package/dist/types/charts/chart-plan.d.ts +674 -0
- package/dist/types/charts/chart-svg.d.ts +59 -0
- package/dist/types/charts/table-data.d.ts +175 -0
- package/dist/types/chat/assistant-message.d.ts +5 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +2 -0
- package/dist/types/chat/compaction-summary-message.d.ts +1 -0
- package/dist/types/chat/execution-shared.d.ts +6 -5
- package/dist/types/chat/fence-figure.d.ts +42 -0
- package/dist/types/chat/figure-markdown.d.ts +42 -0
- package/dist/types/chat/messages.d.ts +1 -1
- package/dist/types/chat/svg-figure.d.ts +33 -0
- package/dist/types/chat/svg-source.d.ts +49 -0
- package/dist/types/chat/table-chart.d.ts +89 -0
- package/dist/types/chat/tool-execution.d.ts +2 -0
- package/dist/types/chat/user-message.d.ts +15 -2
- package/dist/types/chrome/shared.d.ts +9 -0
- package/dist/types/chrome/transcript-container.d.ts +6 -0
- package/dist/types/components/box.d.ts +1 -0
- package/dist/types/components/disclosure.d.ts +1 -0
- package/dist/types/components/editor.d.ts +15 -4
- package/dist/types/components/form.d.ts +1 -0
- package/dist/types/components/image.d.ts +12 -44
- package/dist/types/components/key-value-list.d.ts +1 -0
- package/dist/types/components/layout/row.d.ts +1 -0
- package/dist/types/components/layout/stack.d.ts +1 -0
- package/dist/types/components/markdown.d.ts +36 -3
- package/dist/types/components/scroll-view.d.ts +1 -0
- package/dist/types/components/section.d.ts +1 -0
- package/dist/types/components/table.d.ts +1 -0
- package/dist/types/components/text.d.ts +1 -0
- package/dist/types/components/tree-view.d.ts +7 -0
- package/dist/types/components/truncated-text.d.ts +1 -0
- package/dist/types/fuzzy.d.ts +29 -1
- package/dist/types/key-hint-format.d.ts +1 -1
- package/dist/types/keybinding-matchers.d.ts +3 -0
- package/dist/types/keybindings.d.ts +1 -1
- package/dist/types/kitty-graphics.d.ts +2 -2
- package/dist/types/loop-watchdog.d.ts +8 -7
- package/dist/types/multiplexers/cmux.d.ts +16 -0
- package/dist/types/multiplexers/herdr.d.ts +26 -0
- package/dist/types/multiplexers/notify.d.ts +13 -0
- package/dist/types/multiplexers/orca.d.ts +12 -0
- package/dist/types/multiplexers/screen.d.ts +9 -0
- package/dist/types/multiplexers/tmux.d.ts +29 -0
- package/dist/types/multiplexers/types.d.ts +100 -0
- package/dist/types/multiplexers/wmux.d.ts +12 -0
- package/dist/types/multiplexers/zellij.d.ts +12 -0
- package/dist/types/native/backend.d.ts +3 -2
- package/dist/types/native/blobs.d.ts +7 -3
- package/dist/types/native/encode.d.ts +3 -4
- package/dist/types/native/overlay.d.ts +5 -0
- package/dist/types/overlays/agent-hub-projection.d.ts +6 -5
- package/dist/types/overlays/agent-hub-types.d.ts +9 -0
- package/dist/types/overlays/agent-hub.d.ts +2 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +11 -2
- package/dist/types/overlays/agents-hub.d.ts +9 -0
- package/dist/types/overlays/annotation-overlay.d.ts +19 -2
- package/dist/types/overlays/annotation-types.d.ts +2 -0
- package/dist/types/overlays/ask-dialog.d.ts +5 -2
- package/dist/types/overlays/history-search.d.ts +10 -0
- package/dist/types/overlays/hook-selector.d.ts +9 -4
- package/dist/types/overlays/jobs-panel.d.ts +1 -7
- package/dist/types/overlays/model-browser.d.ts +54 -7
- package/dist/types/overlays/model-hub.d.ts +23 -0
- package/dist/types/overlays/oauth-selector.d.ts +0 -1
- package/dist/types/overlays/plan-review-overlay.d.ts +3 -2
- package/dist/types/overlays/session-observer-registry.d.ts +2 -0
- package/dist/types/overlays/session-selector.d.ts +6 -2
- package/dist/types/overlays/settings-defs.d.ts +1 -0
- package/dist/types/overlays/usage-dashboard.d.ts +8 -4
- package/dist/types/overlays/usage-display.d.ts +3 -1
- package/dist/types/prompt/composer.d.ts +1 -1
- package/dist/types/prompt/custom-editor.d.ts +11 -8
- package/dist/types/prompt/image-source.d.ts +2 -1
- package/dist/types/prompt/interactive-context-helpers.d.ts +4 -1
- package/dist/types/prompt/model-mention-autocomplete.d.ts +1 -1
- package/dist/types/prompt/welcome.d.ts +6 -1
- package/dist/types/render/composite.d.ts +2 -0
- package/dist/types/render/output-pane.d.ts +1 -0
- package/dist/types/render/render-utils.d.ts +1 -0
- package/dist/types/render/tool-card.d.ts +6 -0
- package/dist/types/render/width-aware-text.d.ts +2 -0
- package/dist/types/setup/scenes/types.d.ts +1 -0
- package/dist/types/status-line/component.d.ts +3 -0
- package/dist/types/status-line/host.d.ts +4 -1
- package/dist/types/status-line/segments.d.ts +2 -0
- package/dist/types/status-line/types.d.ts +14 -3
- package/dist/types/terminal-capabilities.d.ts +27 -35
- package/dist/types/terminal-multiplexer.d.ts +127 -14
- package/dist/types/terminal.d.ts +22 -6
- package/dist/types/theme/active-symbols.d.ts +1 -1
- package/dist/types/theme/schema.d.ts +11 -2
- package/dist/types/theme/symbols.d.ts +1 -1
- package/dist/types/theme/theme-class.d.ts +7 -0
- package/dist/types/theme/theme.d.ts +1 -1
- package/dist/types/theme/tui-adapters.d.ts +3 -0
- package/dist/types/tmux.d.ts +11 -4
- package/dist/types/tools/daemon.d.ts +1 -1
- package/dist/types/tools/eval.d.ts +22 -3
- package/dist/types/tools/glob.d.ts +4 -0
- package/dist/types/tools/native-view.d.ts +47 -0
- package/dist/types/tools/output-meta.d.ts +11 -1
- package/dist/types/tools/renderer.d.ts +37 -2
- package/dist/types/tools/streaming-output.d.ts +20 -1
- package/dist/types/tools/task.d.ts +0 -4
- package/dist/types/tools/write.d.ts +9 -2
- package/dist/types/tools/yield.d.ts +22 -0
- package/dist/types/tui.d.ts +31 -0
- package/dist/types/utils.d.ts +6 -0
- package/dist/types/vim.d.ts +19 -5
- package/package.json +13 -9
- package/src/app-keybindings.d.ts +1 -1
- package/src/app-keybindings.ts +1 -1
- package/src/apps/autoresearch-dashboard.ts +7 -3
- package/src/apps/cleanse-board.ts +2 -2
- package/src/apps/cleanse-picker.ts +1 -1
- package/src/apps/debug/log-viewer.ts +188 -72
- package/src/apps/debug/raw-sse-buffer.ts +8 -0
- package/src/apps/debug/raw-sse.ts +39 -5
- package/src/apps/git/diff-pane.ts +26 -5
- package/src/apps/git/git-tui.ts +2 -2
- package/src/apps/git/help.ts +29 -20
- package/src/apps/if-bench-board.ts +2 -2
- package/src/apps/ps-top.ts +2 -2
- package/src/apps/setup-model-picker.ts +1 -1
- package/src/autocomplete.d.ts +5 -2
- package/src/autocomplete.ts +67 -43
- package/src/charts/chart-plan.d.ts +674 -0
- package/src/charts/chart-plan.ts +5081 -0
- package/src/charts/chart-svg.d.ts +59 -0
- package/src/charts/chart-svg.ts +4657 -0
- package/src/charts/table-data.d.ts +175 -0
- package/src/charts/table-data.ts +1478 -0
- package/src/chat/advisor-message.ts +11 -0
- package/src/chat/assistant-message.d.ts +5 -0
- package/src/chat/assistant-message.ts +219 -50
- package/src/chat/chat-transcript-builder.d.ts +2 -0
- package/src/chat/chat-transcript-builder.ts +5 -3
- package/src/chat/compaction-summary-message.d.ts +1 -0
- package/src/chat/compaction-summary-message.ts +8 -0
- package/src/chat/execution-shared.d.ts +6 -5
- package/src/chat/execution-shared.ts +42 -25
- package/src/chat/fence-figure.d.ts +42 -0
- package/src/chat/fence-figure.ts +80 -0
- package/src/chat/figure-markdown.d.ts +42 -0
- package/src/chat/figure-markdown.ts +174 -0
- package/src/chat/messages.d.ts +1 -1
- package/src/chat/messages.ts +1 -1
- package/src/chat/read-tool-group.ts +6 -4
- package/src/chat/skill-message.ts +6 -0
- package/src/chat/svg-figure.d.ts +33 -0
- package/src/chat/svg-figure.ts +399 -0
- package/src/chat/svg-source.d.ts +49 -0
- package/src/chat/svg-source.ts +188 -0
- package/src/chat/table-chart.d.ts +89 -0
- package/src/chat/table-chart.ts +294 -0
- package/src/chat/tool-execution.d.ts +2 -0
- package/src/chat/tool-execution.ts +80 -6
- package/src/chat/user-message.d.ts +15 -2
- package/src/chat/user-message.ts +55 -3
- package/src/chrome/shared.ts +53 -0
- package/src/chrome/transcript-container.d.ts +6 -0
- package/src/chrome/transcript-container.ts +93 -13
- package/src/components/box.d.ts +1 -0
- package/src/components/box.ts +5 -0
- package/src/components/disclosure.d.ts +1 -0
- package/src/components/disclosure.ts +8 -0
- package/src/components/editor.d.ts +15 -4
- package/src/components/editor.ts +294 -46
- package/src/components/form.d.ts +1 -0
- package/src/components/form.ts +8 -0
- package/src/components/image.d.ts +12 -44
- package/src/components/image.ts +47 -151
- package/src/components/key-value-list.d.ts +1 -0
- package/src/components/key-value-list.ts +4 -0
- package/src/components/layout/row.d.ts +1 -0
- package/src/components/layout/row.ts +7 -0
- package/src/components/layout/stack.d.ts +1 -0
- package/src/components/layout/stack.ts +7 -0
- package/src/components/markdown.d.ts +36 -3
- package/src/components/markdown.ts +433 -318
- package/src/components/scroll-view.d.ts +1 -0
- package/src/components/scroll-view.ts +5 -0
- package/src/components/section.d.ts +1 -0
- package/src/components/section.ts +5 -0
- package/src/components/settings-list.ts +2 -0
- package/src/components/table.d.ts +1 -0
- package/src/components/table.ts +4 -0
- package/src/components/text.d.ts +1 -0
- package/src/components/text.ts +7 -0
- package/src/components/tree-view.d.ts +7 -0
- package/src/components/tree-view.ts +38 -8
- package/src/components/truncated-text.d.ts +1 -0
- package/src/components/truncated-text.ts +5 -0
- package/src/desktop-notify.ts +1 -1
- package/src/fuzzy.d.ts +29 -1
- package/src/fuzzy.ts +115 -30
- package/src/key-hint-format.d.ts +1 -1
- package/src/key-hint-format.ts +1 -1
- package/src/keybinding-matchers.d.ts +3 -0
- package/src/keybinding-matchers.ts +6 -2
- package/src/keybindings.d.ts +1 -1
- package/src/keybindings.ts +1 -1
- package/src/kitty-graphics.d.ts +2 -2
- package/src/kitty-graphics.ts +4 -4
- package/src/loop-watchdog.d.ts +8 -7
- package/src/loop-watchdog.ts +18 -13
- package/src/multiplexers/cmux.d.ts +16 -0
- package/src/multiplexers/cmux.ts +29 -0
- package/src/multiplexers/herdr.d.ts +26 -0
- package/src/multiplexers/herdr.ts +64 -0
- package/src/multiplexers/notify.d.ts +13 -0
- package/src/multiplexers/notify.ts +24 -0
- package/src/multiplexers/orca.d.ts +12 -0
- package/src/multiplexers/orca.ts +16 -0
- package/src/multiplexers/screen.d.ts +9 -0
- package/src/multiplexers/screen.ts +15 -0
- package/src/multiplexers/tmux.d.ts +29 -0
- package/src/multiplexers/tmux.ts +40 -0
- package/src/multiplexers/types.d.ts +100 -0
- package/src/multiplexers/types.ts +110 -0
- package/src/multiplexers/wmux.d.ts +12 -0
- package/src/multiplexers/wmux.ts +16 -0
- package/src/multiplexers/zellij.d.ts +12 -0
- package/src/multiplexers/zellij.ts +24 -0
- package/src/native/backend.d.ts +3 -2
- package/src/native/backend.ts +174 -18
- package/src/native/blobs.d.ts +7 -3
- package/src/native/blobs.ts +47 -12
- package/src/native/encode.d.ts +3 -4
- package/src/native/encode.ts +58 -31
- package/src/native/overlay.d.ts +5 -0
- package/src/native/overlay.ts +13 -0
- package/src/native/reconcile.ts +4 -0
- package/src/overlays/agent-hub-projection.d.ts +6 -5
- package/src/overlays/agent-hub-projection.ts +124 -13
- package/src/overlays/agent-hub-types.d.ts +9 -0
- package/src/overlays/agent-hub-types.ts +6 -0
- package/src/overlays/agent-hub.ts +44 -29
- package/src/overlays/agent-transcript-viewer.ts +91 -23
- package/src/overlays/agents-hub.ts +28 -8
- package/src/overlays/annotation-overlay.ts +293 -90
- package/src/overlays/annotation-types.ts +2 -0
- package/src/overlays/ask-dialog.ts +7 -10
- package/src/overlays/btw-history-panel.ts +12 -1
- package/src/overlays/copy-selector.ts +30 -8
- package/src/overlays/extensions/state-manager.ts +52 -12
- package/src/overlays/history-search.ts +100 -7
- package/src/overlays/hook-selector.ts +12 -5
- package/src/overlays/jobs-panel.ts +28 -46
- package/src/overlays/model-browser.ts +341 -110
- package/src/overlays/model-hub.ts +300 -49
- package/src/overlays/move-overlay.ts +28 -14
- package/src/overlays/oauth-selector.ts +54 -70
- package/src/overlays/plan-review-overlay.ts +194 -70
- package/src/overlays/plugin-settings.ts +3 -3
- package/src/overlays/report-panel.ts +2 -2
- package/src/overlays/rewind-selector.ts +86 -17
- package/src/overlays/session-observer-registry.d.ts +2 -0
- package/src/overlays/session-observer-registry.ts +10 -2
- package/src/overlays/session-selector.ts +64 -26
- package/src/overlays/settings-defs.ts +4 -3
- package/src/overlays/settings-selector.ts +33 -8
- package/src/overlays/snapcompact-shape-preview.ts +2 -3
- package/src/overlays/stats-notice.ts +1 -1
- package/src/overlays/tree-selector.ts +41 -20
- package/src/overlays/usage-dashboard.ts +100 -50
- package/src/overlays/usage-display.ts +10 -4
- package/src/prompt/attachment-chips.ts +15 -11
- package/src/prompt/composer-attachments.ts +6 -4
- package/src/prompt/composer.ts +4 -15
- package/src/prompt/custom-editor.ts +54 -26
- package/src/prompt/image-source.ts +2 -1
- package/src/prompt/interactive-context-helpers.ts +30 -18
- package/src/prompt/macos-spelling.ts +7 -0
- package/src/prompt/magic-keywords.ts +11 -2
- package/src/prompt/model-mention-autocomplete.ts +14 -14
- package/src/prompt/tips.txt +6 -5
- package/src/prompt/welcome.ts +55 -12
- package/src/prompt/word-completion.ts +38 -5
- package/src/render/composite.d.ts +2 -0
- package/src/render/composite.ts +64 -0
- package/src/render/output-pane.d.ts +1 -0
- package/src/render/output-pane.ts +6 -0
- package/src/render/render-utils.d.ts +1 -0
- package/src/render/render-utils.ts +11 -0
- package/src/render/tool-card.d.ts +6 -0
- package/src/render/tool-card.ts +15 -0
- package/src/render/width-aware-text.d.ts +2 -0
- package/src/render/width-aware-text.ts +5 -0
- package/src/setup/scenes/model.ts +2 -1
- package/src/setup/scenes/types.ts +1 -0
- package/src/status-line/component.ts +292 -78
- package/src/status-line/host.ts +4 -1
- package/src/status-line/segments.ts +40 -22
- package/src/status-line/types.ts +15 -3
- package/src/terminal-capabilities.d.ts +27 -35
- package/src/terminal-capabilities.ts +75 -189
- package/src/terminal-multiplexer.d.ts +127 -14
- package/src/terminal-multiplexer.ts +112 -33
- package/src/terminal.d.ts +22 -6
- package/src/terminal.ts +139 -37
- package/src/theme/active-symbols.d.ts +1 -1
- package/src/theme/active-symbols.ts +1 -1
- package/src/theme/schema-validation.ts +1 -0
- package/src/theme/schema.d.ts +11 -2
- package/src/theme/schema.ts +14 -1
- package/src/theme/session-color.ts +1 -7
- package/src/theme/symbols.d.ts +1 -1
- package/src/theme/symbols.ts +6 -1
- package/src/theme/theme-class.d.ts +7 -0
- package/src/theme/theme-class.ts +26 -1
- package/src/theme/theme-schema.json +5 -1
- package/src/theme/theme.d.ts +1 -1
- package/src/theme/theme.ts +8 -4
- package/src/theme/tui-adapters.d.ts +3 -0
- package/src/theme/tui-adapters.ts +68 -0
- package/src/tmux.d.ts +11 -4
- package/src/tmux.ts +47 -11
- package/src/tools/ast-edit.ts +59 -35
- package/src/tools/ast-grep.ts +35 -16
- package/src/tools/bash.ts +92 -42
- package/src/tools/daemon.d.ts +1 -1
- package/src/tools/daemon.ts +1 -1
- package/src/tools/default-renderer.ts +35 -19
- package/src/tools/edit.ts +142 -120
- package/src/tools/eval-format/index.ts +28 -2
- package/src/tools/eval-format/javascript.ts +7 -5
- package/src/tools/eval.d.ts +22 -3
- package/src/tools/eval.ts +364 -208
- package/src/tools/fetch.ts +5 -6
- package/src/tools/glob.d.ts +4 -0
- package/src/tools/glob.ts +33 -65
- package/src/tools/grep.ts +81 -48
- package/src/tools/index.ts +2 -0
- package/src/tools/lsp.ts +81 -59
- package/src/tools/mcp.ts +111 -68
- package/src/tools/native-view.d.ts +47 -0
- package/src/tools/native-view.ts +102 -1
- package/src/tools/output-meta.d.ts +11 -1
- package/src/tools/output-meta.ts +23 -3
- package/src/tools/read.ts +7 -5
- package/src/tools/renderer.d.ts +37 -2
- package/src/tools/renderer.ts +42 -2
- package/src/tools/streaming-output.d.ts +20 -1
- package/src/tools/streaming-output.ts +149 -50
- package/src/tools/task.d.ts +0 -4
- package/src/tools/task.ts +112 -59
- package/src/tools/todo.ts +119 -30
- package/src/tools/wait.ts +34 -24
- package/src/tools/web-search.ts +1 -1
- package/src/tools/write.d.ts +9 -2
- package/src/tools/write.ts +147 -95
- package/src/tools/yield.d.ts +22 -0
- package/src/tools/yield.ts +225 -0
- package/src/tui.d.ts +31 -0
- package/src/tui.ts +309 -160
- package/src/utils.d.ts +6 -0
- package/src/utils.ts +19 -0
- package/src/vim.d.ts +19 -5
- package/src/vim.ts +333 -18
- package/src/windows-input-mode.ts +8 -0
package/src/chat/user-message.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { applyBackgroundToLine, padding, visibleWidth } from "../utils";
|
|
1
|
+
import { applyBackgroundToLine, padding, stripTerminalSequences, visibleWidth } from "../utils";
|
|
2
|
+
import type { AnimationFrame, TranscriptPresentationTarget } from "../chrome/transcript-container";
|
|
2
3
|
import { type Component, Container } from "../tui";
|
|
3
4
|
import { Disclosure } from "../components/disclosure";
|
|
4
5
|
import { Markdown } from "../components/markdown";
|
|
@@ -57,7 +58,7 @@ const OSC133_ZONE_CLOSE = OSC133_ZONE_END + OSC133_COMMAND_START + OSC133_COMMAN
|
|
|
57
58
|
|
|
58
59
|
/** How a user bubble styles its prose and chips (see {@link userBubbleColor}). */
|
|
59
60
|
export interface UserBubbleOptions {
|
|
60
|
-
/**
|
|
61
|
+
/** Filesystem paths for attached image chips, indexed by chip number. */
|
|
61
62
|
imageLinks?: readonly (string | undefined)[];
|
|
62
63
|
/** The message's attached images in chip order (`#1` first); a native bubble shows them. */
|
|
63
64
|
images?: readonly ImageContent[];
|
|
@@ -124,7 +125,8 @@ export function userBubbleColor(
|
|
|
124
125
|
* (see {@link ReactionTarget}) drawn right-aligned in the bubble's top padding row;
|
|
125
126
|
* a live-steered message carries a `*` marker left-aligned in the same row.
|
|
126
127
|
*/
|
|
127
|
-
export class UserMessageComponent extends Container implements ReactionTarget {
|
|
128
|
+
export class UserMessageComponent extends Container implements ReactionTarget, TranscriptPresentationTarget {
|
|
129
|
+
#allocation = Number.POSITIVE_INFINITY;
|
|
128
130
|
// Memoized OSC 133 zone wrapping keyed on the underlying container render
|
|
129
131
|
// (same source ref ⇒ identical rows ⇒ reuse the wrapped copy). Keeps this
|
|
130
132
|
// component reference-stable for the transcript's incremental assembly and
|
|
@@ -177,6 +179,12 @@ export class UserMessageComponent extends Container implements ReactionTarget {
|
|
|
177
179
|
this.addChild(markdown);
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
override releaseRenderCaches(): void {
|
|
183
|
+
this.#zoneSource = undefined;
|
|
184
|
+
this.#zoneLines = undefined;
|
|
185
|
+
super.releaseRenderCaches();
|
|
186
|
+
}
|
|
187
|
+
|
|
180
188
|
setReaction(emoji: string): void {
|
|
181
189
|
if (this.#reaction === emoji) return;
|
|
182
190
|
this.#reaction = emoji;
|
|
@@ -281,11 +289,47 @@ export class UserMessageComponent extends Container implements ReactionTarget {
|
|
|
281
289
|
return applyBackgroundToLine(` ${marker}${padding(gap)}${emoji}`, width, this.#bgColor);
|
|
282
290
|
}
|
|
283
291
|
|
|
292
|
+
/** Apply the transcript allocator's current viewport reservation. */
|
|
293
|
+
setTranscriptAllocation(rows: number, _frame?: AnimationFrame): void {
|
|
294
|
+
this.#allocation = Math.max(0, Math.trunc(rows));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
isTranscriptBlockFinalized(): boolean {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Single-row emergency representation for the overflow transcript layout:
|
|
303
|
+
* renders the first content line instead of the blank top padding row, and
|
|
304
|
+
* omits OSC 133 shell integration markers so moving live blocks across the
|
|
305
|
+
* viewport does not leave stale prompt marks on lines it no longer occupies.
|
|
306
|
+
*/
|
|
307
|
+
renderTranscriptBlockEmergencyRow(width: number): string | undefined {
|
|
308
|
+
return this.#selectEmergencyRow(super.render(width));
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
#selectEmergencyRow(lines: readonly string[]): string | undefined {
|
|
312
|
+
if (lines.length === 0) return undefined;
|
|
313
|
+
if (lines.length >= 3) {
|
|
314
|
+
for (let i = 1; i < lines.length - 1; i++) {
|
|
315
|
+
if (stripTerminalSequences(lines[i]!).trim().length > 0) {
|
|
316
|
+
return lines[i];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return lines[1];
|
|
320
|
+
}
|
|
321
|
+
return lines[0];
|
|
322
|
+
}
|
|
323
|
+
|
|
284
324
|
override render(width: number): readonly string[] {
|
|
285
325
|
const lines = super.render(width);
|
|
286
326
|
if (lines.length === 0) {
|
|
287
327
|
return lines;
|
|
288
328
|
}
|
|
329
|
+
if (this.#allocation === 1) {
|
|
330
|
+
const emergency = this.#selectEmergencyRow(lines);
|
|
331
|
+
if (emergency !== undefined) return [emergency];
|
|
332
|
+
}
|
|
289
333
|
if (this.#zoneSource === lines && this.#zoneLines !== undefined) {
|
|
290
334
|
return this.#zoneLines;
|
|
291
335
|
}
|
|
@@ -337,6 +381,10 @@ class SyntheticSummary implements Component {
|
|
|
337
381
|
this.#summary = summary;
|
|
338
382
|
}
|
|
339
383
|
|
|
384
|
+
releaseRenderCaches(): void {
|
|
385
|
+
this.#cache = undefined;
|
|
386
|
+
}
|
|
387
|
+
|
|
340
388
|
invalidate(): void {
|
|
341
389
|
this.#cache = undefined;
|
|
342
390
|
}
|
|
@@ -425,6 +473,10 @@ export class CollapsedSyntheticMessageComponent implements Component {
|
|
|
425
473
|
this.#disclosure.invalidate();
|
|
426
474
|
}
|
|
427
475
|
|
|
476
|
+
releaseRenderCaches(): void {
|
|
477
|
+
this.#disclosure.releaseRenderCaches();
|
|
478
|
+
}
|
|
479
|
+
|
|
428
480
|
dispose(): void {
|
|
429
481
|
this.#disclosure.dispose();
|
|
430
482
|
}
|
package/src/chrome/shared.ts
CHANGED
|
@@ -10,6 +10,59 @@ export function sanitizeStatusText(text: string): string {
|
|
|
10
10
|
return sanitizeDisplaySingleLine(text).replace(/ +/g, " ").trim();
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/** 7-bit SGR (`ESC [ <params> m`) — the one escape family a hook status may keep. */
|
|
14
|
+
const SGR_RE = /\x1b\[[0-9;:]*m/g;
|
|
15
|
+
const SGR_RESET = "\x1b[0m";
|
|
16
|
+
const WHITESPACE_RE = /\s/;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Like {@link sanitizeStatusText}, but keeps 7-bit SGR so extensions can colour
|
|
20
|
+
* `ctx.ui.setStatus` text. Every other escape (OSC links/titles, DCS/PM/APC,
|
|
21
|
+
* 7- and 8-bit CSI), C0/C1, lone surrogates, newlines and tabs are sanitized at
|
|
22
|
+
* least as strictly as in `sanitizeStatusText`; space runs collapse and edges
|
|
23
|
+
* trim (`String#trim` whitespace) by visible text, regardless of SGR placement.
|
|
24
|
+
* A styled result always ends with `\x1b[0m`.
|
|
25
|
+
*/
|
|
26
|
+
export function sanitizeHookStatusText(input: string): string {
|
|
27
|
+
// Drop lone surrogates before splitting, as `sanitizeText` does, so stripped escapes
|
|
28
|
+
// cannot fuse surrogate halves from neighbouring chunks into a new character.
|
|
29
|
+
const wellFormed = input.toWellFormed();
|
|
30
|
+
const text = wellFormed === input ? input : wellFormed.replaceAll("\ufffd", "");
|
|
31
|
+
SGR_RE.lastIndex = 0;
|
|
32
|
+
if (!SGR_RE.test(text)) return sanitizeStatusText(text); // byte-identical for unstyled input
|
|
33
|
+
let out = "";
|
|
34
|
+
// SGR codes and whitespace seen since the last visible char, in source order.
|
|
35
|
+
let pending = "";
|
|
36
|
+
let lastWasSpace = false;
|
|
37
|
+
let hasVisible = false;
|
|
38
|
+
let cursor = 0;
|
|
39
|
+
SGR_RE.lastIndex = 0;
|
|
40
|
+
for (;;) {
|
|
41
|
+
const match = SGR_RE.exec(text);
|
|
42
|
+
// `sanitizeText` runs `Bun.stripANSI` only when an ESC is present; a chunk between SGR
|
|
43
|
+
// codes often has none, so strip explicitly to drop 8-bit (C1) sequence payloads.
|
|
44
|
+
const chunk = sanitizeDisplaySingleLine(Bun.stripANSI(text.slice(cursor, match ? match.index : text.length)));
|
|
45
|
+
for (const ch of chunk) {
|
|
46
|
+
if (WHITESPACE_RE.test(ch)) {
|
|
47
|
+
// Leading whitespace drops; ASCII space runs collapse even across SGR codes.
|
|
48
|
+
if (hasVisible && !(ch === " " && lastWasSpace)) pending += ch;
|
|
49
|
+
lastWasSpace = ch === " ";
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
out += pending + ch;
|
|
53
|
+
pending = "";
|
|
54
|
+
lastWasSpace = false;
|
|
55
|
+
hasVisible = true;
|
|
56
|
+
}
|
|
57
|
+
if (!match) break;
|
|
58
|
+
pending += match[0];
|
|
59
|
+
cursor = match.index + match[0].length;
|
|
60
|
+
}
|
|
61
|
+
if (!hasVisible) return "";
|
|
62
|
+
// Trailing whitespace trims; trailing SGR codes stay (they never contain whitespace).
|
|
63
|
+
return out + pending.replace(/\s+/g, "") + SGR_RESET;
|
|
64
|
+
}
|
|
65
|
+
|
|
13
66
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
67
|
// Tab Bar Theme
|
|
15
68
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -63,6 +63,12 @@ export interface TranscriptViewportSpan {
|
|
|
63
63
|
export declare class TranscriptContainer extends Container {
|
|
64
64
|
#private;
|
|
65
65
|
addChild(component: Component): void;
|
|
66
|
+
/**
|
|
67
|
+
* `#entries` mirrors `children`; move both together or the next `#syncEntries`
|
|
68
|
+
* pays a full O(n) rebuild.
|
|
69
|
+
*/
|
|
70
|
+
insertChildAt(component: Component, index: number): void;
|
|
71
|
+
/** Removes `component` if {@link canRemoveBlock} allows it; otherwise does nothing. */
|
|
66
72
|
removeChild(component: Component): void;
|
|
67
73
|
clear(): void;
|
|
68
74
|
setToolActivityVisible(visible: boolean): void;
|
|
@@ -58,6 +58,12 @@ export interface AppendOnlyTranscriptBlock {
|
|
|
58
58
|
|
|
59
59
|
interface FinalizableBlock {
|
|
60
60
|
isTranscriptBlockFinalized?(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* A finalized block whose rows still wait on async work (an SVG figure's
|
|
63
|
+
* raster). Retirement holds until it lands: committed rows can never be
|
|
64
|
+
* repainted, so retiring early would freeze a placeholder into scrollback.
|
|
65
|
+
*/
|
|
66
|
+
isTranscriptBlockPending?(): boolean;
|
|
61
67
|
/** Render the row that must remain represented under emergency viewport pressure. */
|
|
62
68
|
renderTranscriptBlockEmergencyRow?(width: number): string | undefined;
|
|
63
69
|
}
|
|
@@ -129,7 +135,7 @@ const EMPTY_STABLE_ROWS: readonly TranscriptStableRow[] = [];
|
|
|
129
135
|
|
|
130
136
|
function isFinalized(component: Component): boolean {
|
|
131
137
|
const block = component as Component & FinalizableBlock;
|
|
132
|
-
return block.isTranscriptBlockFinalized?.() ?? true;
|
|
138
|
+
return (block.isTranscriptBlockFinalized?.() ?? true) && block.isTranscriptBlockPending?.() !== true;
|
|
133
139
|
}
|
|
134
140
|
|
|
135
141
|
function blockMode(component: Component): TranscriptBlockMode {
|
|
@@ -208,6 +214,7 @@ export class TranscriptContainer extends Container {
|
|
|
208
214
|
*/
|
|
209
215
|
#frameRows = new Map<TranscriptEntry, readonly string[]>();
|
|
210
216
|
#frameRowsWidth = 0;
|
|
217
|
+
#releaseFailures = new WeakSet<Component>();
|
|
211
218
|
/** The `children` array `#entries` last mirrored; see {@link #syncEntries}. */
|
|
212
219
|
#syncedChildren: Component[] | undefined;
|
|
213
220
|
/** Forces the next {@link #syncEntries} to compare every entry, not just the live tail. */
|
|
@@ -229,15 +236,40 @@ export class TranscriptContainer extends Container {
|
|
|
229
236
|
stableFrozen: false,
|
|
230
237
|
imageScan: undefined,
|
|
231
238
|
});
|
|
232
|
-
//
|
|
233
|
-
//
|
|
239
|
+
// `children` is public and may be edited externally; re-check the whole
|
|
240
|
+
// list once instead of trusting positions. Insert-after-anchor callers
|
|
241
|
+
// use insertChildAt, which keeps both arrays in lockstep.
|
|
234
242
|
this.#entriesUnverified = true;
|
|
235
243
|
}
|
|
236
244
|
|
|
245
|
+
/**
|
|
246
|
+
* `#entries` mirrors `children`; move both together or the next `#syncEntries`
|
|
247
|
+
* pays a full O(n) rebuild.
|
|
248
|
+
*/
|
|
249
|
+
insertChildAt(component: Component, index: number): void {
|
|
250
|
+
this.addChild(component);
|
|
251
|
+
const from = this.children.length - 1;
|
|
252
|
+
if (index >= from) {
|
|
253
|
+
this.#entriesUnverified = false;
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const [moved] = this.children.splice(from, 1);
|
|
257
|
+
if (moved) this.children.splice(index, 0, moved);
|
|
258
|
+
const [entry] = this.#entries.splice(this.#entries.length - 1, 1);
|
|
259
|
+
if (entry) this.#entries.splice(index, 0, entry);
|
|
260
|
+
// Both arrays moved in lockstep, so the live-tail check applies again.
|
|
261
|
+
this.#entriesUnverified = false;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** Removes `component` if {@link canRemoveBlock} allows it; otherwise does nothing. */
|
|
237
265
|
override removeChild(component: Component): void {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
266
|
+
const index = this.#removableIndex(component);
|
|
267
|
+
if (index < 0) return;
|
|
268
|
+
// #removableIndex synced entries, which now mirror children index for
|
|
269
|
+
// index. This class renders through its own entries, never Container's
|
|
270
|
+
// memoized render, so splicing children directly is the whole removal.
|
|
271
|
+
this.children.splice(index, 1);
|
|
272
|
+
this.#entries.splice(index, 1);
|
|
241
273
|
this.#frontier = Math.min(this.#frontier, this.#entries.length);
|
|
242
274
|
this.#childStartRows.delete(component);
|
|
243
275
|
}
|
|
@@ -292,14 +324,24 @@ export class TranscriptContainer extends Container {
|
|
|
292
324
|
|
|
293
325
|
/** Whether a transient block may be discarded without leaving tape history. */
|
|
294
326
|
canRemoveBlock(component: Component): boolean {
|
|
327
|
+
return this.#removableIndex(component) >= 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Syncs entries, then returns `component`'s index if it can be discarded
|
|
332
|
+
* without leaving tape history (not committed, not emitted, not in an
|
|
333
|
+
* offered batch), else -1.
|
|
334
|
+
*/
|
|
335
|
+
#removableIndex(component: Component): number {
|
|
295
336
|
this.#syncEntries();
|
|
296
|
-
|
|
297
|
-
|
|
337
|
+
// Removable blocks are transient ones near the live tail, so search from there.
|
|
338
|
+
const index = this.#entries.findLastIndex(entry => entry.component === component);
|
|
339
|
+
if (index < 0) return -1;
|
|
298
340
|
const entry = this.#entries[index]!;
|
|
299
|
-
if (entry.state === "committed" || entry.emitted > 0) return
|
|
300
|
-
if (this.#offered?.kind === "commit" && index < this.#offered.end) return
|
|
301
|
-
if (this.#offered?.kind === "append" && index === this.#offered.entry) return
|
|
302
|
-
return
|
|
341
|
+
if (entry.state === "committed" || entry.emitted > 0) return -1;
|
|
342
|
+
if (this.#offered?.kind === "commit" && index < this.#offered.end) return -1;
|
|
343
|
+
if (this.#offered?.kind === "append" && index === this.#offered.entry) return -1;
|
|
344
|
+
return index;
|
|
303
345
|
}
|
|
304
346
|
|
|
305
347
|
/**
|
|
@@ -586,7 +628,10 @@ export class TranscriptContainer extends Container {
|
|
|
586
628
|
popLoopPhase();
|
|
587
629
|
}
|
|
588
630
|
this.#replayPending = false;
|
|
589
|
-
if (rows.length === 0)
|
|
631
|
+
if (rows.length === 0) {
|
|
632
|
+
this.#releaseCommittedRenderCaches();
|
|
633
|
+
return undefined;
|
|
634
|
+
}
|
|
590
635
|
const batch: HistoryBatch = { id: this.#nextBatchId++, rows, kind: "replay" };
|
|
591
636
|
this.#offered = { batch, kind: "replay" };
|
|
592
637
|
return batch;
|
|
@@ -764,6 +809,8 @@ export class TranscriptContainer extends Container {
|
|
|
764
809
|
this.#retireEntry(this.#entries[index]!);
|
|
765
810
|
}
|
|
766
811
|
this.#frontier = offered.end;
|
|
812
|
+
} else {
|
|
813
|
+
this.#releaseCommittedRenderCaches();
|
|
767
814
|
}
|
|
768
815
|
this.#offered = undefined;
|
|
769
816
|
if (this.#replayRequested) this.#startReplay();
|
|
@@ -783,6 +830,7 @@ export class TranscriptContainer extends Container {
|
|
|
783
830
|
const entry = this.#entries[index]!;
|
|
784
831
|
this.#setAllocation(entry.component, Number.MAX_SAFE_INTEGER, this.#lastFrame);
|
|
785
832
|
const block = trimBlankEdges(entry.component.render(width));
|
|
833
|
+
if (entry.state === "committed") this.#releaseRenderCaches(entry);
|
|
786
834
|
if (block.length === 0) continue;
|
|
787
835
|
if (rows.length > 0) rows.unshift("");
|
|
788
836
|
rows.unshift(...block);
|
|
@@ -830,6 +878,7 @@ export class TranscriptContainer extends Container {
|
|
|
830
878
|
for (const entry of this.#entries) {
|
|
831
879
|
this.#setAllocation(entry.component, Number.MAX_SAFE_INTEGER, this.#lastFrame);
|
|
832
880
|
const block = this.#renderEntry(entry, width);
|
|
881
|
+
if (entry.state === "committed") this.#releaseRenderCaches(entry);
|
|
833
882
|
if (block.length === 0) continue;
|
|
834
883
|
if (rows.length > 0) rows.push("");
|
|
835
884
|
this.#childStartRows.set(entry.component, rows.length);
|
|
@@ -1071,6 +1120,29 @@ export class TranscriptContainer extends Container {
|
|
|
1071
1120
|
entry.stableRows = EMPTY_STABLE_ROWS;
|
|
1072
1121
|
entry.renderedStableByWidth = new Map();
|
|
1073
1122
|
entry.stableRowCountByWidth = new Map();
|
|
1123
|
+
this.#frameRows.delete(entry);
|
|
1124
|
+
this.#releaseRenderCaches(entry);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
#releaseCommittedRenderCaches(): void {
|
|
1128
|
+
for (let index = 0; index < this.#frontier; index++) {
|
|
1129
|
+
this.#releaseRenderCaches(this.#entries[index]!);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
#releaseRenderCaches(entry: TranscriptEntry): void {
|
|
1134
|
+
const release = entry.component.releaseRenderCaches;
|
|
1135
|
+
if (release === undefined) return;
|
|
1136
|
+
try {
|
|
1137
|
+
release.call(entry.component);
|
|
1138
|
+
} catch (err) {
|
|
1139
|
+
if (this.#releaseFailures.has(entry.component)) return;
|
|
1140
|
+
this.#releaseFailures.add(entry.component);
|
|
1141
|
+
logger.warn("Transcript block failed to release render caches", {
|
|
1142
|
+
component: entry.component.constructor.name,
|
|
1143
|
+
error: String(err),
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1074
1146
|
}
|
|
1075
1147
|
|
|
1076
1148
|
#startReplay(): void {
|
|
@@ -1172,6 +1244,14 @@ export class TranscriptContainer extends Container {
|
|
|
1172
1244
|
continue;
|
|
1173
1245
|
}
|
|
1174
1246
|
this.#setAllocation(candidate.entry.component, 1, frame);
|
|
1247
|
+
const emergency = (
|
|
1248
|
+
candidate.entry.component as Component & FinalizableBlock
|
|
1249
|
+
).renderTranscriptBlockEmergencyRow?.(width);
|
|
1250
|
+
if (emergency !== undefined) {
|
|
1251
|
+
output.push(emergency);
|
|
1252
|
+
owners.push(candidate.entry.component);
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1175
1255
|
const rendered = this.#renderEntry(candidate.entry, width).slice(
|
|
1176
1256
|
this.#projectedEmittedRowCount(candidate.entry, candidate.index, width),
|
|
1177
1257
|
);
|
package/src/components/box.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export declare class Box implements Component {
|
|
|
30
30
|
setBgFn(bgFn?: (text: string) => string): void;
|
|
31
31
|
setBorder(border?: BoxBorder): void;
|
|
32
32
|
invalidate(): void;
|
|
33
|
+
releaseRenderCaches(): void;
|
|
33
34
|
/**
|
|
34
35
|
* A `card` when the box has a border or background: the background token
|
|
35
36
|
* picks tone/role (user message, tool state, selection), a border colour
|
package/src/components/box.ts
CHANGED
|
@@ -135,6 +135,11 @@ export class Box implements Component {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
releaseRenderCaches(): void {
|
|
139
|
+
this.#invalidateCache();
|
|
140
|
+
for (const child of this.children) child.releaseRenderCaches?.();
|
|
141
|
+
}
|
|
142
|
+
|
|
138
143
|
/**
|
|
139
144
|
* A `card` when the box has a border or background: the background token
|
|
140
145
|
* picks tone/role (user message, tool state, selection), a border colour
|
|
@@ -36,6 +36,7 @@ export declare class Disclosure implements Component {
|
|
|
36
36
|
setExpanded(expanded: boolean): void;
|
|
37
37
|
setIgnoreTight(ignore: boolean): this;
|
|
38
38
|
invalidate(): void;
|
|
39
|
+
releaseRenderCaches(): void;
|
|
39
40
|
dispose(): void;
|
|
40
41
|
debugState(): Record<string, unknown>;
|
|
41
42
|
get debugChildren(): readonly Component[];
|
|
@@ -100,6 +100,14 @@ export class Disclosure implements Component {
|
|
|
100
100
|
this.#body?.invalidate?.();
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
releaseRenderCaches(): void {
|
|
104
|
+
this.#cache = undefined;
|
|
105
|
+
this.#boundedCache = undefined;
|
|
106
|
+
this.#summary?.releaseRenderCaches?.();
|
|
107
|
+
this.#collapsedBody?.releaseRenderCaches?.();
|
|
108
|
+
this.#body?.releaseRenderCaches?.();
|
|
109
|
+
}
|
|
110
|
+
|
|
103
111
|
dispose(): void {
|
|
104
112
|
if (this.#disposed) return;
|
|
105
113
|
this.#disposed = true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AutocompleteProvider } from "../autocomplete";
|
|
2
|
-
import type { TspEditorDecoration, TspTone } from "@linxiraos/pi-wire";
|
|
2
|
+
import type { TspEditorDecoration, TspText, TspTone } from "@linxiraos/pi-wire";
|
|
3
3
|
import { type DescribeContext, type NativeChild, type NativeNode, type NativeTextEdit, type NativeUiEvent } from "../native/node";
|
|
4
4
|
import type { SymbolTheme } from "../symbols";
|
|
5
5
|
import { type Component, type Focusable } from "../tui";
|
|
@@ -106,8 +106,11 @@ export declare class Editor implements Component, Focusable {
|
|
|
106
106
|
* dialog's text field; only the prompt composer claims `zeta.editor`).
|
|
107
107
|
*/
|
|
108
108
|
describeLayout: ((input: NativeNode, cx: DescribeContext) => NativeEditorLayout) | undefined;
|
|
109
|
-
/**
|
|
110
|
-
|
|
109
|
+
/**
|
|
110
|
+
* TSP placeholder for the empty buffer; natively it replaces the rotating ANSI {@link placeholder} hints.
|
|
111
|
+
* Return a stable value (the same spans array) while it is unchanged: the editor node is reused by identity.
|
|
112
|
+
*/
|
|
113
|
+
describePlaceholder: (() => TspText) | undefined;
|
|
111
114
|
/** Called with the selected text when Visual mode yanks, so hosts can reach the system
|
|
112
115
|
* clipboard — `packages/tui` deliberately has no clipboard dependency of its own. */
|
|
113
116
|
onYank?: (text: string) => void;
|
|
@@ -146,6 +149,12 @@ export declare class Editor implements Component, Focusable {
|
|
|
146
149
|
* cursor. The host styles it (ANSI allowed). Re-evaluated on every render, so hosts can derive
|
|
147
150
|
* it from live state. */
|
|
148
151
|
placeholder?: () => string | undefined;
|
|
152
|
+
/** Whole-message prediction for the next prompt, painted as ghost text after the cursor while
|
|
153
|
+
* the single-line buffer is a strict prefix of it, the cursor sits at its end, and no
|
|
154
|
+
* autocomplete is open. A shown prediction replaces the {@link placeholder}; Tab or Right inserts
|
|
155
|
+
* the rest without submitting. Must be a single line. Re-evaluated on every render, so hosts can
|
|
156
|
+
* derive it from live state. */
|
|
157
|
+
prediction?: () => string | undefined;
|
|
149
158
|
constructor(theme: EditorTheme);
|
|
150
159
|
/** Return bounded editor content, cursor, and transient child state for debug inspection. */
|
|
151
160
|
debugState(): Record<string, unknown>;
|
|
@@ -250,6 +259,8 @@ export declare class Editor implements Component, Focusable {
|
|
|
250
259
|
get atoms(): ReadonlyMap<string, string>;
|
|
251
260
|
/** Monotonic buffer-content revision for render caches. Cursor-only movement does not advance it. */
|
|
252
261
|
get textRevision(): number;
|
|
262
|
+
/** Monotonic atom-table revision for render caches: advances whenever {@link atoms} is mutated or replaced. */
|
|
263
|
+
get atomsRevision(): number;
|
|
253
264
|
/** Whether the buffer text equals `value`, without `getText()`'s full join —
|
|
254
265
|
* O(1) for the hot per-keystroke probes against short single-line values. */
|
|
255
266
|
textEquals(value: string): boolean;
|
|
@@ -285,7 +296,7 @@ export declare class Editor implements Component, Focusable {
|
|
|
285
296
|
* Mirrors the transient state the key dispatch tears down before this action so the two
|
|
286
297
|
* cannot diverge: a pending character jump is cancelled by any other key, and an open
|
|
287
298
|
* spelling-assist popup is dismissed by anything that is not one of its accept keys (its
|
|
288
|
-
*
|
|
299
|
+
* refresh skips assist mode, so a surviving list would hang around forever).
|
|
289
300
|
* While Vim owns the buffer (Normal or Visual) the operation is Vim's `x` — deleting the
|
|
290
301
|
* selection and returning to Normal in Visual mode, the grapheme under the cursor
|
|
291
302
|
* otherwise. Only Insert mode and Vim-off editors delete straight through. */
|