@oh-my-pi/pi-tui 18.2.4 → 18.2.5
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 +23 -0
- package/README.md +43 -0
- package/dist/types/app-keybindings.d.ts +395 -0
- package/dist/types/apps/autoresearch-dashboard.d.ts +43 -0
- package/dist/types/apps/autoresearch-data.d.ts +15 -0
- package/dist/types/apps/cleanse-board.d.ts +66 -0
- package/dist/types/apps/cleanse-picker.d.ts +23 -0
- package/dist/types/apps/debug/log-formatting.d.ts +6 -0
- package/dist/types/apps/debug/log-viewer.d.ts +81 -0
- package/dist/types/apps/debug/protocol-probe.d.ts +42 -0
- package/dist/types/apps/debug/raw-sse-buffer.d.ts +58 -0
- package/dist/types/apps/debug/raw-sse.d.ts +26 -0
- package/dist/types/apps/debug/terminal-info.d.ts +34 -0
- package/dist/types/apps/debug/viewer-frame.d.ts +52 -0
- package/dist/types/apps/git/avatar.d.ts +9 -0
- package/dist/types/apps/git/colors.d.ts +49 -0
- package/dist/types/apps/git/diff-pane.d.ts +188 -0
- package/dist/types/apps/git/git-tui.d.ts +66 -0
- package/dist/types/apps/git/sidebar.d.ts +149 -0
- package/dist/types/apps/git/state.d.ts +117 -0
- package/dist/types/apps/if-bench-board.d.ts +75 -0
- package/dist/types/apps/live-visualizer.d.ts +33 -0
- package/dist/types/apps/ps-data.d.ts +51 -0
- package/dist/types/apps/ps-top.d.ts +33 -0
- package/dist/types/apps/session-picker.d.ts +26 -0
- package/dist/types/apps/setup-model-picker.d.ts +13 -0
- package/dist/types/apps/standalone-picker.d.ts +42 -0
- package/dist/types/autocomplete.d.ts +4 -0
- package/dist/types/chat/advisor-message.d.ts +11 -0
- package/dist/types/chat/assistant-message.d.ts +106 -0
- package/dist/types/chat/background-tan-message.d.ts +9 -0
- package/dist/types/chat/bash-execution.d.ts +47 -0
- package/dist/types/chat/cache-invalidation-marker.d.ts +50 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +50 -0
- package/dist/types/chat/collab-prompt-message.d.ts +10 -0
- package/dist/types/chat/compaction-summary-message.d.ts +54 -0
- package/dist/types/chat/custom-message.d.ts +10 -0
- package/dist/types/chat/display-preferences.d.ts +13 -0
- package/dist/types/chat/eval-execution.d.ts +29 -0
- package/dist/types/chat/execution-shared.d.ts +51 -0
- package/dist/types/chat/extension-types.d.ts +28 -0
- package/dist/types/chat/hook-message.d.ts +10 -0
- package/dist/types/chat/image-loading.d.ts +46 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +21 -0
- package/dist/types/chat/messages.d.ts +189 -0
- package/dist/types/chat/reaction.d.ts +30 -0
- package/dist/types/chat/read-target.d.ts +4 -0
- package/dist/types/chat/read-tool-group.d.ts +67 -0
- package/dist/types/chat/served-model-marker.d.ts +47 -0
- package/dist/types/chat/skill-message.d.ts +33 -0
- package/dist/types/chat/skill-title-input.d.ts +14 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +12 -0
- package/dist/types/chat/thinking-display.d.ts +12 -0
- package/dist/types/chat/todo-reminder.d.ts +13 -0
- package/dist/types/chat/tool-execution.d.ts +138 -0
- package/dist/types/chat/transcript-browser.d.ts +93 -0
- package/dist/types/chat/transcript-entry.d.ts +45 -0
- package/dist/types/chat/transcript-outline.d.ts +86 -0
- package/dist/types/chat/transcript-render-helpers.d.ts +92 -0
- package/dist/types/chat/ttsr-notification.d.ts +23 -0
- package/dist/types/chat/user-message.d.ts +52 -0
- package/dist/types/chrome/chat-block.d.ts +64 -0
- package/dist/types/chrome/collab-qrcode.d.ts +28 -0
- package/dist/types/chrome/context-thresholds.d.ts +10 -0
- package/dist/types/chrome/countdown-timer.d.ts +14 -0
- package/dist/types/chrome/diff.d.ts +14 -0
- package/dist/types/chrome/dynamic-border.d.ts +16 -0
- package/dist/types/chrome/error-block.d.ts +17 -0
- package/dist/types/chrome/form-theme.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +12 -0
- package/dist/types/chrome/index.d.ts +20 -0
- package/dist/types/chrome/keybinding-hints.d.ts +40 -0
- package/dist/types/chrome/live-board.d.ts +23 -0
- package/dist/types/chrome/local-date.d.ts +4 -0
- package/dist/types/chrome/message-divider.d.ts +22 -0
- package/dist/types/chrome/message-frame.d.ts +52 -0
- package/dist/types/chrome/message-notice.d.ts +35 -0
- package/dist/types/chrome/overlay-box.d.ts +74 -0
- package/dist/types/chrome/qrcode.d.ts +48 -0
- package/dist/types/chrome/segment-track.d.ts +27 -0
- package/dist/types/chrome/select-list-mouse-routing.d.ts +4 -0
- package/dist/types/chrome/selector-helpers.d.ts +52 -0
- package/dist/types/chrome/shared.d.ts +5 -0
- package/dist/types/chrome/streaming-panel.d.ts +19 -0
- package/dist/types/chrome/tool-activity.d.ts +17 -0
- package/dist/types/chrome/transcript-container.d.ts +129 -0
- package/dist/types/chrome/transcript-status.d.ts +12 -0
- package/dist/types/chrome/visual-truncate.d.ts +19 -0
- package/dist/types/components/disclosure.d.ts +42 -0
- package/dist/types/components/form.d.ts +130 -0
- package/dist/types/components/key-value-list.d.ts +24 -0
- package/dist/types/components/layout/geometry.d.ts +73 -0
- package/dist/types/components/layout/row.d.ts +55 -0
- package/dist/types/components/layout/split-pane.d.ts +80 -0
- package/dist/types/components/layout/stack.d.ts +50 -0
- package/dist/types/components/menu-selection.d.ts +71 -0
- package/dist/types/components/metric.d.ts +44 -0
- package/dist/types/components/progress-bar.d.ts +36 -0
- package/dist/types/components/scroll-view.d.ts +53 -19
- package/dist/types/components/scroll-viewport.d.ts +46 -0
- package/dist/types/components/section.d.ts +19 -0
- package/dist/types/components/select-list.d.ts +46 -2
- package/dist/types/components/settings-list.d.ts +20 -0
- package/dist/types/components/table.d.ts +32 -0
- package/dist/types/components/tree-view.d.ts +130 -0
- package/dist/types/components/wizard-step.d.ts +60 -0
- package/dist/types/hotkeys-markdown.d.ts +7 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/keybinding-matchers.d.ts +35 -0
- package/dist/types/keys.d.ts +2 -2
- package/dist/types/lang-from-path.d.ts +9 -0
- package/dist/types/overlays/advisor-config.d.ts +114 -0
- package/dist/types/overlays/agent-activity.d.ts +41 -0
- package/dist/types/overlays/agent-hub-projection.d.ts +33 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +53 -0
- package/dist/types/overlays/agent-hub-types.d.ts +99 -0
- package/dist/types/overlays/agent-hub.d.ts +126 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +71 -0
- package/dist/types/overlays/agents-hub.d.ts +72 -0
- package/dist/types/overlays/ask-dialog.d.ts +88 -0
- package/dist/types/overlays/bordered-loader.d.ts +11 -0
- package/dist/types/overlays/btw-history-panel.d.ts +29 -0
- package/dist/types/overlays/btw-history.d.ts +17 -0
- package/dist/types/overlays/btw-panel.d.ts +26 -0
- package/dist/types/overlays/cleanse-panel.d.ts +36 -0
- package/dist/types/overlays/codex-reset-fireworks.d.ts +52 -0
- package/dist/types/overlays/composer-shape-preview.d.ts +47 -0
- package/dist/types/overlays/composer-shape-registry.d.ts +50 -0
- package/dist/types/overlays/copy-selector.d.ts +48 -0
- package/dist/types/overlays/copy-targets.d.ts +63 -0
- package/dist/types/overlays/error-banner.d.ts +13 -0
- package/dist/types/overlays/extensions/display-text.d.ts +10 -0
- package/dist/types/overlays/extensions/extension-dashboard.d.ts +63 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +54 -0
- package/dist/types/overlays/extensions/inspector-model.d.ts +109 -0
- package/dist/types/overlays/extensions/inspector-panel.d.ts +17 -0
- package/dist/types/overlays/extensions/live-tool-session.d.ts +28 -0
- package/dist/types/overlays/extensions/mcp-runtime.d.ts +107 -0
- package/dist/types/overlays/extensions/state-manager.d.ts +42 -0
- package/dist/types/overlays/extensions/types.d.ts +165 -0
- package/dist/types/overlays/history-search.d.ts +16 -0
- package/dist/types/overlays/hook-editor.d.ts +44 -0
- package/dist/types/overlays/hook-input.d.ts +20 -0
- package/dist/types/overlays/hook-selector.d.ts +71 -0
- package/dist/types/overlays/hub-frame.d.ts +77 -0
- package/dist/types/overlays/login-dialog.d.ts +43 -0
- package/dist/types/overlays/logout-account-selector.d.ts +15 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +87 -0
- package/dist/types/overlays/model-browser.d.ts +213 -0
- package/dist/types/overlays/model-hub.d.ts +72 -0
- package/dist/types/overlays/model-picker.d.ts +74 -0
- package/dist/types/overlays/model-selector.d.ts +52 -0
- package/dist/types/overlays/move-overlay.d.ts +39 -0
- package/dist/types/overlays/oauth-selector.d.ts +41 -0
- package/dist/types/overlays/omfg-panel.d.ts +20 -0
- package/dist/types/overlays/pause-screen.d.ts +43 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +89 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +19 -0
- package/dist/types/overlays/plan-toc.d.ts +41 -0
- package/dist/types/overlays/plugin-selector.d.ts +28 -0
- package/dist/types/overlays/plugin-settings.d.ts +180 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +11 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +23 -0
- package/dist/types/overlays/rewind-selector.d.ts +61 -0
- package/dist/types/overlays/running-subagent-badge.d.ts +6 -0
- package/dist/types/overlays/session-account-selector.d.ts +24 -0
- package/dist/types/overlays/session-info-overlay.d.ts +17 -0
- package/dist/types/overlays/session-observer-registry.d.ts +77 -0
- package/dist/types/overlays/session-selector.d.ts +131 -0
- package/dist/types/overlays/settings-defs.d.ts +119 -0
- package/dist/types/overlays/settings-selector.d.ts +73 -0
- package/dist/types/overlays/show-images-selector.d.ts +11 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +31 -0
- package/dist/types/overlays/theme-selector.d.ts +12 -0
- package/dist/types/overlays/thinking-selector.d.ts +12 -0
- package/dist/types/overlays/tiny-title-download-progress.d.ts +21 -0
- package/dist/types/overlays/tree-selector.d.ts +92 -0
- package/dist/types/overlays/usage-dashboard.d.ts +94 -0
- package/dist/types/overlays/usage-display.d.ts +5 -0
- package/dist/types/overlays/usage-row.d.ts +17 -0
- package/dist/types/prompt/attachment-chips.d.ts +19 -0
- package/dist/types/prompt/composer-attachments.d.ts +71 -0
- package/dist/types/prompt/composer-cache.d.ts +37 -0
- package/dist/types/prompt/composer.d.ts +159 -0
- package/dist/types/prompt/custom-editor.d.ts +261 -0
- package/dist/types/prompt/editor-top-gap.d.ts +18 -0
- package/dist/types/prompt/emoji-autocomplete.d.ts +16 -0
- package/dist/types/prompt/github-ref-autocomplete.d.ts +35 -0
- package/dist/types/prompt/gradient-highlight.d.ts +32 -0
- package/dist/types/prompt/image-format.d.ts +4 -0
- package/dist/types/prompt/image-references.d.ts +26 -0
- package/dist/types/prompt/interactive-context-helpers.d.ts +43 -0
- package/dist/types/prompt/internal-url-autocomplete.d.ts +56 -0
- package/dist/types/prompt/macos-spelling.d.ts +44 -0
- package/dist/types/prompt/magic-keyword-boundary.d.ts +9 -0
- package/dist/types/prompt/magic-keywords.d.ts +26 -0
- package/dist/types/prompt/markdown-prose.d.ts +15 -0
- package/dist/types/prompt/model-mention-autocomplete.d.ts +25 -0
- package/dist/types/prompt/model-mention-syntax.d.ts +24 -0
- package/dist/types/prompt/orchestrate.d.ts +13 -0
- package/dist/types/prompt/prompt-action-autocomplete.d.ts +56 -0
- package/dist/types/prompt/queue-input.d.ts +8 -0
- package/dist/types/prompt/skill-tokens.d.ts +13 -0
- package/dist/types/prompt/tools-markdown.d.ts +12 -0
- package/dist/types/prompt/ultrathink.d.ts +13 -0
- package/dist/types/prompt/usage-amounts.d.ts +26 -0
- package/dist/types/prompt/video.d.ts +18 -0
- package/dist/types/prompt/welcome.d.ts +83 -0
- package/dist/types/prompt/workflow.d.ts +13 -0
- package/dist/types/render/code-cell.d.ts +51 -0
- package/dist/types/render/file-list.d.ts +22 -0
- package/dist/types/render/hyperlink.d.ts +80 -0
- package/dist/types/render/index.d.ts +16 -0
- package/dist/types/render/output-block.d.ts +54 -0
- package/dist/types/render/output-pane.d.ts +80 -0
- package/dist/types/render/render-utils.d.ts +312 -0
- package/dist/types/render/sixel.d.ts +21 -0
- package/dist/types/render/status-line.d.ts +23 -0
- package/dist/types/render/tool-card.d.ts +71 -0
- package/dist/types/render/tree-list.d.ts +29 -0
- package/dist/types/render/types.d.ts +17 -0
- package/dist/types/render/utils.d.ts +43 -0
- package/dist/types/render/width-aware-text.d.ts +23 -0
- package/dist/types/setup/lazy.d.ts +3 -0
- package/dist/types/setup/scenes/composer.d.ts +3 -0
- package/dist/types/setup/scenes/glyph.d.ts +3 -0
- package/dist/types/setup/scenes/model.d.ts +3 -0
- package/dist/types/setup/scenes/outro.d.ts +2 -0
- package/dist/types/setup/scenes/providers.d.ts +3 -0
- package/dist/types/setup/scenes/sign-in.d.ts +21 -0
- package/dist/types/setup/scenes/splash.d.ts +11 -0
- package/dist/types/setup/scenes/theme.d.ts +3 -0
- package/dist/types/setup/scenes/types.d.ts +110 -0
- package/dist/types/setup/scenes/web-search.d.ts +22 -0
- package/dist/types/setup/setup-version.d.ts +11 -0
- package/dist/types/setup/startup-splash.d.ts +9 -0
- package/dist/types/setup/wizard-overlay.d.ts +16 -0
- package/dist/types/setup/wizard.d.ts +25 -0
- package/dist/types/status-line/component.d.ts +182 -0
- package/dist/types/status-line/context-usage.d.ts +156 -0
- package/dist/types/status-line/footer.d.ts +30 -0
- package/dist/types/status-line/git-utils.d.ts +22 -0
- package/dist/types/status-line/host.d.ts +129 -0
- package/dist/types/status-line/index.d.ts +6 -0
- package/dist/types/status-line/loop.d.ts +18 -0
- package/dist/types/status-line/metrics.d.ts +21 -0
- package/dist/types/status-line/presets.d.ts +3 -0
- package/dist/types/status-line/schema.d.ts +15 -0
- package/dist/types/status-line/segments.d.ts +5 -0
- package/dist/types/status-line/separators.d.ts +3 -0
- package/dist/types/status-line/types.d.ts +236 -0
- package/dist/types/stdin-buffer.d.ts +4 -0
- package/dist/types/theme/color.d.ts +24 -0
- package/dist/types/theme/defaults/index.d.ts +9489 -0
- package/dist/types/theme/index.d.ts +4 -0
- package/dist/types/theme/loader.d.ts +23 -0
- package/dist/types/theme/mermaid-cache.d.ts +26 -0
- package/dist/types/theme/schema-validation.d.ts +3 -0
- package/dist/types/theme/schema.d.ts +25 -0
- package/dist/types/theme/session-color.d.ts +43 -0
- package/dist/types/theme/shimmer.d.ts +44 -0
- package/dist/types/theme/symbols.d.ts +34 -0
- package/dist/types/theme/theme-class.d.ts +299 -0
- package/dist/types/theme/theme.d.ts +111 -0
- package/dist/types/theme/tui-adapters.d.ts +30 -0
- package/dist/types/thinking.d.ts +165 -0
- package/dist/types/tools/agent-tree.d.ts +36 -0
- package/dist/types/tools/ask.d.ts +67 -0
- package/dist/types/tools/ast-edit.d.ts +53 -0
- package/dist/types/tools/ast-grep.d.ts +52 -0
- package/dist/types/tools/autoresearch.d.ts +156 -0
- package/dist/types/tools/bash-interactive.d.ts +28 -0
- package/dist/types/tools/bash.d.ts +103 -0
- package/dist/types/tools/conflict-detect.d.ts +43 -0
- package/dist/types/tools/debug.d.ts +60 -0
- package/dist/types/tools/default-renderer.d.ts +24 -0
- package/dist/types/tools/edit.d.ts +158 -0
- package/dist/types/tools/eval-format/code-mode-declarations.d.ts +5 -0
- package/dist/types/tools/eval-format/index.d.ts +5 -0
- package/dist/types/tools/eval-format/javascript.d.ts +2 -0
- package/dist/types/tools/eval-format/python.d.ts +2 -0
- package/dist/types/tools/eval.d.ts +94 -0
- package/dist/types/tools/fetch.d.ts +42 -0
- package/dist/types/tools/gh-format.d.ts +8 -0
- package/dist/types/tools/github.d.ts +144 -0
- package/dist/types/tools/glob.d.ts +44 -0
- package/dist/types/tools/goal.d.ts +42 -0
- package/dist/types/tools/grep.d.ts +64 -0
- package/dist/types/tools/grouped-file-output.d.ts +71 -0
- package/dist/types/tools/hashline-format.d.ts +28 -0
- package/dist/types/tools/hub.d.ts +340 -0
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/tools/json-tree.d.ts +59 -0
- package/dist/types/tools/line-ranges.d.ts +29 -0
- package/dist/types/tools/list-limit.d.ts +15 -0
- package/dist/types/tools/lsp.d.ts +72 -0
- package/dist/types/tools/match-line-format.d.ts +11 -0
- package/dist/types/tools/mcp.d.ts +81 -0
- package/dist/types/tools/memory.d.ts +67 -0
- package/dist/types/tools/output-meta.d.ts +151 -0
- package/dist/types/tools/read.d.ts +139 -0
- package/dist/types/tools/renderer.d.ts +98 -0
- package/dist/types/tools/report-tool-issue.d.ts +8 -0
- package/dist/types/tools/resolve.d.ts +47 -0
- package/dist/types/tools/streaming-output.d.ts +282 -0
- package/dist/types/tools/subprocess.d.ts +24 -0
- package/dist/types/tools/task-repair-args.d.ts +53 -0
- package/dist/types/tools/task-yield-assembly.d.ts +20 -0
- package/dist/types/tools/task.d.ts +425 -0
- package/dist/types/tools/terminal-output.d.ts +8 -0
- package/dist/types/tools/think.d.ts +13 -0
- package/dist/types/tools/todo.d.ts +118 -0
- package/dist/types/tools/tool-errors.d.ts +7 -0
- package/dist/types/tools/vibe.d.ts +120 -0
- package/dist/types/tools/web-search.d.ts +195 -0
- package/dist/types/tools/write.d.ts +76 -0
- package/dist/types/tools/xd-url.d.ts +13 -0
- package/dist/types/tools/xdev.d.ts +52 -0
- package/dist/types/tui.d.ts +18 -0
- package/dist/types/utils.d.ts +2 -0
- package/package.json +37 -3
- package/src/app-keybindings.ts +760 -0
- package/src/apps/autoresearch-dashboard.ts +500 -0
- package/src/apps/autoresearch-data.ts +64 -0
- package/src/apps/cleanse-board.ts +341 -0
- package/src/apps/cleanse-picker.ts +57 -0
- package/src/apps/debug/log-formatting.ts +53 -0
- package/src/apps/debug/log-viewer.ts +868 -0
- package/src/apps/debug/protocol-probe.ts +267 -0
- package/src/apps/debug/raw-sse-buffer.ts +449 -0
- package/src/apps/debug/raw-sse.ts +282 -0
- package/src/apps/debug/terminal-info.ts +115 -0
- package/src/apps/debug/viewer-frame.ts +174 -0
- package/src/apps/git/avatar.ts +52 -0
- package/src/apps/git/colors.ts +109 -0
- package/src/apps/git/diff-pane.ts +1512 -0
- package/src/apps/git/git-tui.ts +889 -0
- package/src/apps/git/sidebar.ts +1204 -0
- package/src/apps/git/state.ts +113 -0
- package/src/apps/if-bench-board.ts +324 -0
- package/src/apps/live-visualizer.ts +238 -0
- package/src/apps/ps-data.ts +116 -0
- package/src/apps/ps-top.ts +422 -0
- package/src/apps/session-picker.ts +95 -0
- package/src/apps/setup-model-picker.ts +21 -0
- package/src/apps/standalone-picker.ts +111 -0
- package/src/autocomplete.ts +9 -13
- package/src/chat/advisor-message.ts +175 -0
- package/src/chat/assistant-message.ts +1214 -0
- package/src/chat/background-tan-message.ts +35 -0
- package/src/chat/bash-execution.ts +394 -0
- package/src/chat/cache-invalidation-marker.ts +94 -0
- package/src/chat/chat-transcript-builder.ts +593 -0
- package/src/chat/collab-prompt-message.ts +34 -0
- package/src/chat/compaction-summary-message.ts +261 -0
- package/src/chat/custom-message.ts +23 -0
- package/src/chat/display-preferences.ts +24 -0
- package/src/chat/eval-execution.ts +172 -0
- package/src/chat/execution-shared.ts +113 -0
- package/src/chat/extension-types.ts +46 -0
- package/src/chat/hook-message.ts +20 -0
- package/src/chat/image-loading.ts +122 -0
- package/src/chat/late-diagnostics-message.ts +92 -0
- package/src/chat/messages.ts +305 -0
- package/src/chat/reaction.ts +65 -0
- package/src/chat/read-target.ts +7 -0
- package/src/chat/read-tool-group.ts +873 -0
- package/src/chat/served-model-marker.ts +91 -0
- package/src/chat/skill-message.ts +220 -0
- package/src/chat/skill-title-input.ts +41 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +35 -0
- package/src/chat/thinking-display.ts +312 -0
- package/src/chat/todo-reminder.ts +33 -0
- package/src/chat/tool-execution.ts +1395 -0
- package/src/chat/transcript-browser.ts +268 -0
- package/src/chat/transcript-entry.ts +96 -0
- package/src/chat/transcript-outline.ts +260 -0
- package/src/chat/transcript-render-helpers.ts +315 -0
- package/src/chat/ttsr-notification.ts +123 -0
- package/src/chat/user-message.ts +287 -0
- package/src/chrome/chat-block.ts +110 -0
- package/src/chrome/collab-qrcode.ts +74 -0
- package/src/chrome/context-thresholds.ts +85 -0
- package/src/chrome/countdown-timer.ts +74 -0
- package/src/chrome/diff.ts +266 -0
- package/src/chrome/dynamic-border.ts +36 -0
- package/src/chrome/error-block.ts +63 -0
- package/src/chrome/form-theme.ts +10 -0
- package/src/chrome/format.ts +66 -0
- package/src/chrome/index.ts +21 -0
- package/src/chrome/keybinding-hints.ts +55 -0
- package/src/chrome/live-board.ts +123 -0
- package/src/chrome/local-date.ts +20 -0
- package/src/chrome/message-divider.ts +51 -0
- package/src/chrome/message-frame.ts +164 -0
- package/src/chrome/message-notice.ts +103 -0
- package/src/chrome/overlay-box.ts +301 -0
- package/src/chrome/qrcode.ts +539 -0
- package/src/chrome/segment-track.ts +86 -0
- package/src/chrome/select-list-mouse-routing.ts +11 -0
- package/src/chrome/selector-helpers.ts +119 -0
- package/src/chrome/shared.ts +27 -0
- package/src/chrome/streaming-panel.ts +72 -0
- package/src/chrome/tool-activity.ts +44 -0
- package/src/chrome/transcript-container.ts +902 -0
- package/src/chrome/transcript-status.ts +27 -0
- package/src/chrome/visual-truncate.ts +70 -0
- package/src/components/disclosure.ts +235 -0
- package/src/components/editor.ts +10 -12
- package/src/components/form.ts +566 -0
- package/src/components/input.ts +6 -27
- package/src/components/key-value-list.ts +88 -0
- package/src/components/layout/geometry.ts +202 -0
- package/src/components/layout/row.ts +283 -0
- package/src/components/layout/split-pane.ts +349 -0
- package/src/components/layout/stack.ts +261 -0
- package/src/components/markdown.ts +16 -12
- package/src/components/menu-selection.ts +248 -0
- package/src/components/metric.ts +132 -0
- package/src/components/progress-bar.ts +140 -0
- package/src/components/scroll-view.ts +372 -70
- package/src/components/scroll-viewport.ts +154 -0
- package/src/components/section.ts +77 -0
- package/src/components/select-list.ts +238 -159
- package/src/components/settings-list.ts +103 -80
- package/src/components/table.ts +127 -0
- package/src/components/tree-view.ts +481 -0
- package/src/components/wizard-step.ts +229 -0
- package/src/deccara.ts +1 -3
- package/src/hotkeys-markdown.ts +100 -0
- package/src/index.ts +18 -0
- package/src/keybinding-matchers.ts +99 -0
- package/src/keys.ts +2 -2
- package/src/lang-from-path.ts +252 -0
- package/src/overlays/advisor-config.ts +761 -0
- package/src/overlays/agent-activity.ts +113 -0
- package/src/overlays/agent-hub-projection.ts +250 -0
- package/src/overlays/agent-hub-renderer.ts +281 -0
- package/src/overlays/agent-hub-types.ts +74 -0
- package/src/overlays/agent-hub.ts +1562 -0
- package/src/overlays/agent-transcript-viewer.ts +669 -0
- package/src/overlays/agents-hub.ts +1203 -0
- package/src/overlays/ask-dialog.ts +1202 -0
- package/src/overlays/bordered-loader.ts +41 -0
- package/src/overlays/btw-history-panel.ts +591 -0
- package/src/overlays/btw-history.ts +33 -0
- package/src/overlays/btw-panel.ts +167 -0
- package/src/overlays/cleanse-panel.ts +167 -0
- package/src/overlays/codex-reset-fireworks.ts +375 -0
- package/src/overlays/composer-shape-preview.ts +137 -0
- package/src/overlays/composer-shape-registry.ts +82 -0
- package/src/overlays/copy-selector.ts +618 -0
- package/src/overlays/copy-targets.ts +210 -0
- package/src/overlays/error-banner.ts +39 -0
- package/src/overlays/extensions/display-text.ts +39 -0
- package/src/overlays/extensions/extension-dashboard.ts +645 -0
- package/src/overlays/extensions/extension-list.ts +667 -0
- package/src/overlays/extensions/inspector-model.ts +484 -0
- package/src/overlays/extensions/inspector-panel.ts +669 -0
- package/src/overlays/extensions/live-tool-session.ts +67 -0
- package/src/overlays/extensions/mcp-runtime.ts +289 -0
- package/src/overlays/extensions/state-manager.ts +337 -0
- package/src/overlays/extensions/types.ts +208 -0
- package/src/overlays/history-search.ts +268 -0
- package/src/overlays/hook-editor.ts +272 -0
- package/src/overlays/hook-input.ts +84 -0
- package/src/overlays/hook-selector.ts +635 -0
- package/src/overlays/hub-frame.ts +262 -0
- package/src/overlays/login-dialog.ts +231 -0
- package/src/overlays/logout-account-selector.ts +115 -0
- package/src/overlays/mcp-add-wizard.ts +1436 -0
- package/src/overlays/model-browser.ts +1176 -0
- package/src/overlays/model-hub.ts +2279 -0
- package/src/overlays/model-picker.ts +285 -0
- package/src/overlays/model-selector.ts +107 -0
- package/src/overlays/move-overlay.ts +197 -0
- package/src/overlays/oauth-selector.ts +446 -0
- package/src/overlays/omfg-panel.ts +136 -0
- package/src/overlays/pause-screen.ts +198 -0
- package/src/overlays/plan-review-overlay.ts +1227 -0
- package/src/overlays/plan-save-overlay.ts +74 -0
- package/src/overlays/plan-toc.ts +139 -0
- package/src/overlays/plugin-selector.ts +97 -0
- package/src/overlays/plugin-settings.ts +839 -0
- package/src/overlays/queue-mode-selector.ts +55 -0
- package/src/overlays/reset-usage-selector.ts +170 -0
- package/src/overlays/rewind-selector.ts +499 -0
- package/src/overlays/running-subagent-badge.ts +19 -0
- package/src/overlays/session-account-selector.ts +68 -0
- package/src/overlays/session-info-overlay.ts +96 -0
- package/src/overlays/session-observer-registry.ts +289 -0
- package/src/overlays/session-selector.ts +1137 -0
- package/src/overlays/settings-defs.ts +315 -0
- package/src/overlays/settings-selector.ts +1415 -0
- package/src/overlays/show-images-selector.ts +44 -0
- package/src/overlays/snapcompact-shape-preview-doc.md +14 -0
- package/src/overlays/snapcompact-shape-preview.ts +192 -0
- package/src/overlays/theme-selector.ts +62 -0
- package/src/overlays/thinking-selector.ts +51 -0
- package/src/overlays/tiny-title-download-progress.ts +102 -0
- package/src/overlays/tree-selector.ts +1121 -0
- package/src/overlays/usage-dashboard.ts +629 -0
- package/src/overlays/usage-display.ts +45 -0
- package/src/overlays/usage-row.ts +118 -0
- package/src/prompt/attachment-chips.ts +201 -0
- package/src/prompt/composer-attachments.ts +280 -0
- package/src/prompt/composer-cache.ts +304 -0
- package/src/prompt/composer.ts +934 -0
- package/src/prompt/custom-editor.ts +1392 -0
- package/src/prompt/data/emojis.json +1 -0
- package/src/prompt/editor-top-gap.ts +28 -0
- package/src/prompt/emoji-autocomplete.ts +285 -0
- package/src/prompt/github-ref-autocomplete.ts +75 -0
- package/src/prompt/gradient-highlight.ts +101 -0
- package/src/prompt/image-format.ts +28 -0
- package/src/prompt/image-references.ts +102 -0
- package/src/prompt/interactive-context-helpers.ts +126 -0
- package/src/prompt/internal-url-autocomplete.ts +155 -0
- package/src/prompt/macos-spelling.ts +456 -0
- package/src/prompt/magic-keyword-boundary.ts +23 -0
- package/src/prompt/magic-keywords.ts +42 -0
- package/src/prompt/markdown-prose.ts +245 -0
- package/src/prompt/model-mention-autocomplete.ts +94 -0
- package/src/prompt/model-mention-syntax.ts +41 -0
- package/src/prompt/orchestrate.ts +26 -0
- package/src/prompt/prompt-action-autocomplete.ts +337 -0
- package/src/prompt/queue-input.ts +132 -0
- package/src/prompt/skill-tokens.ts +36 -0
- package/src/prompt/tips.txt +27 -0
- package/src/prompt/tools-markdown.ts +29 -0
- package/src/prompt/ultrathink.ts +26 -0
- package/src/prompt/usage-amounts.ts +99 -0
- package/src/prompt/video.ts +47 -0
- package/src/prompt/welcome.ts +605 -0
- package/src/prompt/workflow.ts +26 -0
- package/src/render/code-cell.ts +244 -0
- package/src/render/file-list.ts +58 -0
- package/src/render/hyperlink.ts +192 -0
- package/src/render/index.ts +17 -0
- package/src/render/output-block.ts +267 -0
- package/src/render/output-pane.ts +299 -0
- package/src/render/render-utils.ts +1182 -0
- package/src/render/sixel.ts +69 -0
- package/src/render/status-line.ts +55 -0
- package/src/render/tool-card.ts +272 -0
- package/src/render/tree-list.ts +188 -0
- package/src/render/types.ts +19 -0
- package/src/render/utils.ts +109 -0
- package/src/render/width-aware-text.ts +60 -0
- package/src/setup/lazy.ts +17 -0
- package/src/setup/scenes/composer.ts +127 -0
- package/src/setup/scenes/glyph.ts +120 -0
- package/src/setup/scenes/model.ts +138 -0
- package/src/setup/scenes/outro.ts +24 -0
- package/src/setup/scenes/providers.ts +107 -0
- package/src/setup/scenes/sign-in.ts +373 -0
- package/src/setup/scenes/splash.ts +192 -0
- package/src/setup/scenes/theme.ts +343 -0
- package/src/setup/scenes/types.ts +111 -0
- package/src/setup/scenes/web-search.ts +165 -0
- package/src/setup/setup-version.ts +11 -0
- package/src/setup/startup-splash.ts +107 -0
- package/src/setup/wizard-overlay.ts +319 -0
- package/src/setup/wizard.ts +101 -0
- package/src/status-line/component.ts +3003 -0
- package/src/status-line/context-usage.ts +688 -0
- package/src/status-line/footer.ts +323 -0
- package/src/status-line/git-utils.ts +42 -0
- package/src/status-line/host.ts +97 -0
- package/src/status-line/index.ts +6 -0
- package/src/status-line/loop.ts +28 -0
- package/src/status-line/metrics.ts +94 -0
- package/src/status-line/presets.ts +107 -0
- package/src/status-line/schema.ts +57 -0
- package/src/status-line/segments.ts +934 -0
- package/src/status-line/separators.ts +55 -0
- package/src/status-line/types.ts +227 -0
- package/src/stdin-buffer.ts +4 -2
- package/src/theme/color.ts +95 -0
- package/src/theme/dark.json +95 -0
- package/src/theme/defaults/alabaster.json +93 -0
- package/src/theme/defaults/amethyst.json +96 -0
- package/src/theme/defaults/anthracite.json +93 -0
- package/src/theme/defaults/basalt.json +91 -0
- package/src/theme/defaults/birch.json +95 -0
- package/src/theme/defaults/dark-abyss.json +91 -0
- package/src/theme/defaults/dark-arctic.json +104 -0
- package/src/theme/defaults/dark-aurora.json +95 -0
- package/src/theme/defaults/dark-catppuccin.json +107 -0
- package/src/theme/defaults/dark-cavern.json +91 -0
- package/src/theme/defaults/dark-celestial.json +106 -0
- package/src/theme/defaults/dark-copper.json +95 -0
- package/src/theme/defaults/dark-cosmos.json +90 -0
- package/src/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/theme/defaults/dark-dracula.json +98 -0
- package/src/theme/defaults/dark-eclipse.json +91 -0
- package/src/theme/defaults/dark-ember.json +95 -0
- package/src/theme/defaults/dark-equinox.json +90 -0
- package/src/theme/defaults/dark-forest.json +96 -0
- package/src/theme/defaults/dark-github.json +105 -0
- package/src/theme/defaults/dark-gruvbox.json +112 -0
- package/src/theme/defaults/dark-lavender.json +95 -0
- package/src/theme/defaults/dark-lunar.json +89 -0
- package/src/theme/defaults/dark-midnight.json +95 -0
- package/src/theme/defaults/dark-monochrome.json +94 -0
- package/src/theme/defaults/dark-monokai.json +98 -0
- package/src/theme/defaults/dark-nebula.json +90 -0
- package/src/theme/defaults/dark-nord.json +98 -0
- package/src/theme/defaults/dark-ocean.json +101 -0
- package/src/theme/defaults/dark-one.json +100 -0
- package/src/theme/defaults/dark-poimandres.json +115 -0
- package/src/theme/defaults/dark-rainforest.json +91 -0
- package/src/theme/defaults/dark-reef.json +91 -0
- package/src/theme/defaults/dark-retro.json +92 -0
- package/src/theme/defaults/dark-rose-pine.json +96 -0
- package/src/theme/defaults/dark-sakura.json +95 -0
- package/src/theme/defaults/dark-slate.json +95 -0
- package/src/theme/defaults/dark-solarized.json +97 -0
- package/src/theme/defaults/dark-solstice.json +90 -0
- package/src/theme/defaults/dark-starfall.json +91 -0
- package/src/theme/defaults/dark-sunset.json +99 -0
- package/src/theme/defaults/dark-swamp.json +90 -0
- package/src/theme/defaults/dark-synthwave.json +103 -0
- package/src/theme/defaults/dark-taiga.json +91 -0
- package/src/theme/defaults/dark-terminal.json +95 -0
- package/src/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/theme/defaults/dark-tundra.json +91 -0
- package/src/theme/defaults/dark-twilight.json +91 -0
- package/src/theme/defaults/dark-volcanic.json +91 -0
- package/src/theme/defaults/graphite.json +92 -0
- package/src/theme/defaults/index.ts +201 -0
- package/src/theme/defaults/light-arctic.json +107 -0
- package/src/theme/defaults/light-aurora-day.json +91 -0
- package/src/theme/defaults/light-canyon.json +91 -0
- package/src/theme/defaults/light-catppuccin.json +106 -0
- package/src/theme/defaults/light-cirrus.json +90 -0
- package/src/theme/defaults/light-coral.json +95 -0
- package/src/theme/defaults/light-cyberpunk.json +96 -0
- package/src/theme/defaults/light-dawn.json +90 -0
- package/src/theme/defaults/light-dunes.json +91 -0
- package/src/theme/defaults/light-eucalyptus.json +95 -0
- package/src/theme/defaults/light-forest.json +100 -0
- package/src/theme/defaults/light-frost.json +95 -0
- package/src/theme/defaults/light-github.json +115 -0
- package/src/theme/defaults/light-glacier.json +91 -0
- package/src/theme/defaults/light-gruvbox.json +108 -0
- package/src/theme/defaults/light-haze.json +90 -0
- package/src/theme/defaults/light-honeycomb.json +95 -0
- package/src/theme/defaults/light-lagoon.json +91 -0
- package/src/theme/defaults/light-lavender.json +95 -0
- package/src/theme/defaults/light-meadow.json +91 -0
- package/src/theme/defaults/light-mint.json +95 -0
- package/src/theme/defaults/light-monochrome.json +101 -0
- package/src/theme/defaults/light-ocean.json +99 -0
- package/src/theme/defaults/light-one.json +99 -0
- package/src/theme/defaults/light-opal.json +91 -0
- package/src/theme/defaults/light-orchard.json +91 -0
- package/src/theme/defaults/light-paper.json +95 -0
- package/src/theme/defaults/light-poimandres.json +115 -0
- package/src/theme/defaults/light-prism.json +90 -0
- package/src/theme/defaults/light-retro.json +98 -0
- package/src/theme/defaults/light-sand.json +95 -0
- package/src/theme/defaults/light-savanna.json +91 -0
- package/src/theme/defaults/light-solarized.json +102 -0
- package/src/theme/defaults/light-soleil.json +90 -0
- package/src/theme/defaults/light-sunset.json +99 -0
- package/src/theme/defaults/light-synthwave.json +98 -0
- package/src/theme/defaults/light-tokyo-night.json +111 -0
- package/src/theme/defaults/light-wetland.json +91 -0
- package/src/theme/defaults/light-zenith.json +89 -0
- package/src/theme/defaults/limestone.json +94 -0
- package/src/theme/defaults/mahogany.json +97 -0
- package/src/theme/defaults/marble.json +93 -0
- package/src/theme/defaults/obsidian.json +91 -0
- package/src/theme/defaults/onyx.json +91 -0
- package/src/theme/defaults/pearl.json +93 -0
- package/src/theme/defaults/porcelain.json +91 -0
- package/src/theme/defaults/quartz.json +96 -0
- package/src/theme/defaults/sandstone.json +95 -0
- package/src/theme/defaults/titanium.json +90 -0
- package/src/theme/index.ts +5 -0
- package/src/theme/light.json +93 -0
- package/src/theme/loader.ts +200 -0
- package/src/theme/mermaid-cache.ts +92 -0
- package/src/theme/schema-validation.ts +119 -0
- package/src/theme/schema.ts +168 -0
- package/src/theme/session-color.ts +253 -0
- package/src/theme/shimmer.ts +307 -0
- package/src/theme/symbols.ts +1433 -0
- package/src/theme/theme-class.ts +787 -0
- package/src/theme/theme-schema.json +463 -0
- package/src/theme/theme.ts +810 -0
- package/src/theme/tui-adapters.ts +339 -0
- package/src/thinking.ts +380 -0
- package/src/tools/agent-tree.ts +128 -0
- package/src/tools/ask.ts +482 -0
- package/src/tools/ast-edit.ts +210 -0
- package/src/tools/ast-grep.ts +171 -0
- package/src/tools/autoresearch.ts +287 -0
- package/src/tools/bash-interactive.ts +295 -0
- package/src/tools/bash.ts +468 -0
- package/src/tools/conflict-detect.ts +77 -0
- package/src/tools/debug.ts +167 -0
- package/src/tools/default-renderer.ts +172 -0
- package/src/tools/edit.ts +1258 -0
- package/src/tools/eval-format/code-mode-declarations.ts +61 -0
- package/src/tools/eval-format/index.ts +16 -0
- package/src/tools/eval-format/javascript.ts +952 -0
- package/src/tools/eval-format/python.ts +544 -0
- package/src/tools/eval.ts +835 -0
- package/src/tools/fetch.ts +226 -0
- package/src/tools/gh-format.ts +18 -0
- package/src/tools/github.ts +686 -0
- package/src/tools/glob.ts +213 -0
- package/src/tools/goal.ts +153 -0
- package/src/tools/grep.ts +385 -0
- package/src/tools/grouped-file-output.ts +211 -0
- package/src/tools/hashline-format.ts +59 -0
- package/src/tools/hub.ts +1488 -0
- package/src/tools/index.ts +71 -0
- package/src/tools/json-tree.ts +388 -0
- package/src/tools/line-ranges.ts +98 -0
- package/src/tools/list-limit.ts +43 -0
- package/src/tools/lsp.ts +702 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/mcp.ts +309 -0
- package/src/tools/memory.ts +220 -0
- package/src/tools/output-meta.ts +367 -0
- package/src/tools/read.ts +628 -0
- package/src/tools/renderer.ts +107 -0
- package/src/tools/report-tool-issue.ts +13 -0
- package/src/tools/resolve.ts +139 -0
- package/src/tools/streaming-output.ts +1576 -0
- package/src/tools/subprocess.ts +39 -0
- package/src/tools/task-repair-args.ts +118 -0
- package/src/tools/task-yield-assembly.ts +147 -0
- package/src/tools/task.ts +2110 -0
- package/src/tools/terminal-output.ts +153 -0
- package/src/tools/think.ts +28 -0
- package/src/tools/todo.ts +580 -0
- package/src/tools/tool-errors.ts +15 -0
- package/src/tools/vibe.ts +420 -0
- package/src/tools/web-search.ts +409 -0
- package/src/tools/write.ts +511 -0
- package/src/tools/xd-url.ts +28 -0
- package/src/tools/xdev.ts +201 -0
- package/src/tui.ts +57 -4
- package/src/utils.ts +8 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { popLoopPhase, pushLoopPhase } from "@oh-my-pi/pi-utils";
|
|
2
|
-
import {
|
|
2
|
+
import { getMenuWindow, MenuSelection } from "./menu-selection";
|
|
3
3
|
import { getKeybindings } from "../keybindings";
|
|
4
|
-
import { extractPrintableText } from "../keys";
|
|
4
|
+
import { extractPrintableText, matchesKey } from "../keys";
|
|
5
5
|
import { type MouseRoutable, routeSelectListMouse, type SgrMouseEvent } from "../mouse";
|
|
6
6
|
import type { SymbolTheme } from "../symbols";
|
|
7
7
|
import type { Component } from "../tui";
|
|
@@ -31,6 +31,12 @@ export interface SelectItem {
|
|
|
31
31
|
icon?: string;
|
|
32
32
|
/** Dim hint text shown inline after cursor when this item is selected */
|
|
33
33
|
hint?: string;
|
|
34
|
+
/** Disabled rows stay visible but are skipped by navigation and cannot activate. */
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/** When set, activation requires a second Enter/click and this text becomes the status line. */
|
|
37
|
+
confirmation?: string;
|
|
38
|
+
/** Additional text included by the default fuzzy filter without being rendered. */
|
|
39
|
+
searchText?: string;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export interface SelectListTheme {
|
|
@@ -54,12 +60,48 @@ export interface SelectListTruncatePrimaryContext {
|
|
|
54
60
|
isSelected: boolean;
|
|
55
61
|
}
|
|
56
62
|
|
|
63
|
+
/** State supplied to a rich SelectList row renderer or measurer. */
|
|
64
|
+
export interface SelectListRenderItemContext {
|
|
65
|
+
item: SelectItem;
|
|
66
|
+
index: number;
|
|
67
|
+
width: number;
|
|
68
|
+
selected: boolean;
|
|
69
|
+
hovered: boolean;
|
|
70
|
+
pendingConfirmation: boolean;
|
|
71
|
+
theme: SelectListTheme;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Current controlled menu state supplied to a custom status renderer. */
|
|
75
|
+
export interface SelectListStatusContext {
|
|
76
|
+
query: string;
|
|
77
|
+
selectedIndex: number;
|
|
78
|
+
visibleCount: number;
|
|
79
|
+
totalCount: number;
|
|
80
|
+
pendingItem: SelectItem | undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
57
83
|
export interface SelectListLayoutOptions {
|
|
58
84
|
minPrimaryColumnWidth?: number;
|
|
59
85
|
maxPrimaryColumnWidth?: number;
|
|
60
86
|
truncatePrimary?: (context: SelectListTruncatePrimaryContext) => string;
|
|
61
87
|
/** Enable type-to-filter search when the item count exceeds maxVisible. Defaults to true. */
|
|
62
88
|
overflowSearch?: boolean;
|
|
89
|
+
/** Search activation policy. `overflowSearch` remains authoritative when this is omitted. */
|
|
90
|
+
search?: "overflow" | "always" | "never";
|
|
91
|
+
/** Domain-specific filtering/ranking. Selection is retained by item value when possible. */
|
|
92
|
+
filterItems?: (items: readonly SelectItem[], query: string) => readonly SelectItem[];
|
|
93
|
+
/** Custom rich-row renderer. Every returned line is mouse-hit-tested as the same item. */
|
|
94
|
+
renderItem?: (context: SelectListRenderItemContext) => readonly string[];
|
|
95
|
+
/** Cheap row measurement for custom renderers; defaults to calling renderItem and reading its length. */
|
|
96
|
+
measureItem?: (context: SelectListRenderItemContext) => number;
|
|
97
|
+
/** Empty-list message (before a query is entered). */
|
|
98
|
+
emptyText?: string;
|
|
99
|
+
/** No-match message (after filtering). */
|
|
100
|
+
noMatchText?: string;
|
|
101
|
+
/** Optional status renderer. Return undefined to omit the status row. */
|
|
102
|
+
statusText?: (context: SelectListStatusContext) => string | undefined;
|
|
103
|
+
/** Whether single-step keyboard navigation wraps at the edges. Defaults to true. */
|
|
104
|
+
wrapNavigation?: boolean;
|
|
63
105
|
/**
|
|
64
106
|
* Wrap long descriptions onto continuation rows indented under the
|
|
65
107
|
* description column instead of truncating. Defaults to false so existing
|
|
@@ -95,10 +137,19 @@ type SelectItemLayout =
|
|
|
95
137
|
};
|
|
96
138
|
|
|
97
139
|
export class SelectList implements Component, MouseRoutable {
|
|
140
|
+
/**
|
|
141
|
+
* Sanitized `{label, description}` per item object. `sanitizeSingleLine`
|
|
142
|
+
* is 3 passes + 2 regex execs per call and render() used to run it up to
|
|
143
|
+
* 3x per item per frame (column widths, row counts, item render). Items
|
|
144
|
+
* are host-owned and stable across frames; the map is cleared when the
|
|
145
|
+
* visible item list identity changes.
|
|
146
|
+
*/
|
|
147
|
+
#sanitized = new WeakMap<
|
|
148
|
+
SelectItem,
|
|
149
|
+
{ sourceLabel: string; sourceDescription: string | undefined; label: string; description: string | undefined }
|
|
150
|
+
>();
|
|
98
151
|
#maxVisible: number;
|
|
99
|
-
#
|
|
100
|
-
#filterQuery = "";
|
|
101
|
-
#selectedIndex: number = 0;
|
|
152
|
+
#selection: MenuSelection<SelectItem>;
|
|
102
153
|
#hoveredIndex: number | null = null;
|
|
103
154
|
/** Per-render map of 0-based output line → filtered-item index. */
|
|
104
155
|
#hitRows: (number | undefined)[] = [];
|
|
@@ -108,24 +159,31 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
108
159
|
onSelectionChange?: (item: SelectItem) => void;
|
|
109
160
|
|
|
110
161
|
constructor(
|
|
111
|
-
|
|
162
|
+
items: ReadonlyArray<SelectItem>,
|
|
112
163
|
maxVisible: number,
|
|
113
164
|
private readonly theme: SelectListTheme,
|
|
114
165
|
private readonly layout: SelectListLayoutOptions = {},
|
|
115
166
|
) {
|
|
116
167
|
this.#maxVisible = Math.max(1, Math.trunc(maxVisible));
|
|
117
|
-
this.#
|
|
168
|
+
this.#selection = new MenuSelection(items, {
|
|
169
|
+
getKey: item => item.value,
|
|
170
|
+
getSearchText: item => this.#getFilterText(item),
|
|
171
|
+
isDisabled: item => item.disabled === true,
|
|
172
|
+
requiresConfirmation: item => item.confirmation !== undefined,
|
|
173
|
+
filter: layout.filterItems,
|
|
174
|
+
});
|
|
118
175
|
}
|
|
119
176
|
/** Return item, selection, and filter state for debug inspection. */
|
|
120
177
|
debugState(): Record<string, unknown> {
|
|
121
|
-
const selected = this.#
|
|
178
|
+
const selected = this.#selection.selectedItem;
|
|
122
179
|
return {
|
|
123
|
-
itemCount: this.items.length,
|
|
124
|
-
filteredItemCount: this.#
|
|
125
|
-
selectedIndex: this.#
|
|
180
|
+
itemCount: this.#selection.items.length,
|
|
181
|
+
filteredItemCount: this.#selection.visibleItems.length,
|
|
182
|
+
selectedIndex: this.#selection.selectedIndex,
|
|
126
183
|
selectedItemId: selected?.value ?? null,
|
|
127
184
|
selectedItemLabel: selected?.label ?? null,
|
|
128
|
-
filterText: this.#
|
|
185
|
+
filterText: this.#selection.query,
|
|
186
|
+
pendingItemId: this.#selection.pendingKey ?? null,
|
|
129
187
|
maxVisible: this.#maxVisible,
|
|
130
188
|
};
|
|
131
189
|
}
|
|
@@ -139,8 +197,22 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
139
197
|
this.#setFilter(filter, true);
|
|
140
198
|
}
|
|
141
199
|
|
|
200
|
+
/** Replace controlled items while retaining the selected value when possible. */
|
|
201
|
+
setItems(items: readonly SelectItem[]): void {
|
|
202
|
+
if (this.#selection.setItems(items)) this.#notifySelectionChange();
|
|
203
|
+
}
|
|
204
|
+
|
|
142
205
|
setSelectedIndex(index: number): void {
|
|
143
|
-
this.#
|
|
206
|
+
this.#selection.setSelectedIndex(index);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Select a visible item by its stable value. */
|
|
210
|
+
setSelectedValue(value: string): void {
|
|
211
|
+
this.#selection.setSelectedKey(value);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
getFilter(): string {
|
|
215
|
+
return this.#selection.query;
|
|
144
216
|
}
|
|
145
217
|
|
|
146
218
|
/** Resolve a 0-based rendered-line index to a filtered-item index. */
|
|
@@ -155,22 +227,15 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
155
227
|
|
|
156
228
|
/** Move the selection one step for a wheel notch. */
|
|
157
229
|
handleWheel(delta: -1 | 1): void {
|
|
158
|
-
if (this.#
|
|
159
|
-
const next = clamp(this.#selectedIndex + delta, 0, this.#filteredItems.length - 1);
|
|
160
|
-
if (next === this.#selectedIndex) return;
|
|
161
|
-
this.#selectedIndex = next;
|
|
162
|
-
this.#notifySelectionChange();
|
|
230
|
+
if (this.#selection.move(delta)) this.#notifySelectionChange();
|
|
163
231
|
}
|
|
164
232
|
|
|
165
|
-
/** Mouse click: select the item under the pointer and
|
|
233
|
+
/** Mouse click: select the item under the pointer and request activation. */
|
|
166
234
|
clickItem(index: number): void {
|
|
167
|
-
const item = this.#
|
|
168
|
-
if (!item) return;
|
|
169
|
-
if (index
|
|
170
|
-
|
|
171
|
-
this.#notifySelectionChange();
|
|
172
|
-
}
|
|
173
|
-
this.onSelect?.(item);
|
|
235
|
+
const item = this.#selection.visibleItems[index];
|
|
236
|
+
if (!item || item.disabled) return;
|
|
237
|
+
if (this.#selection.setSelectedIndex(index)) this.#notifySelectionChange();
|
|
238
|
+
this.#activateSelected();
|
|
174
239
|
}
|
|
175
240
|
|
|
176
241
|
routeMouse(event: SgrMouseEvent, line: number, _col: number): void {
|
|
@@ -184,14 +249,18 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
184
249
|
render(width: number): readonly string[] {
|
|
185
250
|
const lines: string[] = [];
|
|
186
251
|
this.#hitRows = [];
|
|
187
|
-
|
|
252
|
+
let showSearchStatus = this.#shouldRenderSearchStatus();
|
|
188
253
|
|
|
189
|
-
// If no items match filter,
|
|
190
|
-
if (this.#
|
|
254
|
+
// If no items match filter, distinguish an empty data set from no search matches.
|
|
255
|
+
if (this.#selection.visibleItems.length === 0) {
|
|
191
256
|
if (showSearchStatus) {
|
|
192
257
|
lines.push(this.#renderStatusLine(width));
|
|
193
258
|
}
|
|
194
|
-
|
|
259
|
+
const message =
|
|
260
|
+
this.#selection.query.trim().length > 0
|
|
261
|
+
? (this.layout.noMatchText ?? "No matching items")
|
|
262
|
+
: (this.layout.emptyText ?? "No items");
|
|
263
|
+
lines.push(this.theme.noMatch(` ${message}`));
|
|
195
264
|
return lines;
|
|
196
265
|
}
|
|
197
266
|
|
|
@@ -204,31 +273,35 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
204
273
|
|
|
205
274
|
// Compute per-item visual row counts at the conservative width (i.e.
|
|
206
275
|
// assume the scrollbar column might be reserved). For non-wrap layouts
|
|
207
|
-
// every count is 1, so
|
|
208
|
-
// back to the original `N > maxVisible` predicate exactly.
|
|
276
|
+
// every count is 1, so total visual rows equal the visible item count.
|
|
209
277
|
const conservativeRowWidth = Math.max(0, width - 1);
|
|
210
278
|
// oxlint-disable-next-line unicorn/no-new-array -- length preallocation
|
|
211
|
-
const rowCounts = new Array<number>(this.#
|
|
212
|
-
let
|
|
213
|
-
|
|
214
|
-
const item = this.#filteredItems[i];
|
|
279
|
+
const rowCounts = new Array<number>(this.#selection.visibleItems.length);
|
|
280
|
+
for (let i = 0; i < this.#selection.visibleItems.length; i++) {
|
|
281
|
+
const item = this.#selection.visibleItems[i];
|
|
215
282
|
if (!item) {
|
|
216
283
|
rowCounts[i] = 0;
|
|
217
284
|
continue;
|
|
218
285
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
286
|
+
const context = this.#renderContext(item, i, conservativeRowWidth);
|
|
287
|
+
rowCounts[i] = this.layout.measureItem
|
|
288
|
+
? Math.max(1, Math.trunc(this.layout.measureItem(context)))
|
|
289
|
+
: this.layout.renderItem
|
|
290
|
+
? Math.max(1, this.layout.renderItem(context).length)
|
|
291
|
+
: wrapEnabled
|
|
292
|
+
? this.#computeItemRowCount(item, conservativeRowWidth, primaryColumnWidth, iconColumnWidth)
|
|
293
|
+
: 1;
|
|
223
294
|
}
|
|
224
295
|
|
|
225
|
-
const
|
|
296
|
+
const window = getMenuWindow(rowCounts, this.#selection.selectedIndex, visualBudget);
|
|
297
|
+
const overflow = window.totalRows > visualBudget;
|
|
298
|
+
showSearchStatus = this.#shouldRenderSearchStatus();
|
|
226
299
|
const rowWidth = Math.max(0, width - (overflow ? 1 : 0));
|
|
227
300
|
|
|
228
301
|
// Pick a window centered on the selected item that fits in visualBudget
|
|
229
302
|
// rows. Falls through to the original item-count window when every row
|
|
230
303
|
// count is 1.
|
|
231
|
-
const { startIndex, endIndex,
|
|
304
|
+
const { startIndex, endIndex, rowOffset } = window;
|
|
232
305
|
|
|
233
306
|
// Render visible items. Cap rows at the budget so a single item that
|
|
234
307
|
// wraps to more than `visualBudget` rows (pathological — e.g. a 5-row
|
|
@@ -236,30 +309,36 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
236
309
|
// scrollbar carries the offscreen rows.
|
|
237
310
|
const rows: string[] = [];
|
|
238
311
|
for (let i = startIndex; i < endIndex && rows.length < visualBudget; i++) {
|
|
239
|
-
const item = this.#
|
|
312
|
+
const item = this.#selection.visibleItems[i];
|
|
240
313
|
if (!item) continue;
|
|
241
|
-
const
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
primaryColumnWidth,
|
|
247
|
-
iconColumnWidth,
|
|
248
|
-
);
|
|
314
|
+
const isSelected = i === this.#selection.selectedIndex;
|
|
315
|
+
const hovered = i === this.#hoveredIndex && !isSelected;
|
|
316
|
+
const context = this.#renderContext(item, i, rowWidth);
|
|
317
|
+
const itemRows = this.layout.renderItem
|
|
318
|
+
? [...this.layout.renderItem(context)]
|
|
319
|
+
: this.#renderItem(item, isSelected, rowWidth, primaryColumnWidth, iconColumnWidth);
|
|
249
320
|
for (const row of itemRows) {
|
|
250
321
|
if (rows.length >= visualBudget) break;
|
|
251
322
|
this.#hitRows[rows.length] = i;
|
|
252
|
-
|
|
323
|
+
const styled =
|
|
324
|
+
this.layout.renderItem !== undefined
|
|
325
|
+
? row
|
|
326
|
+
: item.disabled
|
|
327
|
+
? this.theme.description(row)
|
|
328
|
+
: hovered && this.theme.hovered
|
|
329
|
+
? this.theme.hovered(row)
|
|
330
|
+
: row;
|
|
331
|
+
rows.push(styled);
|
|
253
332
|
}
|
|
254
333
|
}
|
|
255
334
|
|
|
256
335
|
const sv = new ScrollView(rows, {
|
|
257
336
|
height: rows.length,
|
|
258
337
|
scrollbar: "auto",
|
|
259
|
-
totalRows:
|
|
338
|
+
totalRows: window.totalRows,
|
|
260
339
|
theme: { track: t => this.theme.scrollInfo(t), thumb: t => this.theme.selectedPrefix(t) },
|
|
261
340
|
});
|
|
262
|
-
sv.setScrollOffset(
|
|
341
|
+
sv.setScrollOffset(rowOffset);
|
|
263
342
|
lines.push(...sv.render(width));
|
|
264
343
|
|
|
265
344
|
// Add search status when relevant (scrollbar now indicates overflow)
|
|
@@ -272,46 +351,31 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
272
351
|
|
|
273
352
|
handleInput(keyData: string): void {
|
|
274
353
|
const kb = getKeybindings();
|
|
275
|
-
// Escape or Ctrl+C
|
|
276
354
|
if (kb.matches(keyData, "tui.select.cancel")) {
|
|
277
|
-
if (this.onCancel)
|
|
278
|
-
this.onCancel();
|
|
279
|
-
}
|
|
355
|
+
if (!this.#selection.cancelConfirmation()) this.onCancel?.();
|
|
280
356
|
return;
|
|
281
357
|
}
|
|
282
358
|
|
|
283
|
-
if (this.#handleSearchInput(keyData))
|
|
284
|
-
|
|
285
|
-
}
|
|
359
|
+
if (this.#handleSearchInput(keyData)) return;
|
|
360
|
+
if (this.#selection.visibleItems.length === 0) return;
|
|
286
361
|
|
|
287
|
-
|
|
288
|
-
// Up arrow - wrap to bottom when at top
|
|
362
|
+
let selectionChanged = false;
|
|
289
363
|
if (kb.matches(keyData, "tui.select.up")) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
this.#
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
else if (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// PageDown - jump down by one visible page
|
|
304
|
-
else if (kb.matches(keyData, "tui.select.pageDown")) {
|
|
305
|
-
this.#selectedIndex = Math.min(this.#filteredItems.length - 1, this.#selectedIndex + this.#maxVisible);
|
|
306
|
-
this.#notifySelectionChange();
|
|
307
|
-
}
|
|
308
|
-
// Enter
|
|
309
|
-
else if (kb.matches(keyData, "tui.select.confirm") || keyData === "\n") {
|
|
310
|
-
const selectedItem = this.#filteredItems[this.#selectedIndex];
|
|
311
|
-
if (selectedItem && this.onSelect) {
|
|
312
|
-
this.onSelect(selectedItem);
|
|
313
|
-
}
|
|
364
|
+
selectionChanged = this.#selection.move(-1, this.layout.wrapNavigation !== false);
|
|
365
|
+
} else if (kb.matches(keyData, "tui.select.down")) {
|
|
366
|
+
selectionChanged = this.#selection.move(1, this.layout.wrapNavigation !== false);
|
|
367
|
+
} else if (kb.matches(keyData, "tui.select.pageUp")) {
|
|
368
|
+
selectionChanged = this.#selection.move(-this.#maxVisible);
|
|
369
|
+
} else if (kb.matches(keyData, "tui.select.pageDown")) {
|
|
370
|
+
selectionChanged = this.#selection.move(this.#maxVisible);
|
|
371
|
+
} else if (matchesKey(keyData, "home")) {
|
|
372
|
+
selectionChanged = this.#selection.moveToBoundary("first");
|
|
373
|
+
} else if (matchesKey(keyData, "end")) {
|
|
374
|
+
selectionChanged = this.#selection.moveToBoundary("last");
|
|
375
|
+
} else if (kb.matches(keyData, "tui.select.confirm") || keyData === "\n") {
|
|
376
|
+
this.#activateSelected();
|
|
314
377
|
}
|
|
378
|
+
if (selectionChanged) this.#notifySelectionChange();
|
|
315
379
|
}
|
|
316
380
|
|
|
317
381
|
#renderItem(
|
|
@@ -378,54 +442,6 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
378
442
|
return kept;
|
|
379
443
|
}
|
|
380
444
|
|
|
381
|
-
/**
|
|
382
|
-
* Pick a contiguous window of items containing `selectedIndex` such that
|
|
383
|
-
* their visual rows fit within `budget`. Centers the selection roughly
|
|
384
|
-
* mid-window: first expands up by ⌊budget/2⌋ rows, then fills downward,
|
|
385
|
-
* then back upward with any remaining budget. For non-wrap layouts (every
|
|
386
|
-
* `rowCounts[i] === 1`) this resolves to the same `[start, start+maxVisible)`
|
|
387
|
-
* window the prior arithmetic produced.
|
|
388
|
-
*/
|
|
389
|
-
#pickWindow(
|
|
390
|
-
rowCounts: ReadonlyArray<number>,
|
|
391
|
-
budget: number,
|
|
392
|
-
): { startIndex: number; endIndex: number; visualOffset: number } {
|
|
393
|
-
const n = rowCounts.length;
|
|
394
|
-
const selected = Math.max(0, Math.min(this.#selectedIndex, n - 1));
|
|
395
|
-
if (n === 0) return { startIndex: 0, endIndex: 0, visualOffset: 0 };
|
|
396
|
-
|
|
397
|
-
const half = Math.floor(budget / 2);
|
|
398
|
-
let lo = selected;
|
|
399
|
-
let rowsAboveSelected = 0;
|
|
400
|
-
// Step 1: expand upward up to `half` rows above the selection so it
|
|
401
|
-
// lands near the visual middle, matching the prior centering.
|
|
402
|
-
while (lo > 0 && rowsAboveSelected + (rowCounts[lo - 1] ?? 0) <= half) {
|
|
403
|
-
lo--;
|
|
404
|
-
rowsAboveSelected += rowCounts[lo] ?? 0;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// Step 2: expand downward until the budget is filled. The selected
|
|
408
|
-
// item's own rows are always counted; if it alone exceeds `budget`
|
|
409
|
-
// the surplus is clipped at render time and the scrollbar carries it.
|
|
410
|
-
let hi = selected + 1;
|
|
411
|
-
let used = rowsAboveSelected + (rowCounts[selected] ?? 0);
|
|
412
|
-
while (hi < n && used + (rowCounts[hi] ?? 0) <= budget) {
|
|
413
|
-
used += rowCounts[hi] ?? 0;
|
|
414
|
-
hi++;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Step 3: if room remains (selection sat near the bottom), keep
|
|
418
|
-
// expanding upward.
|
|
419
|
-
while (lo > 0 && used + (rowCounts[lo - 1] ?? 0) <= budget) {
|
|
420
|
-
lo--;
|
|
421
|
-
used += rowCounts[lo] ?? 0;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
let visualOffset = 0;
|
|
425
|
-
for (let i = 0; i < lo; i++) visualOffset += rowCounts[i] ?? 0;
|
|
426
|
-
return { startIndex: lo, endIndex: hi, visualOffset };
|
|
427
|
-
}
|
|
428
|
-
|
|
429
445
|
#computeItemLayout(
|
|
430
446
|
item: SelectItem,
|
|
431
447
|
isSelected: boolean,
|
|
@@ -440,7 +456,7 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
440
456
|
const iconWidth = item.icon ? visibleWidth(item.icon) : 0;
|
|
441
457
|
const iconCell = iconColumnWidth > 0 ? (item.icon ?? "") + padding(iconColumnWidth - iconWidth + 1) : "";
|
|
442
458
|
const prefixWidth = visibleWidth(prefix) + (iconColumnWidth > 0 ? iconColumnWidth + 1 : 0);
|
|
443
|
-
const descriptionSingleLine =
|
|
459
|
+
const descriptionSingleLine = this.#sanitizedDescription(item);
|
|
444
460
|
|
|
445
461
|
if (descriptionSingleLine && width > 40) {
|
|
446
462
|
const effectivePrimaryColumnWidth = Math.max(1, Math.min(primaryColumnWidth, width - prefixWidth - 4));
|
|
@@ -478,7 +494,7 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
478
494
|
|
|
479
495
|
#getIconColumnWidth(): number {
|
|
480
496
|
let widest = 0;
|
|
481
|
-
for (const item of this.#
|
|
497
|
+
for (const item of this.#selection.visibleItems) {
|
|
482
498
|
if (item.icon) widest = Math.max(widest, visibleWidth(item.icon));
|
|
483
499
|
}
|
|
484
500
|
return widest;
|
|
@@ -486,7 +502,7 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
486
502
|
|
|
487
503
|
#getPrimaryColumnWidth(): number {
|
|
488
504
|
const { min, max } = this.#getPrimaryColumnBounds();
|
|
489
|
-
const widestPrimary = this.#
|
|
505
|
+
const widestPrimary = this.#selection.visibleItems.reduce((widest, item) => {
|
|
490
506
|
return Math.max(widest, visibleWidth(this.#getDisplayValue(item)) + PRIMARY_COLUMN_GAP);
|
|
491
507
|
}, 0);
|
|
492
508
|
|
|
@@ -521,23 +537,72 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
521
537
|
}
|
|
522
538
|
|
|
523
539
|
#getDisplayValue(item: SelectItem): string {
|
|
524
|
-
return
|
|
540
|
+
return this.#sanitizedLabel(item);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
#sanitizedLabel(item: SelectItem): string {
|
|
544
|
+
return this.#sanitizedEntry(item).label;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
#sanitizedDescription(item: SelectItem): string | undefined {
|
|
548
|
+
return this.#sanitizedEntry(item).description;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
#sanitizedEntry(item: SelectItem): { label: string; description: string | undefined } {
|
|
552
|
+
const sourceLabel = item.label || item.value;
|
|
553
|
+
const sourceDescription = item.description;
|
|
554
|
+
const cached = this.#sanitized.get(item);
|
|
555
|
+
if (
|
|
556
|
+
cached !== undefined &&
|
|
557
|
+
cached.sourceLabel === sourceLabel &&
|
|
558
|
+
cached.sourceDescription === sourceDescription
|
|
559
|
+
) {
|
|
560
|
+
return cached;
|
|
561
|
+
}
|
|
562
|
+
const entry = {
|
|
563
|
+
sourceLabel,
|
|
564
|
+
sourceDescription,
|
|
565
|
+
label: sanitizeSingleLine(sourceLabel),
|
|
566
|
+
description: sourceDescription ? sanitizeSingleLine(sourceDescription) : undefined,
|
|
567
|
+
};
|
|
568
|
+
this.#sanitized.set(item, entry);
|
|
569
|
+
return entry;
|
|
525
570
|
}
|
|
526
571
|
|
|
527
572
|
#renderStatusLine(width: number): string {
|
|
528
|
-
const
|
|
529
|
-
|
|
573
|
+
const pendingItem =
|
|
574
|
+
this.#selection.pendingKey === undefined
|
|
575
|
+
? undefined
|
|
576
|
+
: this.#selection.visibleItems.find(item => item.value === this.#selection.pendingKey);
|
|
577
|
+
const query = sanitizeSingleLine(this.#selection.query);
|
|
578
|
+
const custom = this.layout.statusText?.({
|
|
579
|
+
query,
|
|
580
|
+
selectedIndex: this.#selection.selectedIndex,
|
|
581
|
+
visibleCount: this.#selection.visibleItems.length,
|
|
582
|
+
totalCount: this.#selection.items.length,
|
|
583
|
+
pendingItem,
|
|
584
|
+
});
|
|
585
|
+
const statusText =
|
|
586
|
+
this.layout.statusText !== undefined
|
|
587
|
+
? (custom ?? "")
|
|
588
|
+
: (pendingItem?.confirmation ??
|
|
589
|
+
(query ? ` Search: ${query}` : this.#canEditSearch() ? " Type to search" : ""));
|
|
530
590
|
return this.theme.scrollInfo(truncateToWidth(statusText, Math.max(1, width - 2), Ellipsis.Omit));
|
|
531
591
|
}
|
|
532
592
|
|
|
533
593
|
#shouldRenderSearchStatus(): boolean {
|
|
594
|
+
const policy = this.layout.search ?? (this.layout.overflowSearch === false ? "never" : "overflow");
|
|
534
595
|
return (
|
|
535
|
-
this.
|
|
596
|
+
this.#selection.pendingKey !== undefined ||
|
|
597
|
+
this.layout.statusText !== undefined ||
|
|
598
|
+
(policy !== "never" && this.#selection.query.length > 0) ||
|
|
599
|
+
(this.#canEditSearch() && this.#selection.items.length > this.#maxVisible)
|
|
536
600
|
);
|
|
537
601
|
}
|
|
538
602
|
|
|
539
603
|
#canEditSearch(): boolean {
|
|
540
|
-
|
|
604
|
+
const policy = this.layout.search ?? (this.layout.overflowSearch === false ? "never" : "overflow");
|
|
605
|
+
return policy === "always" || (policy === "overflow" && this.#selection.items.length > this.#maxVisible);
|
|
541
606
|
}
|
|
542
607
|
|
|
543
608
|
#handleSearchInput(keyData: string): boolean {
|
|
@@ -545,8 +610,8 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
545
610
|
|
|
546
611
|
const kb = getKeybindings();
|
|
547
612
|
if (kb.matches(keyData, "tui.editor.deleteCharBackward")) {
|
|
548
|
-
if (this.#
|
|
549
|
-
const chars = [...this.#
|
|
613
|
+
if (this.#selection.query.length === 0) return false;
|
|
614
|
+
const chars = [...this.#selection.query];
|
|
550
615
|
chars.pop();
|
|
551
616
|
this.#setFilter(chars.join(""), true);
|
|
552
617
|
return true;
|
|
@@ -554,30 +619,25 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
554
619
|
|
|
555
620
|
const printableText = extractPrintableText(keyData);
|
|
556
621
|
if (printableText === undefined) return false;
|
|
557
|
-
if (this.#
|
|
622
|
+
if (this.#selection.query.length === 0 && printableText.trim().length === 0) return false;
|
|
558
623
|
|
|
559
|
-
this.#setFilter(this.#
|
|
624
|
+
this.#setFilter(this.#selection.query + printableText, true);
|
|
560
625
|
return true;
|
|
561
626
|
}
|
|
562
627
|
|
|
563
628
|
#setFilter(filter: string, notify: boolean): void {
|
|
564
|
-
|
|
629
|
+
let changed: boolean;
|
|
565
630
|
if (filter.trim()) {
|
|
566
|
-
// Breadcrumb the fuzzy match so the loop watchdog can attribute a
|
|
567
|
-
// large-list filter stall instead of logging it as "unknown".
|
|
568
631
|
pushLoopPhase("ui.select-filter");
|
|
569
632
|
try {
|
|
570
|
-
|
|
633
|
+
changed = this.#selection.setQuery(filter);
|
|
571
634
|
} finally {
|
|
572
635
|
popLoopPhase();
|
|
573
636
|
}
|
|
574
637
|
} else {
|
|
575
|
-
|
|
576
|
-
}
|
|
577
|
-
this.#selectedIndex = 0;
|
|
578
|
-
if (notify) {
|
|
579
|
-
this.#notifySelectionChange();
|
|
638
|
+
changed = this.#selection.setQuery(filter);
|
|
580
639
|
}
|
|
640
|
+
if (notify && changed) this.#notifySelectionChange();
|
|
581
641
|
}
|
|
582
642
|
|
|
583
643
|
#getFilterText(item: SelectItem): string {
|
|
@@ -588,18 +648,37 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
588
648
|
if (item.hint) {
|
|
589
649
|
text += ` ${item.hint}`;
|
|
590
650
|
}
|
|
651
|
+
if (item.searchText) {
|
|
652
|
+
text += ` ${item.searchText}`;
|
|
653
|
+
}
|
|
591
654
|
return sanitizeSingleLine(text);
|
|
592
655
|
}
|
|
593
656
|
|
|
657
|
+
#renderContext(item: SelectItem, index: number, width: number): SelectListRenderItemContext {
|
|
658
|
+
return {
|
|
659
|
+
item,
|
|
660
|
+
index,
|
|
661
|
+
width,
|
|
662
|
+
selected: index === this.#selection.selectedIndex,
|
|
663
|
+
hovered: index === this.#hoveredIndex,
|
|
664
|
+
pendingConfirmation: this.#selection.isPending(item),
|
|
665
|
+
theme: this.theme,
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
#activateSelected(): void {
|
|
670
|
+
const activation = this.#selection.requestActivation();
|
|
671
|
+
if (activation.kind === "confirmed") this.onSelect?.(activation.item);
|
|
672
|
+
}
|
|
673
|
+
|
|
594
674
|
#notifySelectionChange(): void {
|
|
595
|
-
const selectedItem = this.#
|
|
675
|
+
const selectedItem = this.#selection.selectedItem;
|
|
596
676
|
if (selectedItem && this.onSelectionChange) {
|
|
597
677
|
this.onSelectionChange(selectedItem);
|
|
598
678
|
}
|
|
599
679
|
}
|
|
600
680
|
|
|
601
681
|
getSelectedItem(): SelectItem | null {
|
|
602
|
-
|
|
603
|
-
return item || null;
|
|
682
|
+
return this.#selection.selectedItem ?? null;
|
|
604
683
|
}
|
|
605
684
|
}
|