@dst0/p-tui 0.4.41 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autocomplete.d.ts.map +1 -1
- package/dist/autocomplete.js.map +1 -1
- package/dist/components/box.d.ts +3 -1
- package/dist/components/box.d.ts.map +1 -1
- package/dist/components/box.js +19 -10
- package/dist/components/box.js.map +1 -1
- package/dist/components/cancellable-loader.d.ts.map +1 -1
- package/dist/components/cancellable-loader.js.map +1 -1
- package/dist/components/editor/constants.d.ts +9 -0
- package/dist/components/editor/constants.d.ts.map +1 -0
- package/dist/components/editor/constants.js +12 -0
- package/dist/components/editor/constants.js.map +1 -0
- package/dist/components/editor/editor-methods/autocomplete-matching.d.ts +29 -0
- package/dist/components/editor/editor-methods/autocomplete-matching.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/autocomplete-matching.js +104 -0
- package/dist/components/editor/editor-methods/autocomplete-matching.js.map +1 -0
- package/dist/components/editor/editor-methods/autocomplete-request.d.ts +14 -0
- package/dist/components/editor/editor-methods/autocomplete-request.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/autocomplete-request.js +72 -0
- package/dist/components/editor/editor-methods/autocomplete-request.js.map +1 -0
- package/dist/components/editor/editor-methods/backspace-cursor.d.ts +9 -0
- package/dist/components/editor/editor-methods/backspace-cursor.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/backspace-cursor.js +122 -0
- package/dist/components/editor/editor-methods/backspace-cursor.js.map +1 -0
- package/dist/components/editor/editor-methods/configuration.d.ts +17 -0
- package/dist/components/editor/editor-methods/configuration.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/configuration.js +107 -0
- package/dist/components/editor/editor-methods/configuration.js.map +1 -0
- package/dist/components/editor/editor-methods/cursor-movement.d.ts +7 -0
- package/dist/components/editor/editor-methods/cursor-movement.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/cursor-movement.js +112 -0
- package/dist/components/editor/editor-methods/cursor-movement.js.map +1 -0
- package/dist/components/editor/editor-methods/input-handling.d.ts +3 -0
- package/dist/components/editor/editor-methods/input-handling.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/input-handling.js +257 -0
- package/dist/components/editor/editor-methods/input-handling.js.map +1 -0
- package/dist/components/editor/editor-methods/paste-submit.d.ts +7 -0
- package/dist/components/editor/editor-methods/paste-submit.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/paste-submit.js +105 -0
- package/dist/components/editor/editor-methods/paste-submit.js.map +1 -0
- package/dist/components/editor/editor-methods/render.d.ts +3 -0
- package/dist/components/editor/editor-methods/render.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/render.js +114 -0
- package/dist/components/editor/editor-methods/render.js.map +1 -0
- package/dist/components/editor/editor-methods/text-insertion.d.ts +4 -0
- package/dist/components/editor/editor-methods/text-insertion.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/text-insertion.js +91 -0
- package/dist/components/editor/editor-methods/text-insertion.js.map +1 -0
- package/dist/components/editor/editor-methods/text-layout.d.ts +15 -0
- package/dist/components/editor/editor-methods/text-layout.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/text-layout.js +129 -0
- package/dist/components/editor/editor-methods/text-layout.js.map +1 -0
- package/dist/components/editor/editor-methods/vertical-movement.d.ts +8 -0
- package/dist/components/editor/editor-methods/vertical-movement.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/vertical-movement.js +123 -0
- package/dist/components/editor/editor-methods/vertical-movement.js.map +1 -0
- package/dist/components/editor/editor-methods/word-operations.d.ts +19 -0
- package/dist/components/editor/editor-methods/word-operations.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/word-operations.js +122 -0
- package/dist/components/editor/editor-methods/word-operations.js.map +1 -0
- package/dist/components/editor/editor-methods/yank-undo.d.ts +11 -0
- package/dist/components/editor/editor-methods/yank-undo.d.ts.map +1 -0
- package/dist/components/editor/editor-methods/yank-undo.js +132 -0
- package/dist/components/editor/editor-methods/yank-undo.js.map +1 -0
- package/dist/components/editor/editor.d.ts +67 -0
- package/dist/components/editor/editor.d.ts.map +1 -0
- package/dist/components/editor/editor.js +93 -0
- package/dist/components/editor/editor.js.map +1 -0
- package/dist/components/editor/helpers.d.ts +3 -0
- package/dist/components/editor/helpers.d.ts.map +1 -0
- package/dist/components/editor/helpers.js +3 -0
- package/dist/components/editor/helpers.js.map +1 -0
- package/dist/components/editor/index.d.ts +4 -0
- package/dist/components/editor/index.d.ts.map +1 -0
- package/dist/components/editor/index.js +3 -0
- package/dist/components/editor/index.js.map +1 -0
- package/dist/components/editor/paste-marker.d.ts +5 -0
- package/dist/components/editor/paste-marker.d.ts.map +1 -0
- package/dist/components/editor/paste-marker.js +134 -0
- package/dist/components/editor/paste-marker.js.map +1 -0
- package/dist/components/editor/trigger-patterns.d.ts +4 -0
- package/dist/components/editor/trigger-patterns.d.ts.map +1 -0
- package/dist/components/editor/trigger-patterns.js +11 -0
- package/dist/components/editor/trigger-patterns.js.map +1 -0
- package/dist/components/editor/types.d.ts +25 -0
- package/dist/components/editor/types.d.ts.map +1 -0
- package/dist/components/editor/types.js +2 -0
- package/dist/components/editor/types.js.map +1 -0
- package/dist/components/editor.d.ts +1 -253
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +1 -1915
- package/dist/components/editor.js.map +1 -1
- package/dist/components/image.d.ts.map +1 -1
- package/dist/components/image.js.map +1 -1
- package/dist/components/input/constants.d.ts +2 -0
- package/dist/components/input/constants.d.ts.map +1 -0
- package/dist/components/input/constants.js +3 -0
- package/dist/components/input/constants.js.map +1 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/index.js +2 -0
- package/dist/components/input/index.js.map +1 -0
- package/dist/components/input/input-methods/input-handling.d.ts +3 -0
- package/dist/components/input/input-methods/input-handling.d.ts.map +1 -0
- package/dist/components/input/input-methods/input-handling.js +145 -0
- package/dist/components/input/input-methods/input-handling.js.map +1 -0
- package/dist/components/input/input-methods/render.d.ts +3 -0
- package/dist/components/input/input-methods/render.d.ts.map +1 -0
- package/dist/components/input/input-methods/render.js +62 -0
- package/dist/components/input/input-methods/render.js.map +1 -0
- package/dist/components/input/input-methods/text-editing.d.ts +17 -0
- package/dist/components/input/input-methods/text-editing.d.ts.map +1 -0
- package/dist/components/input/input-methods/text-editing.js +145 -0
- package/dist/components/input/input-methods/text-editing.js.map +1 -0
- package/dist/components/input/input-methods/value-access.d.ts +4 -0
- package/dist/components/input/input-methods/value-access.d.ts.map +1 -0
- package/dist/components/input/input-methods/value-access.js +20 -0
- package/dist/components/input/input-methods/value-access.js.map +1 -0
- package/dist/components/input/input.d.ts +37 -0
- package/dist/components/input/input.d.ts.map +1 -0
- package/dist/components/input/input.js +77 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/input/types.d.ts +5 -0
- package/dist/components/input/types.d.ts.map +1 -0
- package/dist/components/input/types.js +2 -0
- package/dist/components/input/types.js.map +1 -0
- package/dist/components/input.d.ts +1 -36
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +1 -377
- package/dist/components/input.js.map +1 -1
- package/dist/components/loader.d.ts.map +1 -1
- package/dist/components/loader.js.map +1 -1
- package/dist/components/markdown/constants.d.ts +4 -0
- package/dist/components/markdown/constants.d.ts.map +1 -0
- package/dist/components/markdown/constants.js +8 -0
- package/dist/components/markdown/constants.js.map +1 -0
- package/dist/components/markdown/index.d.ts +3 -0
- package/dist/components/markdown/index.d.ts.map +1 -0
- package/dist/components/markdown/index.js +2 -0
- package/dist/components/markdown/index.js.map +1 -0
- package/dist/components/markdown/markdown-methods/inline-rendering.d.ts +7 -0
- package/dist/components/markdown/markdown-methods/inline-rendering.d.ts.map +1 -0
- package/dist/components/markdown/markdown-methods/inline-rendering.js +95 -0
- package/dist/components/markdown/markdown-methods/inline-rendering.js.map +1 -0
- package/dist/components/markdown/markdown-methods/list-table-helpers.d.ts +7 -0
- package/dist/components/markdown/markdown-methods/list-table-helpers.d.ts.map +1 -0
- package/dist/components/markdown/markdown-methods/list-table-helpers.js +61 -0
- package/dist/components/markdown/markdown-methods/list-table-helpers.js.map +1 -0
- package/dist/components/markdown/markdown-methods/table-rendering.d.ts +5 -0
- package/dist/components/markdown/markdown-methods/table-rendering.d.ts.map +1 -0
- package/dist/components/markdown/markdown-methods/table-rendering.js +146 -0
- package/dist/components/markdown/markdown-methods/table-rendering.js.map +1 -0
- package/dist/components/markdown/markdown-methods/text-rendering.d.ts +6 -0
- package/dist/components/markdown/markdown-methods/text-rendering.d.ts.map +1 -0
- package/dist/components/markdown/markdown-methods/text-rendering.js +115 -0
- package/dist/components/markdown/markdown-methods/text-rendering.js.map +1 -0
- package/dist/components/markdown/markdown-methods/theming.d.ts +6 -0
- package/dist/components/markdown/markdown-methods/theming.d.ts.map +1 -0
- package/dist/components/markdown/markdown-methods/theming.js +41 -0
- package/dist/components/markdown/markdown-methods/theming.js.map +1 -0
- package/dist/components/markdown/markdown-methods/token-rendering.d.ts +5 -0
- package/dist/components/markdown/markdown-methods/token-rendering.d.ts.map +1 -0
- package/dist/components/markdown/markdown-methods/token-rendering.js +142 -0
- package/dist/components/markdown/markdown-methods/token-rendering.js.map +1 -0
- package/dist/components/markdown/markdown.d.ts +32 -0
- package/dist/components/markdown/markdown.d.ts.map +1 -0
- package/dist/components/markdown/markdown.js +72 -0
- package/dist/components/markdown/markdown.js.map +1 -0
- package/dist/components/markdown/strictstrikethroughtokenizer.d.ts +6 -0
- package/dist/components/markdown/strictstrikethroughtokenizer.d.ts.map +1 -0
- package/dist/components/markdown/strictstrikethroughtokenizer.js +18 -0
- package/dist/components/markdown/strictstrikethroughtokenizer.js.map +1 -0
- package/dist/components/markdown/types.d.ts +42 -0
- package/dist/components/markdown/types.d.ts.map +1 -0
- package/dist/components/markdown/types.js +2 -0
- package/dist/components/markdown/types.js.map +1 -0
- package/dist/components/markdown.d.ts +1 -96
- package/dist/components/markdown.d.ts.map +1 -1
- package/dist/components/markdown.js +1 -653
- package/dist/components/markdown.js.map +1 -1
- package/dist/components/select-list.d.ts.map +1 -1
- package/dist/components/select-list.js +8 -3
- package/dist/components/select-list.js.map +1 -1
- package/dist/components/settings-list.d.ts.map +1 -1
- package/dist/components/settings-list.js +2 -6
- package/dist/components/settings-list.js.map +1 -1
- package/dist/components/spacer.d.ts.map +1 -1
- package/dist/components/spacer.js.map +1 -1
- package/dist/components/text.d.ts.map +1 -1
- package/dist/components/text.js +2 -2
- package/dist/components/text.js.map +1 -1
- package/dist/components/truncated-text.d.ts.map +1 -1
- package/dist/components/truncated-text.js.map +1 -1
- package/dist/editor-component.d.ts.map +1 -1
- package/dist/editor-component.js.map +1 -1
- package/dist/fuzzy.d.ts.map +1 -1
- package/dist/fuzzy.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keybindings.d.ts.map +1 -1
- package/dist/keybindings.js.map +1 -1
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js +145 -14
- package/dist/keys.js.map +1 -1
- package/dist/kill-ring.d.ts.map +1 -1
- package/dist/kill-ring.js.map +1 -1
- package/dist/native-modifiers.d.ts +9 -0
- package/dist/native-modifiers.d.ts.map +1 -1
- package/dist/native-modifiers.js +5 -0
- package/dist/native-modifiers.js.map +1 -1
- package/dist/stdin-buffer.d.ts +3 -0
- package/dist/stdin-buffer.d.ts.map +1 -1
- package/dist/stdin-buffer.js +24 -21
- package/dist/stdin-buffer.js.map +1 -1
- package/dist/terminal/constants.d.ts +9 -0
- package/dist/terminal/constants.d.ts.map +1 -0
- package/dist/terminal/constants.js +10 -0
- package/dist/terminal/constants.js.map +1 -0
- package/dist/terminal/helpers.d.ts +6 -0
- package/dist/terminal/helpers.d.ts.map +1 -0
- package/dist/terminal/helpers.js +23 -0
- package/dist/terminal/helpers.js.map +1 -0
- package/dist/terminal/index.d.ts +4 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +3 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/processterminal-methods/cursor-screen.d.ts +11 -0
- package/dist/terminal/processterminal-methods/cursor-screen.d.ts.map +1 -0
- package/dist/terminal/processterminal-methods/cursor-screen.js +50 -0
- package/dist/terminal/processterminal-methods/cursor-screen.js.map +1 -0
- package/dist/terminal/processterminal-methods/keyboard-protocol.d.ts +14 -0
- package/dist/terminal/processterminal-methods/keyboard-protocol.d.ts.map +1 -0
- package/dist/terminal/processterminal-methods/keyboard-protocol.js +147 -0
- package/dist/terminal/processterminal-methods/keyboard-protocol.js.map +1 -0
- package/dist/terminal/processterminal-methods/terminal-io.d.ts +9 -0
- package/dist/terminal/processterminal-methods/terminal-io.d.ts.map +1 -0
- package/dist/terminal/processterminal-methods/terminal-io.js +153 -0
- package/dist/terminal/processterminal-methods/terminal-io.js.map +1 -0
- package/dist/terminal/processterminal.d.ts +49 -0
- package/dist/terminal/processterminal.d.ts.map +1 -0
- package/dist/terminal/processterminal.js +129 -0
- package/dist/terminal/processterminal.js.map +1 -0
- package/dist/terminal/types.d.ts +31 -0
- package/dist/terminal/types.d.ts.map +1 -0
- package/dist/terminal/types.js +2 -0
- package/dist/terminal/types.js.map +1 -0
- package/dist/terminal-colors.d.ts +2 -0
- package/dist/terminal-colors.d.ts.map +1 -1
- package/dist/terminal-colors.js +17 -5
- package/dist/terminal-colors.js.map +1 -1
- package/dist/terminal-image.d.ts.map +1 -1
- package/dist/terminal-image.js.map +1 -1
- package/dist/terminal.d.ts +1 -109
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +1 -432
- package/dist/terminal.js.map +1 -1
- package/dist/tui/constants.d.ts +3 -0
- package/dist/tui/constants.d.ts.map +1 -0
- package/dist/tui/constants.js +3 -0
- package/dist/tui/constants.js.map +1 -0
- package/dist/tui/container.d.ts +10 -0
- package/dist/tui/container.d.ts.map +1 -0
- package/dist/tui/container.js +31 -0
- package/dist/tui/container.js.map +1 -0
- package/dist/tui/helpers.d.ts +8 -0
- package/dist/tui/helpers.d.ts.map +1 -0
- package/dist/tui/helpers.js +53 -0
- package/dist/tui/helpers.js.map +1 -0
- package/dist/tui/index.d.ts +6 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +5 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/tui-methods/configuration.d.ts +20 -0
- package/dist/tui/tui-methods/configuration.d.ts.map +1 -0
- package/dist/tui/tui-methods/configuration.js +131 -0
- package/dist/tui/tui-methods/configuration.js.map +1 -0
- package/dist/tui/tui-methods/cursor-background.d.ts +10 -0
- package/dist/tui/tui-methods/cursor-background.d.ts.map +1 -0
- package/dist/tui/tui-methods/cursor-background.js +52 -0
- package/dist/tui/tui-methods/cursor-background.js.map +1 -0
- package/dist/tui/tui-methods/incremental-render.d.ts +17 -0
- package/dist/tui/tui-methods/incremental-render.d.ts.map +1 -0
- package/dist/tui/tui-methods/incremental-render.js +259 -0
- package/dist/tui/tui-methods/incremental-render.js.map +1 -0
- package/dist/tui/tui-methods/input-handling.d.ts +5 -0
- package/dist/tui/tui-methods/input-handling.d.ts.map +1 -0
- package/dist/tui/tui-methods/input-handling.js +111 -0
- package/dist/tui/tui-methods/input-handling.js.map +1 -0
- package/dist/tui/tui-methods/line-compositing.d.ts +7 -0
- package/dist/tui/tui-methods/line-compositing.d.ts.map +1 -0
- package/dist/tui/tui-methods/line-compositing.js +61 -0
- package/dist/tui/tui-methods/line-compositing.js.map +1 -0
- package/dist/tui/tui-methods/overlay-compositing.d.ts +12 -0
- package/dist/tui/tui-methods/overlay-compositing.d.ts.map +1 -0
- package/dist/tui/tui-methods/overlay-compositing.js +123 -0
- package/dist/tui/tui-methods/overlay-compositing.js.map +1 -0
- package/dist/tui/tui-methods/overlay-layout.d.ts +11 -0
- package/dist/tui/tui-methods/overlay-layout.d.ts.map +1 -0
- package/dist/tui/tui-methods/overlay-layout.js +124 -0
- package/dist/tui/tui-methods/overlay-layout.js.map +1 -0
- package/dist/tui/tui-methods/overlay-management.d.ts +11 -0
- package/dist/tui/tui-methods/overlay-management.d.ts.map +1 -0
- package/dist/tui/tui-methods/overlay-management.js +152 -0
- package/dist/tui/tui-methods/overlay-management.js.map +1 -0
- package/dist/tui/tui-methods/render-pipeline.d.ts +3 -0
- package/dist/tui/tui-methods/render-pipeline.d.ts.map +1 -0
- package/dist/tui/tui-methods/render-pipeline.js +176 -0
- package/dist/tui/tui-methods/render-pipeline.js.map +1 -0
- package/dist/tui/tui-methods/render-width-error.d.ts +3 -0
- package/dist/tui/tui-methods/render-width-error.d.ts.map +1 -0
- package/dist/tui/tui-methods/render-width-error.js +28 -0
- package/dist/tui/tui-methods/render-width-error.js.map +1 -0
- package/dist/tui/tui-methods/terminal-control.d.ts +8 -0
- package/dist/tui/tui-methods/terminal-control.d.ts.map +1 -0
- package/dist/tui/tui-methods/terminal-control.js +101 -0
- package/dist/tui/tui-methods/terminal-control.js.map +1 -0
- package/dist/tui/tui.d.ts +59 -0
- package/dist/tui/tui.d.ts.map +1 -0
- package/dist/tui/tui.js +78 -0
- package/dist/tui/tui.js.map +1 -0
- package/dist/tui/types.d.ts +124 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +2 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/tui.d.ts +1 -254
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +1 -1344
- package/dist/tui.js.map +1 -1
- package/dist/undo-stack.d.ts.map +1 -1
- package/dist/undo-stack.js.map +1 -1
- package/dist/utils/ansi-wrapping.d.ts +5 -0
- package/dist/utils/ansi-wrapping.d.ts.map +1 -0
- package/dist/utils/ansi-wrapping.js +52 -0
- package/dist/utils/ansi-wrapping.js.map +1 -0
- package/dist/utils/ansicodetracker.d.ts +27 -0
- package/dist/utils/ansicodetracker.d.ts.map +1 -0
- package/dist/utils/ansicodetracker.js +222 -0
- package/dist/utils/ansicodetracker.js.map +1 -0
- package/dist/utils/column-slicing.d.ts +12 -0
- package/dist/utils/column-slicing.d.ts.map +1 -0
- package/dist/utils/column-slicing.js +111 -0
- package/dist/utils/column-slicing.js.map +1 -0
- package/dist/utils/column-truncation.d.ts +2 -0
- package/dist/utils/column-truncation.d.ts.map +1 -0
- package/dist/utils/column-truncation.js +129 -0
- package/dist/utils/column-truncation.js.map +1 -0
- package/dist/utils/constants.d.ts +12 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +12 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/install-delegated-methods.d.ts +5 -0
- package/dist/utils/install-delegated-methods.d.ts.map +1 -0
- package/dist/utils/install-delegated-methods.js +27 -0
- package/dist/utils/install-delegated-methods.js.map +1 -0
- package/dist/utils/segmentation.d.ts +10 -0
- package/dist/utils/segmentation.d.ts.map +1 -0
- package/dist/utils/segmentation.js +111 -0
- package/dist/utils/segmentation.js.map +1 -0
- package/dist/utils/terminal-output.d.ts +10 -0
- package/dist/utils/terminal-output.d.ts.map +1 -0
- package/dist/utils/terminal-output.js +122 -0
- package/dist/utils/terminal-output.js.map +1 -0
- package/dist/utils/types.d.ts +7 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils/width-truncation.d.ts +6 -0
- package/dist/utils/width-truncation.d.ts.map +1 -0
- package/dist/utils/width-truncation.js +121 -0
- package/dist/utils/width-truncation.js.map +1 -0
- package/dist/utils/word-wrapping.d.ts +4 -0
- package/dist/utils/word-wrapping.d.ts.map +1 -0
- package/dist/utils/word-wrapping.js +139 -0
- package/dist/utils/word-wrapping.js.map +1 -0
- package/dist/utils.d.ts +1 -84
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -1059
- package/dist/utils.js.map +1 -1
- package/dist/word-navigation.d.ts.map +1 -1
- package/dist/word-navigation.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["export { applyBackgroundToLine, isPunctuationChar, isWhitespaceChar, wrapTextWithAnsi } from \"./ansi-wrapping.ts\";\nexport { extractSegments, sliceByColumn, sliceWithWidth } from \"./column-slicing.ts\";\nexport { truncateToWidth } from \"./column-truncation.ts\";\nexport { cjkBreakRegex, PUNCTUATION_REGEX } from \"./constants.ts\";\nexport { extractAnsiCode, getGraphemeSegmenter, getWordSegmenter } from \"./segmentation.ts\";\nexport { normalizeTerminalOutput } from \"./terminal-output.ts\";\nexport { visibleWidth } from \"./width-truncation.ts\";\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type DelegatedMethods<Self, MethodModule> = {
|
|
2
|
+
[Key in keyof MethodModule as Key extends `do_${infer MethodName}` ? MethodModule[Key] extends (self: Self, ...args: infer _Args) => infer _Result ? MethodName : never : never]: MethodModule[Key] extends (self: Self, ...args: infer Args) => infer Result ? (...args: Args) => Result : never;
|
|
3
|
+
};
|
|
4
|
+
export declare function installDelegatedMethods<Self extends object>(prototype: Self, methodModules: readonly object[]): void;
|
|
5
|
+
//# sourceMappingURL=install-delegated-methods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-delegated-methods.d.ts","sourceRoot":"","sources":["../../src/utils/install-delegated-methods.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,CAAC,IAAI,EAAE,YAAY,IAAI;KAChD,GAAG,IAAI,MAAM,YAAY,IAAI,GAAG,SAAS,MAAM,MAAM,UAAU,EAAE,GAC9D,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,MAAM,KAAK,KAAK,MAAM,OAAO,GAC3E,UAAU,GACV,KAAK,GACP,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,MAAM,IAAI,KAAK,MAAM,MAAM,GACnF,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,GACzB,KAAK;CACV,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,IAAI,SAAS,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAyBpH","sourcesContent":["export type DelegatedMethods<Self, MethodModule> = {\n [Key in keyof MethodModule as Key extends `do_${infer MethodName}`\n ? MethodModule[Key] extends (self: Self, ...args: infer _Args) => infer _Result\n ? MethodName\n : never\n : never]: MethodModule[Key] extends (self: Self, ...args: infer Args) => infer Result\n ? (...args: Args) => Result\n : never;\n};\n\nexport function installDelegatedMethods<Self extends object>(prototype: Self, methodModules: readonly object[]): void {\n const explicitMethods = new Set(Object.getOwnPropertyNames(prototype));\n const installedMethods = new Set<string>();\n\n for (const methodModule of methodModules) {\n for (const [exportName, implementation] of Object.entries(methodModule)) {\n if (!exportName.startsWith(\"do_\") || typeof implementation !== \"function\") continue;\n const methodName = exportName.slice(3);\n if (installedMethods.has(methodName)) {\n throw new Error(`Duplicate delegated method: ${methodName}`);\n }\n installedMethods.add(methodName);\n if (explicitMethods.has(methodName)) continue;\n\n const delegatedMethod = function (this: Self, ...args: unknown[]): unknown {\n return Reflect.apply(implementation, undefined, [this, ...args]);\n };\n Object.defineProperty(delegatedMethod, \"name\", { value: methodName });\n Object.defineProperty(prototype, methodName, {\n configurable: true,\n value: delegatedMethod,\n writable: true,\n });\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function installDelegatedMethods(prototype, methodModules) {
|
|
2
|
+
const explicitMethods = new Set(Object.getOwnPropertyNames(prototype));
|
|
3
|
+
const installedMethods = new Set();
|
|
4
|
+
for (const methodModule of methodModules) {
|
|
5
|
+
for (const [exportName, implementation] of Object.entries(methodModule)) {
|
|
6
|
+
if (!exportName.startsWith("do_") || typeof implementation !== "function")
|
|
7
|
+
continue;
|
|
8
|
+
const methodName = exportName.slice(3);
|
|
9
|
+
if (installedMethods.has(methodName)) {
|
|
10
|
+
throw new Error(`Duplicate delegated method: ${methodName}`);
|
|
11
|
+
}
|
|
12
|
+
installedMethods.add(methodName);
|
|
13
|
+
if (explicitMethods.has(methodName))
|
|
14
|
+
continue;
|
|
15
|
+
const delegatedMethod = function (...args) {
|
|
16
|
+
return Reflect.apply(implementation, undefined, [this, ...args]);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(delegatedMethod, "name", { value: methodName });
|
|
19
|
+
Object.defineProperty(prototype, methodName, {
|
|
20
|
+
configurable: true,
|
|
21
|
+
value: delegatedMethod,
|
|
22
|
+
writable: true,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=install-delegated-methods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-delegated-methods.js","sourceRoot":"","sources":["../../src/utils/install-delegated-methods.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,uBAAuB,CAAsB,SAAe,EAAE,aAAgC,EAAQ;IACpH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC;IACvE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE3C,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,KAAK,MAAM,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,OAAO,cAAc,KAAK,UAAU;gBAAE,SAAS;YACpF,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACjC,IAAI,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,SAAS;YAE9C,MAAM,eAAe,GAAG,UAAsB,GAAG,IAAe,EAAW;gBACzE,OAAO,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;YAAA,CAClE,CAAC;YACF,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YACtE,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE;gBAC3C,YAAY,EAAE,IAAI;gBAClB,KAAK,EAAE,eAAe;gBACtB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AAAA,CACF","sourcesContent":["export type DelegatedMethods<Self, MethodModule> = {\n [Key in keyof MethodModule as Key extends `do_${infer MethodName}`\n ? MethodModule[Key] extends (self: Self, ...args: infer _Args) => infer _Result\n ? MethodName\n : never\n : never]: MethodModule[Key] extends (self: Self, ...args: infer Args) => infer Result\n ? (...args: Args) => Result\n : never;\n};\n\nexport function installDelegatedMethods<Self extends object>(prototype: Self, methodModules: readonly object[]): void {\n const explicitMethods = new Set(Object.getOwnPropertyNames(prototype));\n const installedMethods = new Set<string>();\n\n for (const methodModule of methodModules) {\n for (const [exportName, implementation] of Object.entries(methodModule)) {\n if (!exportName.startsWith(\"do_\") || typeof implementation !== \"function\") continue;\n const methodName = exportName.slice(3);\n if (installedMethods.has(methodName)) {\n throw new Error(`Duplicate delegated method: ${methodName}`);\n }\n installedMethods.add(methodName);\n if (explicitMethods.has(methodName)) continue;\n\n const delegatedMethod = function (this: Self, ...args: unknown[]): unknown {\n return Reflect.apply(implementation, undefined, [this, ...args]);\n };\n Object.defineProperty(delegatedMethod, \"name\", { value: methodName });\n Object.defineProperty(prototype, methodName, {\n configurable: true,\n value: delegatedMethod,\n writable: true,\n });\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function getGraphemeSegmenter(): Intl.Segmenter;
|
|
2
|
+
export declare function getWordSegmenter(): Intl.Segmenter;
|
|
3
|
+
export declare function couldBeEmoji(segment: string): boolean;
|
|
4
|
+
export declare function isPrintableAscii(str: string): boolean;
|
|
5
|
+
export declare function graphemeWidth(segment: string): number;
|
|
6
|
+
export declare function extractAnsiCode(str: string, pos: number): {
|
|
7
|
+
code: string;
|
|
8
|
+
length: number;
|
|
9
|
+
} | null;
|
|
10
|
+
//# sourceMappingURL=segmentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segmentation.d.ts","sourceRoot":"","sources":["../../src/utils/segmentation.ts"],"names":[],"mappings":"AASA,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,SAAS,CAErD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAEjD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAUrD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA4CrD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA2CjG","sourcesContent":["import { eastAsianWidth } from \"get-east-asian-width\";\nimport {\n graphemeSegmenter,\n leadingNonPrintingRegex,\n rgiEmojiRegex,\n wordSegmenter,\n zeroWidthRegex,\n} from \"./constants.ts\";\n\nexport function getGraphemeSegmenter(): Intl.Segmenter {\n return graphemeSegmenter;\n}\n\nexport function getWordSegmenter(): Intl.Segmenter {\n return wordSegmenter;\n}\n\nexport function couldBeEmoji(segment: string): boolean {\n const cp = segment.codePointAt(0)!;\n return (\n (cp >= 0x1f000 && cp <= 0x1fbff) || // Emoji and Pictograph\n (cp >= 0x2300 && cp <= 0x23ff) || // Misc technical\n (cp >= 0x2600 && cp <= 0x27bf) || // Misc symbols, dingbats\n (cp >= 0x2b50 && cp <= 0x2b55) || // Specific stars/circles\n segment.includes(\"\\uFE0F\") || // Contains VS16 (emoji presentation selector)\n segment.length > 2 // Multi-codepoint sequences (ZWJ, skin tones, etc.)\n );\n}\n\nexport function isPrintableAscii(str: string): boolean {\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n if (code < 0x20 || code > 0x7e) {\n return false;\n }\n }\n return true;\n}\n\nexport function graphemeWidth(segment: string): number {\n if (segment === \"\\t\") {\n return 4;\n }\n\n // Zero-width clusters\n if (zeroWidthRegex.test(segment)) {\n return 0;\n }\n\n // Emoji check with pre-filter\n if (couldBeEmoji(segment) && rgiEmojiRegex.test(segment)) {\n return 2;\n }\n\n // Get base visible codepoint\n const base = segment.replace(leadingNonPrintingRegex, \"\");\n const cp = base.codePointAt(0);\n if (cp === undefined) {\n return 0;\n }\n\n // Regional indicator symbols (U+1F1E6..U+1F1FF) are often rendered as\n // full-width emoji in terminals, even when isolated during streaming.\n // Keep width conservative (2) to avoid terminal auto-wrap drift artifacts.\n if (cp >= 0x1f1e6 && cp <= 0x1f1ff) {\n return 2;\n }\n\n let width = eastAsianWidth(cp);\n\n // Trailing halfwidth/fullwidth forms and AM vowels that segment with a base.\n if (segment.length > 1) {\n for (const char of segment.slice(1)) {\n const c = char.codePointAt(0)!;\n if (c >= 0xff00 && c <= 0xffef) {\n width += eastAsianWidth(c);\n } else if (c === 0x0e33 || c === 0x0eb3) {\n width += 1;\n }\n }\n }\n\n return width;\n}\n\nexport function extractAnsiCode(str: string, pos: number): { code: string; length: number } | null {\n if (pos >= str.length || str[pos] !== \"\\x1b\") return null;\n\n const next = str[pos + 1];\n\n // CSI sequence: ESC [ ... m/G/K/H/J\n if (next === \"[\") {\n let j = pos + 2;\n while (j < str.length) {\n const c = str[j]!;\n if (c === \"m\" || c === \"G\" || c === \"K\" || c === \"H\" || c === \"J\") {\n return { code: str.substring(pos, j + 1), length: j + 1 - pos };\n }\n j++;\n }\n return null;\n }\n\n // OSC sequence: ESC ] ... BEL or ESC ] ... ST (ESC \\)\n // Used for hyperlinks (OSC 8), window titles, etc.\n if (next === \"]\") {\n let j = pos + 2;\n while (j < str.length) {\n if (str[j] === \"\\x07\") return { code: str.substring(pos, j + 1), length: j + 1 - pos };\n if (str[j] === \"\\x1b\" && str[j + 1] === \"\\\\\") return { code: str.substring(pos, j + 2), length: j + 2 - pos };\n j++;\n }\n return null;\n }\n\n // APC sequence: ESC _ ... BEL or ESC _ ... ST (ESC \\)\n // Used for cursor marker and application-specific commands\n if (next === \"_\") {\n let j = pos + 2;\n while (j < str.length) {\n if (str[j] === \"\\x07\") return { code: str.substring(pos, j + 1), length: j + 1 - pos };\n if (str[j] === \"\\x1b\" && str[j + 1] === \"\\\\\") return { code: str.substring(pos, j + 2), length: j + 2 - pos };\n j++;\n }\n return null;\n }\n\n return null;\n}\n"]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { eastAsianWidth } from "get-east-asian-width";
|
|
2
|
+
import { graphemeSegmenter, leadingNonPrintingRegex, rgiEmojiRegex, wordSegmenter, zeroWidthRegex, } from "./constants.js";
|
|
3
|
+
export function getGraphemeSegmenter() {
|
|
4
|
+
return graphemeSegmenter;
|
|
5
|
+
}
|
|
6
|
+
export function getWordSegmenter() {
|
|
7
|
+
return wordSegmenter;
|
|
8
|
+
}
|
|
9
|
+
export function couldBeEmoji(segment) {
|
|
10
|
+
const cp = segment.codePointAt(0);
|
|
11
|
+
return ((cp >= 0x1f000 && cp <= 0x1fbff) || // Emoji and Pictograph
|
|
12
|
+
(cp >= 0x2300 && cp <= 0x23ff) || // Misc technical
|
|
13
|
+
(cp >= 0x2600 && cp <= 0x27bf) || // Misc symbols, dingbats
|
|
14
|
+
(cp >= 0x2b50 && cp <= 0x2b55) || // Specific stars/circles
|
|
15
|
+
segment.includes("\uFE0F") || // Contains VS16 (emoji presentation selector)
|
|
16
|
+
segment.length > 2 // Multi-codepoint sequences (ZWJ, skin tones, etc.)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
export function isPrintableAscii(str) {
|
|
20
|
+
for (let i = 0; i < str.length; i++) {
|
|
21
|
+
const code = str.charCodeAt(i);
|
|
22
|
+
if (code < 0x20 || code > 0x7e) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
export function graphemeWidth(segment) {
|
|
29
|
+
if (segment === "\t") {
|
|
30
|
+
return 4;
|
|
31
|
+
}
|
|
32
|
+
// Zero-width clusters
|
|
33
|
+
if (zeroWidthRegex.test(segment)) {
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
// Emoji check with pre-filter
|
|
37
|
+
if (couldBeEmoji(segment) && rgiEmojiRegex.test(segment)) {
|
|
38
|
+
return 2;
|
|
39
|
+
}
|
|
40
|
+
// Get base visible codepoint
|
|
41
|
+
const base = segment.replace(leadingNonPrintingRegex, "");
|
|
42
|
+
const cp = base.codePointAt(0);
|
|
43
|
+
if (cp === undefined) {
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
// Regional indicator symbols (U+1F1E6..U+1F1FF) are often rendered as
|
|
47
|
+
// full-width emoji in terminals, even when isolated during streaming.
|
|
48
|
+
// Keep width conservative (2) to avoid terminal auto-wrap drift artifacts.
|
|
49
|
+
if (cp >= 0x1f1e6 && cp <= 0x1f1ff) {
|
|
50
|
+
return 2;
|
|
51
|
+
}
|
|
52
|
+
let width = eastAsianWidth(cp);
|
|
53
|
+
// Trailing halfwidth/fullwidth forms and AM vowels that segment with a base.
|
|
54
|
+
if (segment.length > 1) {
|
|
55
|
+
for (const char of segment.slice(1)) {
|
|
56
|
+
const c = char.codePointAt(0);
|
|
57
|
+
if (c >= 0xff00 && c <= 0xffef) {
|
|
58
|
+
width += eastAsianWidth(c);
|
|
59
|
+
}
|
|
60
|
+
else if (c === 0x0e33 || c === 0x0eb3) {
|
|
61
|
+
width += 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return width;
|
|
66
|
+
}
|
|
67
|
+
export function extractAnsiCode(str, pos) {
|
|
68
|
+
if (pos >= str.length || str[pos] !== "\x1b")
|
|
69
|
+
return null;
|
|
70
|
+
const next = str[pos + 1];
|
|
71
|
+
// CSI sequence: ESC [ ... m/G/K/H/J
|
|
72
|
+
if (next === "[") {
|
|
73
|
+
let j = pos + 2;
|
|
74
|
+
while (j < str.length) {
|
|
75
|
+
const c = str[j];
|
|
76
|
+
if (c === "m" || c === "G" || c === "K" || c === "H" || c === "J") {
|
|
77
|
+
return { code: str.substring(pos, j + 1), length: j + 1 - pos };
|
|
78
|
+
}
|
|
79
|
+
j++;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
// OSC sequence: ESC ] ... BEL or ESC ] ... ST (ESC \)
|
|
84
|
+
// Used for hyperlinks (OSC 8), window titles, etc.
|
|
85
|
+
if (next === "]") {
|
|
86
|
+
let j = pos + 2;
|
|
87
|
+
while (j < str.length) {
|
|
88
|
+
if (str[j] === "\x07")
|
|
89
|
+
return { code: str.substring(pos, j + 1), length: j + 1 - pos };
|
|
90
|
+
if (str[j] === "\x1b" && str[j + 1] === "\\")
|
|
91
|
+
return { code: str.substring(pos, j + 2), length: j + 2 - pos };
|
|
92
|
+
j++;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
// APC sequence: ESC _ ... BEL or ESC _ ... ST (ESC \)
|
|
97
|
+
// Used for cursor marker and application-specific commands
|
|
98
|
+
if (next === "_") {
|
|
99
|
+
let j = pos + 2;
|
|
100
|
+
while (j < str.length) {
|
|
101
|
+
if (str[j] === "\x07")
|
|
102
|
+
return { code: str.substring(pos, j + 1), length: j + 1 - pos };
|
|
103
|
+
if (str[j] === "\x1b" && str[j + 1] === "\\")
|
|
104
|
+
return { code: str.substring(pos, j + 2), length: j + 2 - pos };
|
|
105
|
+
j++;
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=segmentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segmentation.js","sourceRoot":"","sources":["../../src/utils/segmentation.ts"],"names":[],"mappings":"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","sourcesContent":["import { eastAsianWidth } from \"get-east-asian-width\";\nimport {\n graphemeSegmenter,\n leadingNonPrintingRegex,\n rgiEmojiRegex,\n wordSegmenter,\n zeroWidthRegex,\n} from \"./constants.ts\";\n\nexport function getGraphemeSegmenter(): Intl.Segmenter {\n return graphemeSegmenter;\n}\n\nexport function getWordSegmenter(): Intl.Segmenter {\n return wordSegmenter;\n}\n\nexport function couldBeEmoji(segment: string): boolean {\n const cp = segment.codePointAt(0)!;\n return (\n (cp >= 0x1f000 && cp <= 0x1fbff) || // Emoji and Pictograph\n (cp >= 0x2300 && cp <= 0x23ff) || // Misc technical\n (cp >= 0x2600 && cp <= 0x27bf) || // Misc symbols, dingbats\n (cp >= 0x2b50 && cp <= 0x2b55) || // Specific stars/circles\n segment.includes(\"\\uFE0F\") || // Contains VS16 (emoji presentation selector)\n segment.length > 2 // Multi-codepoint sequences (ZWJ, skin tones, etc.)\n );\n}\n\nexport function isPrintableAscii(str: string): boolean {\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n if (code < 0x20 || code > 0x7e) {\n return false;\n }\n }\n return true;\n}\n\nexport function graphemeWidth(segment: string): number {\n if (segment === \"\\t\") {\n return 4;\n }\n\n // Zero-width clusters\n if (zeroWidthRegex.test(segment)) {\n return 0;\n }\n\n // Emoji check with pre-filter\n if (couldBeEmoji(segment) && rgiEmojiRegex.test(segment)) {\n return 2;\n }\n\n // Get base visible codepoint\n const base = segment.replace(leadingNonPrintingRegex, \"\");\n const cp = base.codePointAt(0);\n if (cp === undefined) {\n return 0;\n }\n\n // Regional indicator symbols (U+1F1E6..U+1F1FF) are often rendered as\n // full-width emoji in terminals, even when isolated during streaming.\n // Keep width conservative (2) to avoid terminal auto-wrap drift artifacts.\n if (cp >= 0x1f1e6 && cp <= 0x1f1ff) {\n return 2;\n }\n\n let width = eastAsianWidth(cp);\n\n // Trailing halfwidth/fullwidth forms and AM vowels that segment with a base.\n if (segment.length > 1) {\n for (const char of segment.slice(1)) {\n const c = char.codePointAt(0)!;\n if (c >= 0xff00 && c <= 0xffef) {\n width += eastAsianWidth(c);\n } else if (c === 0x0e33 || c === 0x0eb3) {\n width += 1;\n }\n }\n }\n\n return width;\n}\n\nexport function extractAnsiCode(str: string, pos: number): { code: string; length: number } | null {\n if (pos >= str.length || str[pos] !== \"\\x1b\") return null;\n\n const next = str[pos + 1];\n\n // CSI sequence: ESC [ ... m/G/K/H/J\n if (next === \"[\") {\n let j = pos + 2;\n while (j < str.length) {\n const c = str[j]!;\n if (c === \"m\" || c === \"G\" || c === \"K\" || c === \"H\" || c === \"J\") {\n return { code: str.substring(pos, j + 1), length: j + 1 - pos };\n }\n j++;\n }\n return null;\n }\n\n // OSC sequence: ESC ] ... BEL or ESC ] ... ST (ESC \\)\n // Used for hyperlinks (OSC 8), window titles, etc.\n if (next === \"]\") {\n let j = pos + 2;\n while (j < str.length) {\n if (str[j] === \"\\x07\") return { code: str.substring(pos, j + 1), length: j + 1 - pos };\n if (str[j] === \"\\x1b\" && str[j + 1] === \"\\\\\") return { code: str.substring(pos, j + 2), length: j + 2 - pos };\n j++;\n }\n return null;\n }\n\n // APC sequence: ESC _ ... BEL or ESC _ ... ST (ESC \\)\n // Used for cursor marker and application-specific commands\n if (next === \"_\") {\n let j = pos + 2;\n while (j < str.length) {\n if (str[j] === \"\\x07\") return { code: str.substring(pos, j + 1), length: j + 1 - pos };\n if (str[j] === \"\\x1b\" && str[j + 1] === \"\\\\\") return { code: str.substring(pos, j + 2), length: j + 2 - pos };\n j++;\n }\n return null;\n }\n\n return null;\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AnsiCodeTracker } from "./ansicodetracker.ts";
|
|
2
|
+
import type { ActiveHyperlink, Osc8Terminator } from "./types.ts";
|
|
3
|
+
export declare function finalizeTruncatedResult(prefix: string, prefixWidth: number, ellipsis: string, ellipsisWidth: number, maxWidth: number, pad: boolean): string;
|
|
4
|
+
export declare function normalizeTerminalOutput(str: string): string;
|
|
5
|
+
export declare function parseOsc8Hyperlink(ansiCode: string): ActiveHyperlink | null | undefined;
|
|
6
|
+
export declare function formatOsc8Hyperlink(hyperlink: ActiveHyperlink): string;
|
|
7
|
+
export declare function formatOsc8Close(terminator: Osc8Terminator): string;
|
|
8
|
+
export declare function updateTrackerFromText(text: string, tracker: AnsiCodeTracker): void;
|
|
9
|
+
export declare function splitIntoTokensWithAnsi(text: string): string[];
|
|
10
|
+
//# sourceMappingURL=terminal-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-output.d.ts","sourceRoot":"","sources":["../../src/utils/terminal-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAElE,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,OAAO,GACX,MAAM,CAYR;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,SAAS,CAkBvF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAEtE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CAElE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAWlF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0E9D","sourcesContent":["import type { AnsiCodeTracker } from \"./ansicodetracker.ts\";\nimport { cjkBreakRegex, graphemeSegmenter, THAI_LAO_AM_GLOBAL_REGEX, THAI_LAO_AM_REGEX } from \"./constants.ts\";\nimport { extractAnsiCode } from \"./segmentation.ts\";\nimport type { ActiveHyperlink, Osc8Terminator } from \"./types.ts\";\n\nexport function finalizeTruncatedResult(\n prefix: string,\n prefixWidth: number,\n ellipsis: string,\n ellipsisWidth: number,\n maxWidth: number,\n pad: boolean,\n): string {\n const reset = \"\\x1b[0m\";\n const visibleWidth = prefixWidth + ellipsisWidth;\n let result: string;\n\n if (ellipsis.length > 0) {\n result = `${prefix}${reset}${ellipsis}${reset}`;\n } else {\n result = `${prefix}${reset}`;\n }\n\n return pad ? result + \" \".repeat(Math.max(0, maxWidth - visibleWidth)) : result;\n}\n\nexport function normalizeTerminalOutput(str: string): string {\n if (!THAI_LAO_AM_REGEX.test(str)) return str;\n return str.replace(THAI_LAO_AM_GLOBAL_REGEX, (char) => (char === \"\\u0e33\" ? \"\\u0e4d\\u0e32\" : \"\\u0ecd\\u0eb2\"));\n}\n\nexport function parseOsc8Hyperlink(ansiCode: string): ActiveHyperlink | null | undefined {\n if (!ansiCode.startsWith(\"\\x1b]8;\")) {\n return undefined;\n }\n\n const terminator: Osc8Terminator = ansiCode.endsWith(\"\\x07\") ? \"\\x07\" : \"\\x1b\\\\\";\n const body = ansiCode.slice(4, terminator === \"\\x07\" ? -1 : -2);\n const separatorIndex = body.indexOf(\";\");\n if (separatorIndex === -1) {\n return undefined;\n }\n\n const params = body.slice(0, separatorIndex);\n const url = body.slice(separatorIndex + 1);\n if (!url) {\n return null;\n }\n return { params, url, terminator };\n}\n\nexport function formatOsc8Hyperlink(hyperlink: ActiveHyperlink): string {\n return `\\x1b]8;${hyperlink.params};${hyperlink.url}${hyperlink.terminator}`;\n}\n\nexport function formatOsc8Close(terminator: Osc8Terminator): string {\n return `\\x1b]8;;${terminator}`;\n}\n\nexport function updateTrackerFromText(text: string, tracker: AnsiCodeTracker): void {\n let i = 0;\n while (i < text.length) {\n const ansiResult = extractAnsiCode(text, i);\n if (ansiResult) {\n tracker.process(ansiResult.code);\n i += ansiResult.length;\n } else {\n i++;\n }\n }\n}\n\nexport function splitIntoTokensWithAnsi(text: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let pendingAnsi = \"\"; // ANSI codes waiting to be attached to next visible content\n let currentKind: \"space\" | \"word\" | null = null;\n let i = 0;\n\n const flushCurrent = (): void => {\n if (!current) {\n return;\n }\n tokens.push(current);\n current = \"\";\n currentKind = null;\n };\n\n while (i < text.length) {\n const ansiResult = extractAnsiCode(text, i);\n if (ansiResult) {\n // Hold ANSI codes separately - they'll be attached to the next visible char\n pendingAnsi += ansiResult.code;\n i += ansiResult.length;\n continue;\n }\n\n let end = i;\n while (end < text.length && !extractAnsiCode(text, end)) {\n end++;\n }\n\n for (const { segment } of graphemeSegmenter.segment(text.slice(i, end))) {\n const segmentIsSpace = segment === \" \";\n if (!segmentIsSpace && cjkBreakRegex.test(segment)) {\n flushCurrent();\n const token = pendingAnsi + segment;\n pendingAnsi = \"\";\n tokens.push(token);\n continue;\n }\n\n const segmentKind = segmentIsSpace ? \"space\" : \"word\";\n if (current && currentKind !== segmentKind) {\n flushCurrent();\n }\n\n // Attach any pending ANSI codes to this visible character\n if (pendingAnsi) {\n current += pendingAnsi;\n pendingAnsi = \"\";\n }\n\n currentKind = segmentKind;\n current += segment;\n }\n\n i = end;\n }\n\n // Handle any remaining pending ANSI codes (attach to last token)\n if (pendingAnsi) {\n if (current) {\n current += pendingAnsi;\n } else if (tokens.length > 0) {\n tokens[tokens.length - 1] += pendingAnsi;\n } else {\n current = pendingAnsi;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return tokens;\n}\n"]}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { cjkBreakRegex, graphemeSegmenter, THAI_LAO_AM_GLOBAL_REGEX, THAI_LAO_AM_REGEX } from "./constants.js";
|
|
2
|
+
import { extractAnsiCode } from "./segmentation.js";
|
|
3
|
+
export function finalizeTruncatedResult(prefix, prefixWidth, ellipsis, ellipsisWidth, maxWidth, pad) {
|
|
4
|
+
const reset = "\x1b[0m";
|
|
5
|
+
const visibleWidth = prefixWidth + ellipsisWidth;
|
|
6
|
+
let result;
|
|
7
|
+
if (ellipsis.length > 0) {
|
|
8
|
+
result = `${prefix}${reset}${ellipsis}${reset}`;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
result = `${prefix}${reset}`;
|
|
12
|
+
}
|
|
13
|
+
return pad ? result + " ".repeat(Math.max(0, maxWidth - visibleWidth)) : result;
|
|
14
|
+
}
|
|
15
|
+
export function normalizeTerminalOutput(str) {
|
|
16
|
+
if (!THAI_LAO_AM_REGEX.test(str))
|
|
17
|
+
return str;
|
|
18
|
+
return str.replace(THAI_LAO_AM_GLOBAL_REGEX, (char) => (char === "\u0e33" ? "\u0e4d\u0e32" : "\u0ecd\u0eb2"));
|
|
19
|
+
}
|
|
20
|
+
export function parseOsc8Hyperlink(ansiCode) {
|
|
21
|
+
if (!ansiCode.startsWith("\x1b]8;")) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const terminator = ansiCode.endsWith("\x07") ? "\x07" : "\x1b\\";
|
|
25
|
+
const body = ansiCode.slice(4, terminator === "\x07" ? -1 : -2);
|
|
26
|
+
const separatorIndex = body.indexOf(";");
|
|
27
|
+
if (separatorIndex === -1) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const params = body.slice(0, separatorIndex);
|
|
31
|
+
const url = body.slice(separatorIndex + 1);
|
|
32
|
+
if (!url) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return { params, url, terminator };
|
|
36
|
+
}
|
|
37
|
+
export function formatOsc8Hyperlink(hyperlink) {
|
|
38
|
+
return `\x1b]8;${hyperlink.params};${hyperlink.url}${hyperlink.terminator}`;
|
|
39
|
+
}
|
|
40
|
+
export function formatOsc8Close(terminator) {
|
|
41
|
+
return `\x1b]8;;${terminator}`;
|
|
42
|
+
}
|
|
43
|
+
export function updateTrackerFromText(text, tracker) {
|
|
44
|
+
let i = 0;
|
|
45
|
+
while (i < text.length) {
|
|
46
|
+
const ansiResult = extractAnsiCode(text, i);
|
|
47
|
+
if (ansiResult) {
|
|
48
|
+
tracker.process(ansiResult.code);
|
|
49
|
+
i += ansiResult.length;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
i++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function splitIntoTokensWithAnsi(text) {
|
|
57
|
+
const tokens = [];
|
|
58
|
+
let current = "";
|
|
59
|
+
let pendingAnsi = ""; // ANSI codes waiting to be attached to next visible content
|
|
60
|
+
let currentKind = null;
|
|
61
|
+
let i = 0;
|
|
62
|
+
const flushCurrent = () => {
|
|
63
|
+
if (!current) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
tokens.push(current);
|
|
67
|
+
current = "";
|
|
68
|
+
currentKind = null;
|
|
69
|
+
};
|
|
70
|
+
while (i < text.length) {
|
|
71
|
+
const ansiResult = extractAnsiCode(text, i);
|
|
72
|
+
if (ansiResult) {
|
|
73
|
+
// Hold ANSI codes separately - they'll be attached to the next visible char
|
|
74
|
+
pendingAnsi += ansiResult.code;
|
|
75
|
+
i += ansiResult.length;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
let end = i;
|
|
79
|
+
while (end < text.length && !extractAnsiCode(text, end)) {
|
|
80
|
+
end++;
|
|
81
|
+
}
|
|
82
|
+
for (const { segment } of graphemeSegmenter.segment(text.slice(i, end))) {
|
|
83
|
+
const segmentIsSpace = segment === " ";
|
|
84
|
+
if (!segmentIsSpace && cjkBreakRegex.test(segment)) {
|
|
85
|
+
flushCurrent();
|
|
86
|
+
const token = pendingAnsi + segment;
|
|
87
|
+
pendingAnsi = "";
|
|
88
|
+
tokens.push(token);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const segmentKind = segmentIsSpace ? "space" : "word";
|
|
92
|
+
if (current && currentKind !== segmentKind) {
|
|
93
|
+
flushCurrent();
|
|
94
|
+
}
|
|
95
|
+
// Attach any pending ANSI codes to this visible character
|
|
96
|
+
if (pendingAnsi) {
|
|
97
|
+
current += pendingAnsi;
|
|
98
|
+
pendingAnsi = "";
|
|
99
|
+
}
|
|
100
|
+
currentKind = segmentKind;
|
|
101
|
+
current += segment;
|
|
102
|
+
}
|
|
103
|
+
i = end;
|
|
104
|
+
}
|
|
105
|
+
// Handle any remaining pending ANSI codes (attach to last token)
|
|
106
|
+
if (pendingAnsi) {
|
|
107
|
+
if (current) {
|
|
108
|
+
current += pendingAnsi;
|
|
109
|
+
}
|
|
110
|
+
else if (tokens.length > 0) {
|
|
111
|
+
tokens[tokens.length - 1] += pendingAnsi;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
current = pendingAnsi;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (current) {
|
|
118
|
+
tokens.push(current);
|
|
119
|
+
}
|
|
120
|
+
return tokens;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=terminal-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-output.js","sourceRoot":"","sources":["../../src/utils/terminal-output.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnsiCodeTracker } from \"./ansicodetracker.ts\";\nimport { cjkBreakRegex, graphemeSegmenter, THAI_LAO_AM_GLOBAL_REGEX, THAI_LAO_AM_REGEX } from \"./constants.ts\";\nimport { extractAnsiCode } from \"./segmentation.ts\";\nimport type { ActiveHyperlink, Osc8Terminator } from \"./types.ts\";\n\nexport function finalizeTruncatedResult(\n prefix: string,\n prefixWidth: number,\n ellipsis: string,\n ellipsisWidth: number,\n maxWidth: number,\n pad: boolean,\n): string {\n const reset = \"\\x1b[0m\";\n const visibleWidth = prefixWidth + ellipsisWidth;\n let result: string;\n\n if (ellipsis.length > 0) {\n result = `${prefix}${reset}${ellipsis}${reset}`;\n } else {\n result = `${prefix}${reset}`;\n }\n\n return pad ? result + \" \".repeat(Math.max(0, maxWidth - visibleWidth)) : result;\n}\n\nexport function normalizeTerminalOutput(str: string): string {\n if (!THAI_LAO_AM_REGEX.test(str)) return str;\n return str.replace(THAI_LAO_AM_GLOBAL_REGEX, (char) => (char === \"\\u0e33\" ? \"\\u0e4d\\u0e32\" : \"\\u0ecd\\u0eb2\"));\n}\n\nexport function parseOsc8Hyperlink(ansiCode: string): ActiveHyperlink | null | undefined {\n if (!ansiCode.startsWith(\"\\x1b]8;\")) {\n return undefined;\n }\n\n const terminator: Osc8Terminator = ansiCode.endsWith(\"\\x07\") ? \"\\x07\" : \"\\x1b\\\\\";\n const body = ansiCode.slice(4, terminator === \"\\x07\" ? -1 : -2);\n const separatorIndex = body.indexOf(\";\");\n if (separatorIndex === -1) {\n return undefined;\n }\n\n const params = body.slice(0, separatorIndex);\n const url = body.slice(separatorIndex + 1);\n if (!url) {\n return null;\n }\n return { params, url, terminator };\n}\n\nexport function formatOsc8Hyperlink(hyperlink: ActiveHyperlink): string {\n return `\\x1b]8;${hyperlink.params};${hyperlink.url}${hyperlink.terminator}`;\n}\n\nexport function formatOsc8Close(terminator: Osc8Terminator): string {\n return `\\x1b]8;;${terminator}`;\n}\n\nexport function updateTrackerFromText(text: string, tracker: AnsiCodeTracker): void {\n let i = 0;\n while (i < text.length) {\n const ansiResult = extractAnsiCode(text, i);\n if (ansiResult) {\n tracker.process(ansiResult.code);\n i += ansiResult.length;\n } else {\n i++;\n }\n }\n}\n\nexport function splitIntoTokensWithAnsi(text: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let pendingAnsi = \"\"; // ANSI codes waiting to be attached to next visible content\n let currentKind: \"space\" | \"word\" | null = null;\n let i = 0;\n\n const flushCurrent = (): void => {\n if (!current) {\n return;\n }\n tokens.push(current);\n current = \"\";\n currentKind = null;\n };\n\n while (i < text.length) {\n const ansiResult = extractAnsiCode(text, i);\n if (ansiResult) {\n // Hold ANSI codes separately - they'll be attached to the next visible char\n pendingAnsi += ansiResult.code;\n i += ansiResult.length;\n continue;\n }\n\n let end = i;\n while (end < text.length && !extractAnsiCode(text, end)) {\n end++;\n }\n\n for (const { segment } of graphemeSegmenter.segment(text.slice(i, end))) {\n const segmentIsSpace = segment === \" \";\n if (!segmentIsSpace && cjkBreakRegex.test(segment)) {\n flushCurrent();\n const token = pendingAnsi + segment;\n pendingAnsi = \"\";\n tokens.push(token);\n continue;\n }\n\n const segmentKind = segmentIsSpace ? \"space\" : \"word\";\n if (current && currentKind !== segmentKind) {\n flushCurrent();\n }\n\n // Attach any pending ANSI codes to this visible character\n if (pendingAnsi) {\n current += pendingAnsi;\n pendingAnsi = \"\";\n }\n\n currentKind = segmentKind;\n current += segment;\n }\n\n i = end;\n }\n\n // Handle any remaining pending ANSI codes (attach to last token)\n if (pendingAnsi) {\n if (current) {\n current += pendingAnsi;\n } else if (tokens.length > 0) {\n tokens[tokens.length - 1] += pendingAnsi;\n } else {\n current = pendingAnsi;\n }\n }\n\n if (current) {\n tokens.push(current);\n }\n\n return tokens;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,cAAc,CAAC;CAC5B","sourcesContent":["export type Osc8Terminator = \"\\x07\" | \"\\x1b\\\\\";\n\nexport interface ActiveHyperlink {\n params: string;\n url: string;\n terminator: Osc8Terminator;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"","sourcesContent":["export type Osc8Terminator = \"\\x07\" | \"\\x1b\\\\\";\n\nexport interface ActiveHyperlink {\n params: string;\n url: string;\n terminator: Osc8Terminator;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"width-truncation.d.ts","sourceRoot":"","sources":["../../src/utils/width-truncation.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA0EvG;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuDhD","sourcesContent":["import { graphemeSegmenter, WIDTH_CACHE_SIZE, widthCache } from \"./constants.ts\";\nimport { extractAnsiCode, graphemeWidth, isPrintableAscii } from \"./segmentation.ts\";\n\nexport function truncateFragmentToWidth(text: string, maxWidth: number): { text: string; width: number } {\n if (isPrintableAscii(text)) {\n const clipped = text.slice(0, maxWidth);\n return { text: clipped, width: clipped.length };\n }\n\n const hasAnsi = text.includes(\"\\x1b\");\n const hasTabs = text.includes(\"\\t\");\n if (!hasAnsi && !hasTabs) {\n let result = \"\";\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(text)) {\n const w = graphemeWidth(segment);\n if (width + w > maxWidth) {\n break;\n }\n result += segment;\n width += w;\n }\n return { text: result, width };\n }\n\n let result = \"\";\n let width = 0;\n let i = 0;\n let pendingAnsi = \"\";\n\n while (i < text.length) {\n const ansi = extractAnsiCode(text, i);\n if (ansi) {\n pendingAnsi += ansi.code;\n i += ansi.length;\n continue;\n }\n\n if (text[i] === \"\\t\") {\n if (width + 4 > maxWidth) {\n break;\n }\n if (pendingAnsi) {\n result += pendingAnsi;\n pendingAnsi = \"\";\n }\n result += \"\\t\";\n width += 4;\n i++;\n continue;\n }\n\n let end = i;\n while (end < text.length && text[end] !== \"\\t\") {\n const nextAnsi = extractAnsiCode(text, end);\n if (nextAnsi) {\n break;\n }\n end++;\n }\n\n for (const { segment } of graphemeSegmenter.segment(text.slice(i, end))) {\n const w = graphemeWidth(segment);\n if (width + w > maxWidth) {\n return { text: result, width };\n }\n if (pendingAnsi) {\n result += pendingAnsi;\n pendingAnsi = \"\";\n }\n result += segment;\n width += w;\n }\n i = end;\n }\n\n return { text: result, width };\n}\n\nexport function visibleWidth(str: string): number {\n if (str.length === 0) {\n return 0;\n }\n\n // Fast path: pure ASCII printable\n if (isPrintableAscii(str)) {\n return str.length;\n }\n\n // Check cache\n const cached = widthCache.get(str);\n if (cached !== undefined) {\n return cached;\n }\n\n // Normalize: tabs to 4 spaces, strip ANSI escape codes\n let clean = str;\n if (str.includes(\"\\t\")) {\n clean = clean.replace(/\\t/g, \" \");\n }\n if (clean.includes(\"\\x1b\")) {\n // Strip supported ANSI/OSC/APC escape sequences in one pass.\n // This covers CSI styling/cursor codes, OSC hyperlinks and prompt markers,\n // and APC sequences like CURSOR_MARKER.\n let stripped = \"\";\n let i = 0;\n while (i < clean.length) {\n const ansi = extractAnsiCode(clean, i);\n if (ansi) {\n i += ansi.length;\n continue;\n }\n stripped += clean[i];\n i++;\n }\n clean = stripped;\n }\n\n // Calculate width\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(clean)) {\n width += graphemeWidth(segment);\n }\n\n // Cache result\n if (widthCache.size >= WIDTH_CACHE_SIZE) {\n const firstKey = widthCache.keys().next().value;\n if (firstKey !== undefined) {\n widthCache.delete(firstKey);\n }\n }\n widthCache.set(str, width);\n\n return width;\n}\n"]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { graphemeSegmenter, WIDTH_CACHE_SIZE, widthCache } from "./constants.js";
|
|
2
|
+
import { extractAnsiCode, graphemeWidth, isPrintableAscii } from "./segmentation.js";
|
|
3
|
+
export function truncateFragmentToWidth(text, maxWidth) {
|
|
4
|
+
if (isPrintableAscii(text)) {
|
|
5
|
+
const clipped = text.slice(0, maxWidth);
|
|
6
|
+
return { text: clipped, width: clipped.length };
|
|
7
|
+
}
|
|
8
|
+
const hasAnsi = text.includes("\x1b");
|
|
9
|
+
const hasTabs = text.includes("\t");
|
|
10
|
+
if (!hasAnsi && !hasTabs) {
|
|
11
|
+
let result = "";
|
|
12
|
+
let width = 0;
|
|
13
|
+
for (const { segment } of graphemeSegmenter.segment(text)) {
|
|
14
|
+
const w = graphemeWidth(segment);
|
|
15
|
+
if (width + w > maxWidth) {
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
result += segment;
|
|
19
|
+
width += w;
|
|
20
|
+
}
|
|
21
|
+
return { text: result, width };
|
|
22
|
+
}
|
|
23
|
+
let result = "";
|
|
24
|
+
let width = 0;
|
|
25
|
+
let i = 0;
|
|
26
|
+
let pendingAnsi = "";
|
|
27
|
+
while (i < text.length) {
|
|
28
|
+
const ansi = extractAnsiCode(text, i);
|
|
29
|
+
if (ansi) {
|
|
30
|
+
pendingAnsi += ansi.code;
|
|
31
|
+
i += ansi.length;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (text[i] === "\t") {
|
|
35
|
+
if (width + 4 > maxWidth) {
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
if (pendingAnsi) {
|
|
39
|
+
result += pendingAnsi;
|
|
40
|
+
pendingAnsi = "";
|
|
41
|
+
}
|
|
42
|
+
result += "\t";
|
|
43
|
+
width += 4;
|
|
44
|
+
i++;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
let end = i;
|
|
48
|
+
while (end < text.length && text[end] !== "\t") {
|
|
49
|
+
const nextAnsi = extractAnsiCode(text, end);
|
|
50
|
+
if (nextAnsi) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
end++;
|
|
54
|
+
}
|
|
55
|
+
for (const { segment } of graphemeSegmenter.segment(text.slice(i, end))) {
|
|
56
|
+
const w = graphemeWidth(segment);
|
|
57
|
+
if (width + w > maxWidth) {
|
|
58
|
+
return { text: result, width };
|
|
59
|
+
}
|
|
60
|
+
if (pendingAnsi) {
|
|
61
|
+
result += pendingAnsi;
|
|
62
|
+
pendingAnsi = "";
|
|
63
|
+
}
|
|
64
|
+
result += segment;
|
|
65
|
+
width += w;
|
|
66
|
+
}
|
|
67
|
+
i = end;
|
|
68
|
+
}
|
|
69
|
+
return { text: result, width };
|
|
70
|
+
}
|
|
71
|
+
export function visibleWidth(str) {
|
|
72
|
+
if (str.length === 0) {
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
// Fast path: pure ASCII printable
|
|
76
|
+
if (isPrintableAscii(str)) {
|
|
77
|
+
return str.length;
|
|
78
|
+
}
|
|
79
|
+
// Check cache
|
|
80
|
+
const cached = widthCache.get(str);
|
|
81
|
+
if (cached !== undefined) {
|
|
82
|
+
return cached;
|
|
83
|
+
}
|
|
84
|
+
// Normalize: tabs to 4 spaces, strip ANSI escape codes
|
|
85
|
+
let clean = str;
|
|
86
|
+
if (str.includes("\t")) {
|
|
87
|
+
clean = clean.replace(/\t/g, " ");
|
|
88
|
+
}
|
|
89
|
+
if (clean.includes("\x1b")) {
|
|
90
|
+
// Strip supported ANSI/OSC/APC escape sequences in one pass.
|
|
91
|
+
// This covers CSI styling/cursor codes, OSC hyperlinks and prompt markers,
|
|
92
|
+
// and APC sequences like CURSOR_MARKER.
|
|
93
|
+
let stripped = "";
|
|
94
|
+
let i = 0;
|
|
95
|
+
while (i < clean.length) {
|
|
96
|
+
const ansi = extractAnsiCode(clean, i);
|
|
97
|
+
if (ansi) {
|
|
98
|
+
i += ansi.length;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
stripped += clean[i];
|
|
102
|
+
i++;
|
|
103
|
+
}
|
|
104
|
+
clean = stripped;
|
|
105
|
+
}
|
|
106
|
+
// Calculate width
|
|
107
|
+
let width = 0;
|
|
108
|
+
for (const { segment } of graphemeSegmenter.segment(clean)) {
|
|
109
|
+
width += graphemeWidth(segment);
|
|
110
|
+
}
|
|
111
|
+
// Cache result
|
|
112
|
+
if (widthCache.size >= WIDTH_CACHE_SIZE) {
|
|
113
|
+
const firstKey = widthCache.keys().next().value;
|
|
114
|
+
if (firstKey !== undefined) {
|
|
115
|
+
widthCache.delete(firstKey);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
widthCache.set(str, width);
|
|
119
|
+
return width;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=width-truncation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"width-truncation.js","sourceRoot":"","sources":["../../src/utils/width-truncation.ts"],"names":[],"mappings":"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","sourcesContent":["import { graphemeSegmenter, WIDTH_CACHE_SIZE, widthCache } from \"./constants.ts\";\nimport { extractAnsiCode, graphemeWidth, isPrintableAscii } from \"./segmentation.ts\";\n\nexport function truncateFragmentToWidth(text: string, maxWidth: number): { text: string; width: number } {\n if (isPrintableAscii(text)) {\n const clipped = text.slice(0, maxWidth);\n return { text: clipped, width: clipped.length };\n }\n\n const hasAnsi = text.includes(\"\\x1b\");\n const hasTabs = text.includes(\"\\t\");\n if (!hasAnsi && !hasTabs) {\n let result = \"\";\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(text)) {\n const w = graphemeWidth(segment);\n if (width + w > maxWidth) {\n break;\n }\n result += segment;\n width += w;\n }\n return { text: result, width };\n }\n\n let result = \"\";\n let width = 0;\n let i = 0;\n let pendingAnsi = \"\";\n\n while (i < text.length) {\n const ansi = extractAnsiCode(text, i);\n if (ansi) {\n pendingAnsi += ansi.code;\n i += ansi.length;\n continue;\n }\n\n if (text[i] === \"\\t\") {\n if (width + 4 > maxWidth) {\n break;\n }\n if (pendingAnsi) {\n result += pendingAnsi;\n pendingAnsi = \"\";\n }\n result += \"\\t\";\n width += 4;\n i++;\n continue;\n }\n\n let end = i;\n while (end < text.length && text[end] !== \"\\t\") {\n const nextAnsi = extractAnsiCode(text, end);\n if (nextAnsi) {\n break;\n }\n end++;\n }\n\n for (const { segment } of graphemeSegmenter.segment(text.slice(i, end))) {\n const w = graphemeWidth(segment);\n if (width + w > maxWidth) {\n return { text: result, width };\n }\n if (pendingAnsi) {\n result += pendingAnsi;\n pendingAnsi = \"\";\n }\n result += segment;\n width += w;\n }\n i = end;\n }\n\n return { text: result, width };\n}\n\nexport function visibleWidth(str: string): number {\n if (str.length === 0) {\n return 0;\n }\n\n // Fast path: pure ASCII printable\n if (isPrintableAscii(str)) {\n return str.length;\n }\n\n // Check cache\n const cached = widthCache.get(str);\n if (cached !== undefined) {\n return cached;\n }\n\n // Normalize: tabs to 4 spaces, strip ANSI escape codes\n let clean = str;\n if (str.includes(\"\\t\")) {\n clean = clean.replace(/\\t/g, \" \");\n }\n if (clean.includes(\"\\x1b\")) {\n // Strip supported ANSI/OSC/APC escape sequences in one pass.\n // This covers CSI styling/cursor codes, OSC hyperlinks and prompt markers,\n // and APC sequences like CURSOR_MARKER.\n let stripped = \"\";\n let i = 0;\n while (i < clean.length) {\n const ansi = extractAnsiCode(clean, i);\n if (ansi) {\n i += ansi.length;\n continue;\n }\n stripped += clean[i];\n i++;\n }\n clean = stripped;\n }\n\n // Calculate width\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(clean)) {\n width += graphemeWidth(segment);\n }\n\n // Cache result\n if (widthCache.size >= WIDTH_CACHE_SIZE) {\n const firstKey = widthCache.keys().next().value;\n if (firstKey !== undefined) {\n widthCache.delete(firstKey);\n }\n }\n widthCache.set(str, width);\n\n return width;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AnsiCodeTracker } from "./ansicodetracker.ts";
|
|
2
|
+
export declare function breakLongWord(word: string, width: number, tracker: AnsiCodeTracker): string[];
|
|
3
|
+
export declare function wrapSingleLine(line: string, width: number): string[];
|
|
4
|
+
//# sourceMappingURL=word-wrapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"word-wrapping.d.ts","sourceRoot":"","sources":["../../src/utils/word-wrapping.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAMvD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAmE7F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+EpE","sourcesContent":["import { AnsiCodeTracker } from \"./ansicodetracker.ts\";\nimport { graphemeSegmenter } from \"./constants.ts\";\nimport { extractAnsiCode } from \"./segmentation.ts\";\nimport { splitIntoTokensWithAnsi, updateTrackerFromText } from \"./terminal-output.ts\";\nimport { visibleWidth } from \"./width-truncation.ts\";\n\nexport function breakLongWord(word: string, width: number, tracker: AnsiCodeTracker): string[] {\n const lines: string[] = [];\n let currentLine = tracker.getActiveCodes();\n let currentWidth = 0;\n\n // First, separate ANSI codes from visible content\n // We need to handle ANSI codes specially since they're not graphemes\n let i = 0;\n const segments: Array<{ type: \"ansi\" | \"grapheme\"; value: string }> = [];\n\n while (i < word.length) {\n const ansiResult = extractAnsiCode(word, i);\n if (ansiResult) {\n segments.push({ type: \"ansi\", value: ansiResult.code });\n i += ansiResult.length;\n } else {\n // Find the next ANSI code or end of string\n let end = i;\n while (end < word.length) {\n const nextAnsi = extractAnsiCode(word, end);\n if (nextAnsi) break;\n end++;\n }\n // Segment this non-ANSI portion into graphemes\n const textPortion = word.slice(i, end);\n for (const seg of graphemeSegmenter.segment(textPortion)) {\n segments.push({ type: \"grapheme\", value: seg.segment });\n }\n i = end;\n }\n }\n\n // Now process segments\n for (const seg of segments) {\n if (seg.type === \"ansi\") {\n currentLine += seg.value;\n tracker.process(seg.value);\n continue;\n }\n\n const grapheme = seg.value;\n // Skip empty graphemes to avoid issues with string-width calculation\n if (!grapheme) continue;\n\n const graphemeWidth = visibleWidth(grapheme);\n\n if (currentWidth + graphemeWidth > width) {\n // Add specific reset for underline only (preserves background)\n const lineEndReset = tracker.getLineEndReset();\n if (lineEndReset) {\n currentLine += lineEndReset;\n }\n lines.push(currentLine);\n currentLine = tracker.getActiveCodes();\n currentWidth = 0;\n }\n\n currentLine += grapheme;\n currentWidth += graphemeWidth;\n }\n\n if (currentLine) {\n // No reset at end of final segment - caller handles continuation\n lines.push(currentLine);\n }\n\n return lines.length > 0 ? lines : [\"\"];\n}\n\nexport function wrapSingleLine(line: string, width: number): string[] {\n if (!line) {\n return [\"\"];\n }\n\n const visibleLength = visibleWidth(line);\n if (visibleLength <= width) {\n return [line];\n }\n\n const wrapped: string[] = [];\n const tracker = new AnsiCodeTracker();\n const tokens = splitIntoTokensWithAnsi(line);\n\n let currentLine = \"\";\n let currentVisibleLength = 0;\n\n for (const token of tokens) {\n const tokenVisibleLength = visibleWidth(token);\n const isWhitespace = token.trim() === \"\";\n\n // Token itself is too long - break it character by character\n if (tokenVisibleLength > width && !isWhitespace) {\n if (currentLine) {\n // Add specific reset for underline only (preserves background)\n const lineEndReset = tracker.getLineEndReset();\n if (lineEndReset) {\n currentLine += lineEndReset;\n }\n wrapped.push(currentLine);\n currentLine = \"\";\n currentVisibleLength = 0;\n }\n\n // Break long token - breakLongWord handles its own resets\n const broken = breakLongWord(token, width, tracker);\n for (let i = 0; i < broken.length - 1; i++) {\n wrapped.push(broken[i]!);\n }\n currentLine = broken[broken.length - 1];\n currentVisibleLength = visibleWidth(currentLine);\n continue;\n }\n\n // Check if adding this token would exceed width\n const totalNeeded = currentVisibleLength + tokenVisibleLength;\n\n if (totalNeeded > width && currentVisibleLength > 0) {\n // Trim trailing whitespace, then add underline reset (not full reset, to preserve background)\n let lineToWrap = currentLine.trimEnd();\n const lineEndReset = tracker.getLineEndReset();\n if (lineEndReset) {\n lineToWrap += lineEndReset;\n }\n wrapped.push(lineToWrap);\n if (isWhitespace) {\n // Don't start new line with whitespace\n currentLine = tracker.getActiveCodes();\n currentVisibleLength = 0;\n } else {\n currentLine = tracker.getActiveCodes() + token;\n currentVisibleLength = tokenVisibleLength;\n }\n } else {\n // Add to current line\n currentLine += token;\n currentVisibleLength += tokenVisibleLength;\n }\n\n updateTrackerFromText(token, tracker);\n }\n\n if (currentLine) {\n // No reset at end of final line - let caller handle it\n wrapped.push(currentLine);\n }\n\n // Trailing whitespace can cause lines to exceed the requested width\n return wrapped.length > 0 ? wrapped.map((line) => line.trimEnd()) : [\"\"];\n}\n"]}
|