@machina.ai/cell-cli 1.0.13-rc9 → 1.0.21-rc1
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/package.json +11 -7
- package/dist/src/commands/mcp/add.d.ts +7 -0
- package/dist/src/commands/mcp/add.js +166 -0
- package/dist/src/commands/mcp/add.js.map +1 -0
- package/dist/src/commands/mcp/list.d.ts +8 -0
- package/dist/src/commands/mcp/list.js +110 -0
- package/dist/src/commands/mcp/list.js.map +1 -0
- package/dist/src/commands/mcp/remove.d.ts +7 -0
- package/dist/src/commands/mcp/remove.js +44 -0
- package/dist/src/commands/mcp/remove.js.map +1 -0
- package/dist/src/commands/mcp.d.ts +7 -0
- package/dist/src/commands/mcp.js +23 -0
- package/dist/src/commands/mcp.js.map +1 -0
- package/dist/src/config/auth.test.d.ts +6 -0
- package/dist/src/config/auth.test.js +28 -0
- package/dist/src/config/auth.test.js.map +1 -0
- package/dist/src/config/config.d.ts +6 -3
- package/dist/src/config/config.js +177 -90
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/extension.d.ts +1 -0
- package/dist/src/config/extension.js +4 -0
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +66 -0
- package/dist/src/config/keyBindings.js +141 -0
- package/dist/src/config/keyBindings.js.map +1 -0
- package/dist/src/config/keyBindings.test.d.ts +6 -0
- package/dist/src/config/keyBindings.test.js +51 -0
- package/dist/src/config/keyBindings.test.js.map +1 -0
- package/dist/src/config/sandboxConfig.js +3 -3
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/settings.d.ts +6 -41
- package/dist/src/config/settings.js +137 -52
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +533 -0
- package/dist/src/config/settingsSchema.js +507 -0
- package/dist/src/config/settingsSchema.js.map +1 -0
- package/dist/src/config/settingsSchema.test.d.ts +6 -0
- package/dist/src/config/settingsSchema.test.js +195 -0
- package/dist/src/config/settingsSchema.test.js.map +1 -0
- package/dist/src/config/trustedFolders.d.ts +37 -0
- package/dist/src/config/trustedFolders.js +118 -0
- package/dist/src/config/trustedFolders.js.map +1 -0
- package/dist/src/config/trustedFolders.test.d.ts +6 -0
- package/dist/src/config/trustedFolders.test.js +160 -0
- package/dist/src/config/trustedFolders.test.js.map +1 -0
- package/dist/src/gemini.d.ts +3 -0
- package/dist/src/gemini.js +106 -68
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.d.ts +6 -0
- package/dist/src/gemini.test.js +193 -0
- package/dist/src/gemini.test.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +2 -1
- package/dist/src/generated/git-commit.js +3 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/nonInteractiveCli.js +35 -55
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/patches/is-in-ci.d.ts +7 -0
- package/dist/src/patches/is-in-ci.js +15 -0
- package/dist/src/patches/is-in-ci.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.js +12 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.d.ts +6 -0
- package/dist/src/services/BuiltinCommandLoader.test.js +108 -0
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -0
- package/dist/src/services/CommandService.d.ts +8 -4
- package/dist/src/services/CommandService.js +24 -8
- package/dist/src/services/CommandService.js.map +1 -1
- package/dist/src/services/CommandService.test.d.ts +6 -0
- package/dist/src/services/CommandService.test.js +232 -0
- package/dist/src/services/CommandService.test.js.map +1 -0
- package/dist/src/services/FileCommandLoader.d.ts +15 -3
- package/dist/src/services/FileCommandLoader.js +115 -38
- package/dist/src/services/FileCommandLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.d.ts +25 -0
- package/dist/src/services/McpPromptLoader.js +192 -0
- package/dist/src/services/McpPromptLoader.js.map +1 -0
- package/dist/src/services/prompt-processors/argumentProcessor.d.ts +16 -0
- package/dist/src/services/prompt-processors/argumentProcessor.js +20 -0
- package/dist/src/services/prompt-processors/argumentProcessor.js.map +1 -0
- package/dist/src/services/prompt-processors/shellProcessor.d.ts +35 -0
- package/dist/src/services/prompt-processors/shellProcessor.js +170 -0
- package/dist/src/services/prompt-processors/shellProcessor.js.map +1 -0
- package/dist/src/services/prompt-processors/types.d.ts +40 -0
- package/dist/src/services/prompt-processors/types.js +16 -0
- package/dist/src/services/prompt-processors/types.js.map +1 -0
- package/dist/src/test-utils/customMatchers.d.ts +14 -0
- package/dist/src/test-utils/customMatchers.js +46 -0
- package/dist/src/test-utils/customMatchers.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.d.ts +18 -0
- package/dist/src/test-utils/mockCommandContext.js +86 -0
- package/dist/src/test-utils/mockCommandContext.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.test.d.ts +6 -0
- package/dist/src/test-utils/mockCommandContext.test.js +51 -0
- package/dist/src/test-utils/mockCommandContext.test.js.map +1 -0
- package/dist/src/test-utils/render.d.ts +8 -0
- package/dist/src/test-utils/render.js +10 -0
- package/dist/src/test-utils/render.js.map +1 -0
- package/dist/src/ui/App.js +229 -67
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/IdeIntegrationNudge.d.ts +16 -0
- package/dist/src/ui/IdeIntegrationNudge.js +52 -0
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -0
- package/dist/src/ui/colors.js +6 -0
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +9 -5
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/bugCommand.js +13 -5
- package/dist/src/ui/commands/bugCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +66 -6
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.d.ts +8 -0
- package/dist/src/ui/commands/directoryCommand.js +134 -0
- package/dist/src/ui/commands/directoryCommand.js.map +1 -0
- package/dist/src/ui/commands/docsCommand.js +1 -1
- package/dist/src/ui/commands/docsCommand.js.map +1 -1
- package/dist/src/ui/commands/helpCommand.js +7 -6
- package/dist/src/ui/commands/helpCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +179 -109
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/initCommand.d.ts +7 -0
- package/dist/src/ui/commands/initCommand.js +76 -0
- package/dist/src/ui/commands/initCommand.js.map +1 -0
- package/dist/src/ui/commands/mcpCommand.js +244 -26
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +9 -4
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/settingsCommand.d.ts +7 -0
- package/dist/src/ui/commands/settingsCommand.js +16 -0
- package/dist/src/ui/commands/settingsCommand.js.map +1 -0
- package/dist/src/ui/commands/setupGithubCommand.d.ts +7 -0
- package/dist/src/ui/commands/setupGithubCommand.js +115 -0
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -0
- package/dist/src/ui/commands/setupGithubCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/setupGithubCommand.test.js +74 -0
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -0
- package/dist/src/ui/commands/terminalSetupCommand.d.ts +13 -0
- package/dist/src/ui/commands/terminalSetupCommand.js +41 -0
- package/dist/src/ui/commands/terminalSetupCommand.js.map +1 -0
- package/dist/src/ui/commands/types.d.ts +42 -3
- package/dist/src/ui/commands/types.js +1 -0
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/vimCommand.d.ts +7 -0
- package/dist/src/ui/commands/vimCommand.js +23 -0
- package/dist/src/ui/commands/vimCommand.js.map +1 -0
- package/dist/src/ui/components/AboutBox.d.ts +1 -0
- package/dist/src/ui/components/AboutBox.js +1 -1
- package/dist/src/ui/components/AboutBox.js.map +1 -1
- package/dist/src/ui/components/AsciiArt.d.ts +3 -2
- package/dist/src/ui/components/AsciiArt.js +23 -12
- package/dist/src/ui/components/AsciiArt.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +12 -6
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.test.d.ts +6 -0
- package/dist/src/ui/components/AuthDialog.test.js +114 -0
- package/dist/src/ui/components/AuthDialog.test.js.map +1 -0
- package/dist/src/ui/components/AuthInProgress.js +5 -4
- package/dist/src/ui/components/AuthInProgress.js.map +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.d.ts +2 -2
- package/dist/src/ui/components/ContextSummaryDisplay.js +31 -34
- package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.d.ts +9 -0
- package/dist/src/ui/components/ContextUsageDisplay.js +14 -0
- package/dist/src/ui/components/ContextUsageDisplay.js.map +1 -0
- package/dist/src/ui/components/DebugProfiler.d.ts +6 -0
- package/dist/src/ui/components/DebugProfiler.js +27 -0
- package/dist/src/ui/components/DebugProfiler.js.map +1 -0
- package/dist/src/ui/components/EditorSettingsDialog.js +6 -5
- package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.d.ts +16 -0
- package/dist/src/ui/components/FolderTrustDialog.js +39 -0
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -0
- package/dist/src/ui/components/FolderTrustDialog.test.d.ts +6 -0
- package/dist/src/ui/components/FolderTrustDialog.test.js +26 -0
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -0
- package/dist/src/ui/components/Footer.d.ts +2 -0
- package/dist/src/ui/components/Footer.js +18 -7
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Header.d.ts +0 -1
- package/dist/src/ui/components/Header.js +13 -5
- package/dist/src/ui/components/Header.js.map +1 -1
- package/dist/src/ui/components/Header.test.d.ts +6 -0
- package/dist/src/ui/components/Header.test.js +44 -0
- package/dist/src/ui/components/Header.test.js.map +1 -0
- package/dist/src/ui/components/Help.js +2 -2
- package/dist/src/ui/components/Help.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.d.ts +2 -0
- package/dist/src/ui/components/HistoryItemDisplay.js +2 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.d.ts +6 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js +91 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -0
- package/dist/src/ui/components/InputPrompt.d.ts +3 -0
- package/dist/src/ui/components/InputPrompt.js +179 -126
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.js +10 -5
- package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.test.d.ts +6 -0
- package/dist/src/ui/components/LoadingIndicator.test.js +190 -0
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -0
- package/dist/src/ui/components/PrepareLabel.d.ts +15 -0
- package/dist/src/ui/components/PrepareLabel.js +16 -0
- package/dist/src/ui/components/PrepareLabel.js.map +1 -0
- package/dist/src/ui/components/SettingsDialog.d.ts +14 -0
- package/dist/src/ui/components/SettingsDialog.js +519 -0
- package/dist/src/ui/components/SettingsDialog.js.map +1 -0
- package/dist/src/ui/components/SettingsDialog.test.d.ts +6 -0
- package/dist/src/ui/components/SettingsDialog.test.js +568 -0
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -0
- package/dist/src/ui/components/ShellConfirmationDialog.d.ts +15 -0
- package/dist/src/ui/components/ShellConfirmationDialog.js +46 -0
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.d.ts +6 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.js +40 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -0
- package/dist/src/ui/components/StatsDisplay.js +8 -7
- package/dist/src/ui/components/StatsDisplay.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.d.ts +1 -0
- package/dist/src/ui/components/SuggestionsDisplay.js +3 -3
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.js +20 -25
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/Tips.js +1 -1
- package/dist/src/ui/components/Tips.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.js +21 -11
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.d.ts +6 -0
- package/dist/src/ui/components/messages/DiffRenderer.test.js +239 -0
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -0
- package/dist/src/ui/components/messages/InfoMessage.js +2 -1
- package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +52 -18
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +37 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolMessage.test.js +118 -0
- package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -0
- package/dist/src/ui/components/messages/UserMessage.js +4 -1
- package/dist/src/ui/components/messages/UserMessage.js.map +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.js +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.js.map +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.test.d.ts +6 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +154 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.js +11 -9
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.d.ts +6 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js +111 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js.map +1 -0
- package/dist/src/ui/components/shared/text-buffer.d.ts +286 -3
- package/dist/src/ui/components/shared/text-buffer.js +612 -89
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/vim-buffer-actions.d.ts +72 -0
- package/dist/src/ui/components/shared/vim-buffer-actions.js +552 -0
- package/dist/src/ui/components/shared/vim-buffer-actions.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.d.ts +30 -0
- package/dist/src/ui/contexts/KeypressContext.js +309 -0
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.test.d.ts +6 -0
- package/dist/src/ui/contexts/KeypressContext.test.js +219 -0
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -0
- package/dist/src/ui/contexts/SessionContext.d.ts +3 -0
- package/dist/src/ui/contexts/SessionContext.js +2 -1
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/contexts/SettingsContext.d.ts +9 -0
- package/dist/src/ui/contexts/SettingsContext.js +15 -0
- package/dist/src/ui/contexts/SettingsContext.js.map +1 -0
- package/dist/src/ui/contexts/VimModeContext.d.ts +19 -0
- package/dist/src/ui/contexts/VimModeContext.js +48 -0
- package/dist/src/ui/contexts/VimModeContext.js.map +1 -0
- package/dist/src/ui/editors/editorSettingsManager.js +6 -13
- package/dist/src/ui/editors/editorSettingsManager.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +82 -62
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.d.ts +6 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.js +809 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.d.ts +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.js +139 -196
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.d.ts +6 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +328 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -0
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +11 -3
- package/dist/src/ui/hooks/slashCommandProcessor.js +237 -90
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.d.ts +23 -0
- package/dist/src/ui/hooks/useAtCompletion.js +178 -0
- package/dist/src/ui/hooks/useAtCompletion.js.map +1 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js +5 -5
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.d.ts +6 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +191 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -0
- package/dist/src/ui/hooks/useCommandCompletion.d.ts +29 -0
- package/dist/src/ui/hooks/useCommandCompletion.js +165 -0
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -0
- package/dist/src/ui/hooks/useCompletion.d.ts +5 -3
- package/dist/src/ui/hooks/useCompletion.js +7 -312
- package/dist/src/ui/hooks/useCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.js +53 -37
- package/dist/src/ui/hooks/useConsoleMessages.js.map +1 -1
- package/dist/src/ui/hooks/useEditorSettings.test.d.ts +6 -0
- package/dist/src/ui/hooks/useEditorSettings.test.js +164 -0
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -0
- package/dist/src/ui/hooks/useFocus.d.ts +4 -0
- package/dist/src/ui/hooks/useFocus.js +4 -4
- package/dist/src/ui/hooks/useFocus.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.d.ts +12 -0
- package/dist/src/ui/hooks/useFolderTrust.js +55 -0
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -1
- package/dist/src/ui/hooks/useGeminiStream.js +40 -26
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.d.ts +6 -0
- package/dist/src/ui/hooks/useGitBranchName.test.js +175 -0
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -0
- package/dist/src/ui/hooks/useHistoryManager.test.d.ts +6 -0
- package/dist/src/ui/hooks/useHistoryManager.test.js +171 -0
- package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -0
- package/dist/src/ui/hooks/useInputHistory.d.ts +1 -1
- package/dist/src/ui/hooks/useInputHistory.test.d.ts +6 -0
- package/dist/src/ui/hooks/useInputHistory.test.js +207 -0
- package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -0
- package/dist/src/ui/hooks/useKeypress.d.ts +4 -16
- package/dist/src/ui/hooks/useKeypress.js +8 -137
- package/dist/src/ui/hooks/useKeypress.js.map +1 -1
- package/dist/src/ui/hooks/useKittyKeyboardProtocol.d.ts +15 -0
- package/dist/src/ui/hooks/useKittyKeyboardProtocol.js +20 -0
- package/dist/src/ui/hooks/useKittyKeyboardProtocol.js.map +1 -0
- package/dist/src/ui/hooks/useLoadingIndicator.test.d.ts +6 -0
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +91 -0
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -0
- package/dist/src/ui/hooks/useMessageQueue.d.ts +22 -0
- package/dist/src/ui/hooks/useMessageQueue.js +49 -0
- package/dist/src/ui/hooks/useMessageQueue.js.map +1 -0
- package/dist/src/ui/hooks/useMessageQueue.test.d.ts +6 -0
- package/dist/src/ui/hooks/useMessageQueue.test.js +158 -0
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -0
- package/dist/src/ui/hooks/usePhraseCycler.js +3 -5
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.js +6 -2
- package/dist/src/ui/hooks/usePrivacySettings.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.d.ts +6 -0
- package/dist/src/ui/hooks/usePrivacySettings.test.js +154 -0
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -0
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +18 -17
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useReverseSearchCompletion.d.ts +19 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.js +56 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.js.map +1 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.d.ts +6 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +163 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -0
- package/dist/src/ui/hooks/useSettingsCommand.d.ts +10 -0
- package/dist/src/ui/hooks/useSettingsCommand.js +21 -0
- package/dist/src/ui/hooks/useSettingsCommand.js.map +1 -0
- package/dist/src/ui/hooks/useShellHistory.d.ts +4 -2
- package/dist/src/ui/hooks/useShellHistory.js +30 -7
- package/dist/src/ui/hooks/useShellHistory.js.map +1 -1
- package/dist/src/ui/hooks/useShellHistory.test.d.ts +6 -0
- package/dist/src/ui/hooks/useShellHistory.test.js +159 -0
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -0
- package/dist/src/ui/hooks/useSlashCompletion.d.ts +20 -0
- package/dist/src/ui/hooks/useSlashCompletion.js +135 -0
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.d.ts +6 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.js +272 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -0
- package/dist/src/ui/hooks/useThemeCommand.js +1 -1
- package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
- package/dist/src/ui/hooks/useTimer.test.d.ts +6 -0
- package/dist/src/ui/hooks/useTimer.test.js +90 -0
- package/dist/src/ui/hooks/useTimer.test.js.map +1 -0
- package/dist/src/ui/hooks/useToolScheduler.test.d.ts +6 -0
- package/dist/src/ui/hooks/useToolScheduler.test.js +846 -0
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -0
- package/dist/src/ui/hooks/vim.d.ts +28 -0
- package/dist/src/ui/hooks/vim.js +639 -0
- package/dist/src/ui/hooks/vim.js.map +1 -0
- package/dist/src/ui/keyMatchers.d.ts +26 -0
- package/dist/src/ui/keyMatchers.js +68 -0
- package/dist/src/ui/keyMatchers.js.map +1 -0
- package/dist/src/ui/keyMatchers.test.d.ts +6 -0
- package/dist/src/ui/keyMatchers.test.js +276 -0
- package/dist/src/ui/keyMatchers.test.js.map +1 -0
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.js +5 -4
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.js.map +1 -1
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.js +5 -4
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.js.map +1 -1
- package/dist/src/ui/privacy/GeminiPrivacyNotice.js +5 -4
- package/dist/src/ui/privacy/GeminiPrivacyNotice.js.map +1 -1
- package/dist/src/ui/semantic-colors.d.ts +7 -0
- package/dist/src/ui/semantic-colors.js +24 -0
- package/dist/src/ui/semantic-colors.js.map +1 -0
- package/dist/src/ui/themes/ansi-light.js +4 -1
- package/dist/src/ui/themes/ansi-light.js.map +1 -1
- package/dist/src/ui/themes/ansi.js +4 -1
- package/dist/src/ui/themes/ansi.js.map +1 -1
- package/dist/src/ui/themes/atom-one-dark.js +4 -1
- package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
- package/dist/src/ui/themes/ayu-light.js +5 -2
- package/dist/src/ui/themes/ayu-light.js.map +1 -1
- package/dist/src/ui/themes/ayu.js +5 -2
- package/dist/src/ui/themes/ayu.js.map +1 -1
- package/dist/src/ui/themes/color-utils.test.d.ts +6 -0
- package/dist/src/ui/themes/color-utils.test.js +197 -0
- package/dist/src/ui/themes/color-utils.test.js.map +1 -0
- package/dist/src/ui/themes/default-light.js +2 -1
- package/dist/src/ui/themes/default-light.js.map +1 -1
- package/dist/src/ui/themes/default.js +2 -1
- package/dist/src/ui/themes/default.js.map +1 -1
- package/dist/src/ui/themes/dracula.js +4 -1
- package/dist/src/ui/themes/dracula.js.map +1 -1
- package/dist/src/ui/themes/github-dark.js +4 -1
- package/dist/src/ui/themes/github-dark.js.map +1 -1
- package/dist/src/ui/themes/github-light.js +4 -1
- package/dist/src/ui/themes/github-light.js.map +1 -1
- package/dist/src/ui/themes/googlecode.js +4 -1
- package/dist/src/ui/themes/googlecode.js.map +1 -1
- package/dist/src/ui/themes/no-color.js +32 -1
- package/dist/src/ui/themes/no-color.js.map +1 -1
- package/dist/src/ui/themes/semantic-tokens.d.ts +37 -0
- package/dist/src/ui/themes/semantic-tokens.js +94 -0
- package/dist/src/ui/themes/semantic-tokens.js.map +1 -0
- package/dist/src/ui/themes/shades-of-purple.js +4 -1
- package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.d.ts +6 -0
- package/dist/src/ui/themes/theme-manager.js +18 -2
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.test.d.ts +6 -0
- package/dist/src/ui/themes/theme-manager.test.js +83 -0
- package/dist/src/ui/themes/theme-manager.test.js.map +1 -0
- package/dist/src/ui/themes/theme.d.ts +48 -2
- package/dist/src/ui/themes/theme.js +102 -92
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/themes/xcode.js +4 -1
- package/dist/src/ui/themes/xcode.js.map +1 -1
- package/dist/src/ui/types.d.ts +13 -2
- package/dist/src/ui/types.js +1 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.d.ts +3 -1
- package/dist/src/ui/utils/CodeColorizer.js +22 -9
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/ConsolePatcher.d.ts +3 -1
- package/dist/src/ui/utils/ConsolePatcher.js +18 -8
- package/dist/src/ui/utils/ConsolePatcher.js.map +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.js +8 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +4 -2
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.test.d.ts +6 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js +151 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -0
- package/dist/src/ui/utils/clipboardUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/clipboardUtils.test.js +65 -0
- package/dist/src/ui/utils/clipboardUtils.test.js.map +1 -0
- package/dist/src/ui/utils/commandUtils.d.ts +1 -0
- package/dist/src/ui/utils/commandUtils.js +22 -1
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/commandUtils.test.js +294 -0
- package/dist/src/ui/utils/commandUtils.test.js.map +1 -0
- package/dist/src/ui/utils/computeStats.js +3 -1
- package/dist/src/ui/utils/computeStats.js.map +1 -1
- package/dist/src/ui/utils/displayUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/displayUtils.test.js +42 -0
- package/dist/src/ui/utils/displayUtils.test.js.map +1 -0
- package/dist/src/ui/utils/formatters.test.d.ts +6 -0
- package/dist/src/ui/utils/formatters.test.js +56 -0
- package/dist/src/ui/utils/formatters.test.js.map +1 -0
- package/dist/src/ui/utils/isNarrowWidth.d.ts +6 -0
- package/dist/src/ui/utils/isNarrowWidth.js +9 -0
- package/dist/src/ui/utils/isNarrowWidth.js.map +1 -0
- package/dist/src/ui/utils/kittyProtocolDetector.d.ts +13 -0
- package/dist/src/ui/utils/kittyProtocolDetector.js +88 -0
- package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -0
- package/dist/src/ui/utils/markdownUtilities.test.d.ts +6 -0
- package/dist/src/ui/utils/markdownUtilities.test.js +42 -0
- package/dist/src/ui/utils/markdownUtilities.test.js.map +1 -0
- package/dist/src/ui/utils/platformConstants.d.ts +43 -0
- package/dist/src/ui/utils/platformConstants.js +44 -0
- package/dist/src/ui/utils/platformConstants.js.map +1 -0
- package/dist/src/ui/utils/terminalSetup.d.ts +30 -0
- package/dist/src/ui/utils/terminalSetup.js +281 -0
- package/dist/src/ui/utils/terminalSetup.js.map +1 -0
- package/dist/src/ui/utils/textUtils.d.ts +0 -8
- package/dist/src/ui/utils/textUtils.js +0 -22
- package/dist/src/ui/utils/textUtils.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.d.ts +7 -1
- package/dist/src/ui/utils/updateCheck.js +47 -9
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.d.ts +6 -0
- package/dist/src/ui/utils/updateCheck.test.js +145 -0
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -0
- package/dist/src/utils/checks.d.ts +19 -0
- package/dist/src/utils/checks.js +24 -0
- package/dist/src/utils/checks.js.map +1 -0
- package/dist/src/utils/cleanup.d.ts +2 -2
- package/dist/src/utils/cleanup.js +2 -2
- package/dist/src/utils/cleanup.js.map +1 -1
- package/dist/src/utils/dialogScopeUtils.d.ts +31 -0
- package/dist/src/utils/dialogScopeUtils.js +48 -0
- package/dist/src/utils/dialogScopeUtils.js.map +1 -0
- package/dist/src/utils/events.d.ts +11 -0
- package/dist/src/utils/events.js +13 -0
- package/dist/src/utils/events.js.map +1 -0
- package/dist/src/utils/gitUtils.d.ts +30 -0
- package/dist/src/utils/gitUtils.js +89 -0
- package/dist/src/utils/gitUtils.js.map +1 -0
- package/dist/src/utils/gitUtils.test.d.ts +6 -0
- package/dist/src/utils/gitUtils.test.js +113 -0
- package/dist/src/utils/gitUtils.test.js.map +1 -0
- package/dist/src/utils/handleAutoUpdate.d.ts +11 -0
- package/dist/src/utils/handleAutoUpdate.js +101 -0
- package/dist/src/utils/handleAutoUpdate.js.map +1 -0
- package/dist/src/utils/installationInfo.d.ts +23 -0
- package/dist/src/utils/installationInfo.js +154 -0
- package/dist/src/utils/installationInfo.js.map +1 -0
- package/dist/src/utils/installationInfo.test.d.ts +6 -0
- package/dist/src/utils/installationInfo.test.js +242 -0
- package/dist/src/utils/installationInfo.test.js.map +1 -0
- package/dist/src/utils/readStdin.js +10 -0
- package/dist/src/utils/readStdin.js.map +1 -1
- package/dist/src/utils/resolvePath.d.ts +6 -0
- package/dist/src/utils/resolvePath.js +21 -0
- package/dist/src/utils/resolvePath.js.map +1 -0
- package/dist/src/utils/sandbox-macos-permissive-closed.sb +6 -0
- package/dist/src/utils/sandbox-macos-permissive-open.sb +6 -0
- package/dist/src/utils/sandbox-macos-permissive-proxied.sb +6 -0
- package/dist/src/utils/sandbox-macos-restrictive-closed.sb +6 -0
- package/dist/src/utils/sandbox-macos-restrictive-open.sb +6 -0
- package/dist/src/utils/sandbox-macos-restrictive-proxied.sb +6 -0
- package/dist/src/utils/sandbox.d.ts +2 -2
- package/dist/src/utils/sandbox.js +448 -397
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/settingsUtils.d.ts +134 -0
- package/dist/src/utils/settingsUtils.js +336 -0
- package/dist/src/utils/settingsUtils.js.map +1 -0
- package/dist/src/utils/settingsUtils.test.d.ts +6 -0
- package/dist/src/utils/settingsUtils.test.js +514 -0
- package/dist/src/utils/settingsUtils.test.js.map +1 -0
- package/dist/src/utils/spawnWrapper.d.ts +7 -0
- package/dist/src/utils/spawnWrapper.js +8 -0
- package/dist/src/utils/spawnWrapper.js.map +1 -0
- package/dist/src/utils/updateEventEmitter.d.ts +11 -0
- package/dist/src/utils/updateEventEmitter.js +12 -0
- package/dist/src/utils/updateEventEmitter.js.map +1 -0
- package/dist/src/utils/userStartupWarnings.test.d.ts +6 -0
- package/dist/src/utils/userStartupWarnings.test.js +67 -0
- package/dist/src/utils/userStartupWarnings.test.js.map +1 -0
- package/dist/src/utils/version.js +1 -1
- package/dist/src/utils/version.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.d.ts +7 -0
- package/dist/src/validateNonInterActiveAuth.js +37 -0
- package/dist/src/validateNonInterActiveAuth.js.map +1 -0
- package/dist/src/zed-integration/acp.d.ts +63 -0
- package/dist/src/{acp → zed-integration}/acp.js +76 -44
- package/dist/src/zed-integration/acp.js.map +1 -0
- package/dist/src/zed-integration/fileSystemService.d.ts +19 -0
- package/dist/src/zed-integration/fileSystemService.js +43 -0
- package/dist/src/zed-integration/fileSystemService.js.map +1 -0
- package/dist/src/zed-integration/schema.d.ts +11679 -0
- package/dist/src/zed-integration/schema.js +305 -0
- package/dist/src/zed-integration/schema.js.map +1 -0
- package/dist/src/zed-integration/zedIntegration.d.ts +10 -0
- package/dist/src/{acp/acpPeer.js → zed-integration/zedIntegration.js} +336 -169
- package/dist/src/zed-integration/zedIntegration.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -8
- package/dist/src/acp/acp.d.ts +0 -208
- package/dist/src/acp/acp.js.map +0 -1
- package/dist/src/acp/acpPeer.d.ts +0 -8
- package/dist/src/acp/acpPeer.js.map +0 -1
- package/dist/src/ui/utils/errorParsing.d.ts +0 -7
- package/dist/src/ui/utils/errorParsing.js +0 -90
- package/dist/src/ui/utils/errorParsing.js.map +0 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import stripAnsi from 'strip-ansi';
|
|
7
|
+
import { stripVTControlCharacters } from 'util';
|
|
7
8
|
import { spawnSync } from 'child_process';
|
|
8
9
|
import fs from 'fs';
|
|
9
10
|
import os from 'os';
|
|
@@ -12,6 +13,7 @@ import { useState, useCallback, useEffect, useMemo, useReducer } from 'react';
|
|
|
12
13
|
import stringWidth from 'string-width';
|
|
13
14
|
import { unescapePath } from '@machina.ai/cell-cli-core';
|
|
14
15
|
import { toCodePoints, cpLen, cpSlice } from '../../utils/textUtils.js';
|
|
16
|
+
import { handleVimAction } from './vim-buffer-actions.js';
|
|
15
17
|
// Simple helper for word‑wise ops.
|
|
16
18
|
function isWordChar(ch) {
|
|
17
19
|
if (ch === undefined) {
|
|
@@ -19,24 +21,397 @@ function isWordChar(ch) {
|
|
|
19
21
|
}
|
|
20
22
|
return !/[\s,.;!?]/.test(ch);
|
|
21
23
|
}
|
|
24
|
+
// Helper functions for line-based word navigation
|
|
25
|
+
export const isWordCharStrict = (char) => /[\w\p{L}\p{N}]/u.test(char); // Matches a single character that is any Unicode letter, any Unicode number, or an underscore
|
|
26
|
+
export const isWhitespace = (char) => /\s/.test(char);
|
|
27
|
+
// Check if a character is a combining mark (only diacritics for now)
|
|
28
|
+
export const isCombiningMark = (char) => /\p{M}/u.test(char);
|
|
29
|
+
// Check if a character should be considered part of a word (including combining marks)
|
|
30
|
+
export const isWordCharWithCombining = (char) => isWordCharStrict(char) || isCombiningMark(char);
|
|
31
|
+
// Get the script of a character (simplified for common scripts)
|
|
32
|
+
export const getCharScript = (char) => {
|
|
33
|
+
if (/[\p{Script=Latin}]/u.test(char))
|
|
34
|
+
return 'latin'; // All Latin script chars including diacritics
|
|
35
|
+
if (/[\p{Script=Han}]/u.test(char))
|
|
36
|
+
return 'han'; // Chinese
|
|
37
|
+
if (/[\p{Script=Arabic}]/u.test(char))
|
|
38
|
+
return 'arabic';
|
|
39
|
+
if (/[\p{Script=Hiragana}]/u.test(char))
|
|
40
|
+
return 'hiragana';
|
|
41
|
+
if (/[\p{Script=Katakana}]/u.test(char))
|
|
42
|
+
return 'katakana';
|
|
43
|
+
if (/[\p{Script=Cyrillic}]/u.test(char))
|
|
44
|
+
return 'cyrillic';
|
|
45
|
+
return 'other';
|
|
46
|
+
};
|
|
47
|
+
// Check if two characters are from different scripts (indicating word boundary)
|
|
48
|
+
export const isDifferentScript = (char1, char2) => {
|
|
49
|
+
if (!isWordCharStrict(char1) || !isWordCharStrict(char2))
|
|
50
|
+
return false;
|
|
51
|
+
return getCharScript(char1) !== getCharScript(char2);
|
|
52
|
+
};
|
|
53
|
+
// Find next word start within a line, starting from col
|
|
54
|
+
export const findNextWordStartInLine = (line, col) => {
|
|
55
|
+
const chars = toCodePoints(line);
|
|
56
|
+
let i = col;
|
|
57
|
+
if (i >= chars.length)
|
|
58
|
+
return null;
|
|
59
|
+
const currentChar = chars[i];
|
|
60
|
+
// Skip current word/sequence based on character type
|
|
61
|
+
if (isWordCharStrict(currentChar)) {
|
|
62
|
+
while (i < chars.length && isWordCharWithCombining(chars[i])) {
|
|
63
|
+
// Check for script boundary - if next character is from different script, stop here
|
|
64
|
+
if (i + 1 < chars.length &&
|
|
65
|
+
isWordCharStrict(chars[i + 1]) &&
|
|
66
|
+
isDifferentScript(chars[i], chars[i + 1])) {
|
|
67
|
+
i++; // Include current character
|
|
68
|
+
break; // Stop at script boundary
|
|
69
|
+
}
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (!isWhitespace(currentChar)) {
|
|
74
|
+
while (i < chars.length &&
|
|
75
|
+
!isWordCharStrict(chars[i]) &&
|
|
76
|
+
!isWhitespace(chars[i])) {
|
|
77
|
+
i++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Skip whitespace
|
|
81
|
+
while (i < chars.length && isWhitespace(chars[i])) {
|
|
82
|
+
i++;
|
|
83
|
+
}
|
|
84
|
+
return i < chars.length ? i : null;
|
|
85
|
+
};
|
|
86
|
+
// Find previous word start within a line
|
|
87
|
+
export const findPrevWordStartInLine = (line, col) => {
|
|
88
|
+
const chars = toCodePoints(line);
|
|
89
|
+
let i = col;
|
|
90
|
+
if (i <= 0)
|
|
91
|
+
return null;
|
|
92
|
+
i--;
|
|
93
|
+
// Skip whitespace moving backwards
|
|
94
|
+
while (i >= 0 && isWhitespace(chars[i])) {
|
|
95
|
+
i--;
|
|
96
|
+
}
|
|
97
|
+
if (i < 0)
|
|
98
|
+
return null;
|
|
99
|
+
if (isWordCharStrict(chars[i])) {
|
|
100
|
+
// We're in a word, move to its beginning
|
|
101
|
+
while (i >= 0 && isWordCharStrict(chars[i])) {
|
|
102
|
+
// Check for script boundary - if previous character is from different script, stop here
|
|
103
|
+
if (i - 1 >= 0 &&
|
|
104
|
+
isWordCharStrict(chars[i - 1]) &&
|
|
105
|
+
isDifferentScript(chars[i], chars[i - 1])) {
|
|
106
|
+
return i; // Return current position at script boundary
|
|
107
|
+
}
|
|
108
|
+
i--;
|
|
109
|
+
}
|
|
110
|
+
return i + 1;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// We're in punctuation, move to its beginning
|
|
114
|
+
while (i >= 0 && !isWordCharStrict(chars[i]) && !isWhitespace(chars[i])) {
|
|
115
|
+
i--;
|
|
116
|
+
}
|
|
117
|
+
return i + 1;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
// Find word end within a line
|
|
121
|
+
export const findWordEndInLine = (line, col) => {
|
|
122
|
+
const chars = toCodePoints(line);
|
|
123
|
+
let i = col;
|
|
124
|
+
// If we're already at the end of a word (including punctuation sequences), advance to next word
|
|
125
|
+
// This includes both regular word endings and script boundaries
|
|
126
|
+
const atEndOfWordChar = i < chars.length &&
|
|
127
|
+
isWordCharWithCombining(chars[i]) &&
|
|
128
|
+
(i + 1 >= chars.length ||
|
|
129
|
+
!isWordCharWithCombining(chars[i + 1]) ||
|
|
130
|
+
(isWordCharStrict(chars[i]) &&
|
|
131
|
+
i + 1 < chars.length &&
|
|
132
|
+
isWordCharStrict(chars[i + 1]) &&
|
|
133
|
+
isDifferentScript(chars[i], chars[i + 1])));
|
|
134
|
+
const atEndOfPunctuation = i < chars.length &&
|
|
135
|
+
!isWordCharWithCombining(chars[i]) &&
|
|
136
|
+
!isWhitespace(chars[i]) &&
|
|
137
|
+
(i + 1 >= chars.length ||
|
|
138
|
+
isWhitespace(chars[i + 1]) ||
|
|
139
|
+
isWordCharWithCombining(chars[i + 1]));
|
|
140
|
+
if (atEndOfWordChar || atEndOfPunctuation) {
|
|
141
|
+
// We're at the end of a word or punctuation sequence, move forward to find next word
|
|
142
|
+
i++;
|
|
143
|
+
// Skip whitespace to find next word or punctuation
|
|
144
|
+
while (i < chars.length && isWhitespace(chars[i])) {
|
|
145
|
+
i++;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// If we're not on a word character, find the next word or punctuation sequence
|
|
149
|
+
if (i < chars.length && !isWordCharWithCombining(chars[i])) {
|
|
150
|
+
// Skip whitespace to find next word or punctuation
|
|
151
|
+
while (i < chars.length && isWhitespace(chars[i])) {
|
|
152
|
+
i++;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Move to end of current word (including combining marks, but stop at script boundaries)
|
|
156
|
+
let foundWord = false;
|
|
157
|
+
let lastBaseCharPos = -1;
|
|
158
|
+
if (i < chars.length && isWordCharWithCombining(chars[i])) {
|
|
159
|
+
// Handle word characters
|
|
160
|
+
while (i < chars.length && isWordCharWithCombining(chars[i])) {
|
|
161
|
+
foundWord = true;
|
|
162
|
+
// Track the position of the last base character (not combining mark)
|
|
163
|
+
if (isWordCharStrict(chars[i])) {
|
|
164
|
+
lastBaseCharPos = i;
|
|
165
|
+
}
|
|
166
|
+
// Check if next character is from a different script (word boundary)
|
|
167
|
+
if (i + 1 < chars.length &&
|
|
168
|
+
isWordCharStrict(chars[i + 1]) &&
|
|
169
|
+
isDifferentScript(chars[i], chars[i + 1])) {
|
|
170
|
+
i++; // Include current character
|
|
171
|
+
if (isWordCharStrict(chars[i - 1])) {
|
|
172
|
+
lastBaseCharPos = i - 1;
|
|
173
|
+
}
|
|
174
|
+
break; // Stop at script boundary
|
|
175
|
+
}
|
|
176
|
+
i++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else if (i < chars.length && !isWhitespace(chars[i])) {
|
|
180
|
+
// Handle punctuation sequences (like ████)
|
|
181
|
+
while (i < chars.length &&
|
|
182
|
+
!isWordCharStrict(chars[i]) &&
|
|
183
|
+
!isWhitespace(chars[i])) {
|
|
184
|
+
foundWord = true;
|
|
185
|
+
lastBaseCharPos = i;
|
|
186
|
+
i++;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Only return a position if we actually found a word
|
|
190
|
+
// Return the position of the last base character, not combining marks
|
|
191
|
+
if (foundWord && lastBaseCharPos >= col) {
|
|
192
|
+
return lastBaseCharPos;
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
};
|
|
196
|
+
// Find next word across lines
|
|
197
|
+
export const findNextWordAcrossLines = (lines, cursorRow, cursorCol, searchForWordStart) => {
|
|
198
|
+
// First try current line
|
|
199
|
+
const currentLine = lines[cursorRow] || '';
|
|
200
|
+
const colInCurrentLine = searchForWordStart
|
|
201
|
+
? findNextWordStartInLine(currentLine, cursorCol)
|
|
202
|
+
: findWordEndInLine(currentLine, cursorCol);
|
|
203
|
+
if (colInCurrentLine !== null) {
|
|
204
|
+
return { row: cursorRow, col: colInCurrentLine };
|
|
205
|
+
}
|
|
206
|
+
// Search subsequent lines
|
|
207
|
+
for (let row = cursorRow + 1; row < lines.length; row++) {
|
|
208
|
+
const line = lines[row] || '';
|
|
209
|
+
const chars = toCodePoints(line);
|
|
210
|
+
// For empty lines, if we haven't found any words yet, return the empty line
|
|
211
|
+
if (chars.length === 0) {
|
|
212
|
+
// Check if there are any words in remaining lines
|
|
213
|
+
let hasWordsInLaterLines = false;
|
|
214
|
+
for (let laterRow = row + 1; laterRow < lines.length; laterRow++) {
|
|
215
|
+
const laterLine = lines[laterRow] || '';
|
|
216
|
+
const laterChars = toCodePoints(laterLine);
|
|
217
|
+
let firstNonWhitespace = 0;
|
|
218
|
+
while (firstNonWhitespace < laterChars.length &&
|
|
219
|
+
isWhitespace(laterChars[firstNonWhitespace])) {
|
|
220
|
+
firstNonWhitespace++;
|
|
221
|
+
}
|
|
222
|
+
if (firstNonWhitespace < laterChars.length) {
|
|
223
|
+
hasWordsInLaterLines = true;
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// If no words in later lines, return the empty line
|
|
228
|
+
if (!hasWordsInLaterLines) {
|
|
229
|
+
return { row, col: 0 };
|
|
230
|
+
}
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
// Find first non-whitespace
|
|
234
|
+
let firstNonWhitespace = 0;
|
|
235
|
+
while (firstNonWhitespace < chars.length &&
|
|
236
|
+
isWhitespace(chars[firstNonWhitespace])) {
|
|
237
|
+
firstNonWhitespace++;
|
|
238
|
+
}
|
|
239
|
+
if (firstNonWhitespace < chars.length) {
|
|
240
|
+
if (searchForWordStart) {
|
|
241
|
+
return { row, col: firstNonWhitespace };
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// For word end, find the end of the first word
|
|
245
|
+
const endCol = findWordEndInLine(line, firstNonWhitespace);
|
|
246
|
+
if (endCol !== null) {
|
|
247
|
+
return { row, col: endCol };
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
};
|
|
254
|
+
// Find previous word across lines
|
|
255
|
+
export const findPrevWordAcrossLines = (lines, cursorRow, cursorCol) => {
|
|
256
|
+
// First try current line
|
|
257
|
+
const currentLine = lines[cursorRow] || '';
|
|
258
|
+
const colInCurrentLine = findPrevWordStartInLine(currentLine, cursorCol);
|
|
259
|
+
if (colInCurrentLine !== null) {
|
|
260
|
+
return { row: cursorRow, col: colInCurrentLine };
|
|
261
|
+
}
|
|
262
|
+
// Search previous lines
|
|
263
|
+
for (let row = cursorRow - 1; row >= 0; row--) {
|
|
264
|
+
const line = lines[row] || '';
|
|
265
|
+
const chars = toCodePoints(line);
|
|
266
|
+
if (chars.length === 0)
|
|
267
|
+
continue;
|
|
268
|
+
// Find last word start
|
|
269
|
+
let lastWordStart = chars.length;
|
|
270
|
+
while (lastWordStart > 0 && isWhitespace(chars[lastWordStart - 1])) {
|
|
271
|
+
lastWordStart--;
|
|
272
|
+
}
|
|
273
|
+
if (lastWordStart > 0) {
|
|
274
|
+
// Find start of this word
|
|
275
|
+
const wordStart = findPrevWordStartInLine(line, lastWordStart);
|
|
276
|
+
if (wordStart !== null) {
|
|
277
|
+
return { row, col: wordStart };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
};
|
|
283
|
+
// Helper functions for vim line operations
|
|
284
|
+
export const getPositionFromOffsets = (startOffset, endOffset, lines) => {
|
|
285
|
+
let offset = 0;
|
|
286
|
+
let startRow = 0;
|
|
287
|
+
let startCol = 0;
|
|
288
|
+
let endRow = 0;
|
|
289
|
+
let endCol = 0;
|
|
290
|
+
// Find start position
|
|
291
|
+
for (let i = 0; i < lines.length; i++) {
|
|
292
|
+
const lineLength = lines[i].length + 1; // +1 for newline
|
|
293
|
+
if (offset + lineLength > startOffset) {
|
|
294
|
+
startRow = i;
|
|
295
|
+
startCol = startOffset - offset;
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
offset += lineLength;
|
|
299
|
+
}
|
|
300
|
+
// Find end position
|
|
301
|
+
offset = 0;
|
|
302
|
+
for (let i = 0; i < lines.length; i++) {
|
|
303
|
+
const lineLength = lines[i].length + (i < lines.length - 1 ? 1 : 0); // +1 for newline except last line
|
|
304
|
+
if (offset + lineLength >= endOffset) {
|
|
305
|
+
endRow = i;
|
|
306
|
+
endCol = endOffset - offset;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
offset += lineLength;
|
|
310
|
+
}
|
|
311
|
+
return { startRow, startCol, endRow, endCol };
|
|
312
|
+
};
|
|
313
|
+
export const getLineRangeOffsets = (startRow, lineCount, lines) => {
|
|
314
|
+
let startOffset = 0;
|
|
315
|
+
// Calculate start offset
|
|
316
|
+
for (let i = 0; i < startRow; i++) {
|
|
317
|
+
startOffset += lines[i].length + 1; // +1 for newline
|
|
318
|
+
}
|
|
319
|
+
// Calculate end offset
|
|
320
|
+
let endOffset = startOffset;
|
|
321
|
+
for (let i = 0; i < lineCount; i++) {
|
|
322
|
+
const lineIndex = startRow + i;
|
|
323
|
+
if (lineIndex < lines.length) {
|
|
324
|
+
endOffset += lines[lineIndex].length;
|
|
325
|
+
if (lineIndex < lines.length - 1) {
|
|
326
|
+
endOffset += 1; // +1 for newline
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return { startOffset, endOffset };
|
|
331
|
+
};
|
|
332
|
+
export const replaceRangeInternal = (state, startRow, startCol, endRow, endCol, text) => {
|
|
333
|
+
const currentLine = (row) => state.lines[row] || '';
|
|
334
|
+
const currentLineLen = (row) => cpLen(currentLine(row));
|
|
335
|
+
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
336
|
+
if (startRow > endRow ||
|
|
337
|
+
(startRow === endRow && startCol > endCol) ||
|
|
338
|
+
startRow < 0 ||
|
|
339
|
+
startCol < 0 ||
|
|
340
|
+
endRow >= state.lines.length ||
|
|
341
|
+
(endRow < state.lines.length && endCol > currentLineLen(endRow))) {
|
|
342
|
+
return state; // Invalid range
|
|
343
|
+
}
|
|
344
|
+
const newLines = [...state.lines];
|
|
345
|
+
const sCol = clamp(startCol, 0, currentLineLen(startRow));
|
|
346
|
+
const eCol = clamp(endCol, 0, currentLineLen(endRow));
|
|
347
|
+
const prefix = cpSlice(currentLine(startRow), 0, sCol);
|
|
348
|
+
const suffix = cpSlice(currentLine(endRow), eCol);
|
|
349
|
+
const normalisedReplacement = text
|
|
350
|
+
.replace(/\r\n/g, '\n')
|
|
351
|
+
.replace(/\r/g, '\n');
|
|
352
|
+
const replacementParts = normalisedReplacement.split('\n');
|
|
353
|
+
// The combined first line of the new text
|
|
354
|
+
const firstLine = prefix + replacementParts[0];
|
|
355
|
+
if (replacementParts.length === 1) {
|
|
356
|
+
// No newlines in replacement: combine prefix, replacement, and suffix on one line.
|
|
357
|
+
newLines.splice(startRow, endRow - startRow + 1, firstLine + suffix);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
// Newlines in replacement: create new lines.
|
|
361
|
+
const lastLine = replacementParts[replacementParts.length - 1] + suffix;
|
|
362
|
+
const middleLines = replacementParts.slice(1, -1);
|
|
363
|
+
newLines.splice(startRow, endRow - startRow + 1, firstLine, ...middleLines, lastLine);
|
|
364
|
+
}
|
|
365
|
+
const finalCursorRow = startRow + replacementParts.length - 1;
|
|
366
|
+
const finalCursorCol = (replacementParts.length > 1 ? 0 : sCol) +
|
|
367
|
+
cpLen(replacementParts[replacementParts.length - 1]);
|
|
368
|
+
return {
|
|
369
|
+
...state,
|
|
370
|
+
lines: newLines,
|
|
371
|
+
cursorRow: Math.min(Math.max(finalCursorRow, 0), newLines.length - 1),
|
|
372
|
+
cursorCol: Math.max(0, Math.min(finalCursorCol, cpLen(newLines[finalCursorRow] || ''))),
|
|
373
|
+
preferredCol: null,
|
|
374
|
+
};
|
|
375
|
+
};
|
|
22
376
|
/**
|
|
23
377
|
* Strip characters that can break terminal rendering.
|
|
24
378
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
379
|
+
* Uses Node.js built-in stripVTControlCharacters to handle VT sequences,
|
|
380
|
+
* then filters remaining control characters that can disrupt display.
|
|
381
|
+
*
|
|
382
|
+
* Characters stripped:
|
|
383
|
+
* - ANSI escape sequences (via strip-ansi)
|
|
384
|
+
* - VT control sequences (via Node.js util.stripVTControlCharacters)
|
|
385
|
+
* - C0 control chars (0x00-0x1F) except CR/LF which are handled elsewhere
|
|
386
|
+
* - C1 control chars (0x80-0x9F) that can cause display issues
|
|
387
|
+
*
|
|
388
|
+
* Characters preserved:
|
|
389
|
+
* - All printable Unicode including emojis
|
|
390
|
+
* - DEL (0x7F) - handled functionally by applyOperations, not a display issue
|
|
391
|
+
* - CR/LF (0x0D/0x0A) - needed for line breaks
|
|
27
392
|
*/
|
|
28
393
|
function stripUnsafeCharacters(str) {
|
|
29
|
-
const
|
|
30
|
-
|
|
394
|
+
const strippedAnsi = stripAnsi(str);
|
|
395
|
+
const strippedVT = stripVTControlCharacters(strippedAnsi);
|
|
396
|
+
return toCodePoints(strippedVT)
|
|
31
397
|
.filter((char) => {
|
|
32
|
-
if (char.length > 1)
|
|
33
|
-
return false;
|
|
34
398
|
const code = char.codePointAt(0);
|
|
35
|
-
if (code === undefined)
|
|
399
|
+
if (code === undefined)
|
|
36
400
|
return false;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
401
|
+
// Preserve CR/LF for line handling
|
|
402
|
+
if (code === 0x0a || code === 0x0d)
|
|
403
|
+
return true;
|
|
404
|
+
// Remove C0 control chars (except CR/LF) that can break display
|
|
405
|
+
// Examples: BELL(0x07) makes noise, BS(0x08) moves cursor, VT(0x0B), FF(0x0C)
|
|
406
|
+
if (code >= 0x00 && code <= 0x1f)
|
|
407
|
+
return false;
|
|
408
|
+
// Remove C1 control chars (0x80-0x9F) - legacy 8-bit control codes
|
|
409
|
+
if (code >= 0x80 && code <= 0x9f)
|
|
410
|
+
return false;
|
|
411
|
+
// Preserve DEL (0x7F) - it's handled functionally by applyOperations as backspace
|
|
412
|
+
// and doesn't cause rendering issues when displayed
|
|
413
|
+
// Preserve all other characters including Unicode/emojis
|
|
414
|
+
return true;
|
|
40
415
|
})
|
|
41
416
|
.join('');
|
|
42
417
|
}
|
|
@@ -106,6 +481,24 @@ export function offsetToLogicalPos(text, offset) {
|
|
|
106
481
|
}
|
|
107
482
|
return [row, col];
|
|
108
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* Converts logical row/col position to absolute text offset
|
|
486
|
+
* Inverse operation of offsetToLogicalPos
|
|
487
|
+
*/
|
|
488
|
+
export function logicalPosToOffset(lines, row, col) {
|
|
489
|
+
let offset = 0;
|
|
490
|
+
// Clamp row to valid range
|
|
491
|
+
const actualRow = Math.min(row, lines.length - 1);
|
|
492
|
+
// Add lengths of all lines before the target row
|
|
493
|
+
for (let i = 0; i < actualRow; i++) {
|
|
494
|
+
offset += cpLen(lines[i]) + 1; // +1 for newline
|
|
495
|
+
}
|
|
496
|
+
// Add column offset within the target row
|
|
497
|
+
if (actualRow >= 0 && actualRow < lines.length) {
|
|
498
|
+
offset += Math.min(col, cpLen(lines[actualRow]));
|
|
499
|
+
}
|
|
500
|
+
return offset;
|
|
501
|
+
}
|
|
109
502
|
// Helper to calculate visual lines and map cursor positions
|
|
110
503
|
function calculateVisualLayout(logicalLines, logicalCursor, viewportWidth) {
|
|
111
504
|
const visualLines = [];
|
|
@@ -279,26 +672,27 @@ function calculateVisualLayout(logicalLines, logicalCursor, viewportWidth) {
|
|
|
279
672
|
};
|
|
280
673
|
}
|
|
281
674
|
const historyLimit = 100;
|
|
282
|
-
export
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
cursorCol: currentState.cursorCol,
|
|
288
|
-
};
|
|
289
|
-
const newStack = [...currentState.undoStack, snapshot];
|
|
290
|
-
if (newStack.length > historyLimit) {
|
|
291
|
-
newStack.shift();
|
|
292
|
-
}
|
|
293
|
-
return { ...currentState, undoStack: newStack, redoStack: [] };
|
|
675
|
+
export const pushUndo = (currentState) => {
|
|
676
|
+
const snapshot = {
|
|
677
|
+
lines: [...currentState.lines],
|
|
678
|
+
cursorRow: currentState.cursorRow,
|
|
679
|
+
cursorCol: currentState.cursorCol,
|
|
294
680
|
};
|
|
681
|
+
const newStack = [...currentState.undoStack, snapshot];
|
|
682
|
+
if (newStack.length > historyLimit) {
|
|
683
|
+
newStack.shift();
|
|
684
|
+
}
|
|
685
|
+
return { ...currentState, undoStack: newStack, redoStack: [] };
|
|
686
|
+
};
|
|
687
|
+
export function textBufferReducer(state, action) {
|
|
688
|
+
const pushUndoLocal = pushUndo;
|
|
295
689
|
const currentLine = (r) => state.lines[r] ?? '';
|
|
296
690
|
const currentLineLen = (r) => cpLen(currentLine(r));
|
|
297
691
|
switch (action.type) {
|
|
298
692
|
case 'set_text': {
|
|
299
693
|
let nextState = state;
|
|
300
694
|
if (action.pushToUndo !== false) {
|
|
301
|
-
nextState =
|
|
695
|
+
nextState = pushUndoLocal(state);
|
|
302
696
|
}
|
|
303
697
|
const newContentLines = action.payload
|
|
304
698
|
.replace(/\r\n?/g, '\n')
|
|
@@ -314,7 +708,7 @@ export function textBufferReducer(state, action) {
|
|
|
314
708
|
};
|
|
315
709
|
}
|
|
316
710
|
case 'insert': {
|
|
317
|
-
const nextState =
|
|
711
|
+
const nextState = pushUndoLocal(state);
|
|
318
712
|
const newLines = [...nextState.lines];
|
|
319
713
|
let newCursorRow = nextState.cursorRow;
|
|
320
714
|
let newCursorCol = nextState.cursorCol;
|
|
@@ -346,7 +740,7 @@ export function textBufferReducer(state, action) {
|
|
|
346
740
|
};
|
|
347
741
|
}
|
|
348
742
|
case 'backspace': {
|
|
349
|
-
const nextState =
|
|
743
|
+
const nextState = pushUndoLocal(state);
|
|
350
744
|
const newLines = [...nextState.lines];
|
|
351
745
|
let newCursorRow = nextState.cursorRow;
|
|
352
746
|
let newCursorCol = nextState.cursorCol;
|
|
@@ -523,7 +917,7 @@ export function textBufferReducer(state, action) {
|
|
|
523
917
|
const { cursorRow, cursorCol, lines } = state;
|
|
524
918
|
const lineContent = currentLine(cursorRow);
|
|
525
919
|
if (cursorCol < currentLineLen(cursorRow)) {
|
|
526
|
-
const nextState =
|
|
920
|
+
const nextState = pushUndoLocal(state);
|
|
527
921
|
const newLines = [...nextState.lines];
|
|
528
922
|
newLines[cursorRow] =
|
|
529
923
|
cpSlice(lineContent, 0, cursorCol) +
|
|
@@ -531,7 +925,7 @@ export function textBufferReducer(state, action) {
|
|
|
531
925
|
return { ...nextState, lines: newLines, preferredCol: null };
|
|
532
926
|
}
|
|
533
927
|
else if (cursorRow < lines.length - 1) {
|
|
534
|
-
const nextState =
|
|
928
|
+
const nextState = pushUndoLocal(state);
|
|
535
929
|
const nextLineContent = currentLine(cursorRow + 1);
|
|
536
930
|
const newLines = [...nextState.lines];
|
|
537
931
|
newLines[cursorRow] = lineContent + nextLineContent;
|
|
@@ -546,7 +940,7 @@ export function textBufferReducer(state, action) {
|
|
|
546
940
|
return state;
|
|
547
941
|
if (cursorCol === 0) {
|
|
548
942
|
// Act as a backspace
|
|
549
|
-
const nextState =
|
|
943
|
+
const nextState = pushUndoLocal(state);
|
|
550
944
|
const prevLineContent = currentLine(cursorRow - 1);
|
|
551
945
|
const currentLineContentVal = currentLine(cursorRow);
|
|
552
946
|
const newCol = cpLen(prevLineContent);
|
|
@@ -561,7 +955,7 @@ export function textBufferReducer(state, action) {
|
|
|
561
955
|
preferredCol: null,
|
|
562
956
|
};
|
|
563
957
|
}
|
|
564
|
-
const nextState =
|
|
958
|
+
const nextState = pushUndoLocal(state);
|
|
565
959
|
const lineContent = currentLine(cursorRow);
|
|
566
960
|
const arr = toCodePoints(lineContent);
|
|
567
961
|
let start = cursorCol;
|
|
@@ -599,14 +993,14 @@ export function textBufferReducer(state, action) {
|
|
|
599
993
|
return state;
|
|
600
994
|
if (cursorCol >= arr.length) {
|
|
601
995
|
// Act as a delete
|
|
602
|
-
const nextState =
|
|
996
|
+
const nextState = pushUndoLocal(state);
|
|
603
997
|
const nextLineContent = currentLine(cursorRow + 1);
|
|
604
998
|
const newLines = [...nextState.lines];
|
|
605
999
|
newLines[cursorRow] = lineContent + nextLineContent;
|
|
606
1000
|
newLines.splice(cursorRow + 1, 1);
|
|
607
1001
|
return { ...nextState, lines: newLines, preferredCol: null };
|
|
608
1002
|
}
|
|
609
|
-
const nextState =
|
|
1003
|
+
const nextState = pushUndoLocal(state);
|
|
610
1004
|
let end = cursorCol;
|
|
611
1005
|
while (end < arr.length && !isWordChar(arr[end]))
|
|
612
1006
|
end++;
|
|
@@ -621,14 +1015,14 @@ export function textBufferReducer(state, action) {
|
|
|
621
1015
|
const { cursorRow, cursorCol, lines } = state;
|
|
622
1016
|
const lineContent = currentLine(cursorRow);
|
|
623
1017
|
if (cursorCol < currentLineLen(cursorRow)) {
|
|
624
|
-
const nextState =
|
|
1018
|
+
const nextState = pushUndoLocal(state);
|
|
625
1019
|
const newLines = [...nextState.lines];
|
|
626
1020
|
newLines[cursorRow] = cpSlice(lineContent, 0, cursorCol);
|
|
627
1021
|
return { ...nextState, lines: newLines };
|
|
628
1022
|
}
|
|
629
1023
|
else if (cursorRow < lines.length - 1) {
|
|
630
1024
|
// Act as a delete
|
|
631
|
-
const nextState =
|
|
1025
|
+
const nextState = pushUndoLocal(state);
|
|
632
1026
|
const nextLineContent = currentLine(cursorRow + 1);
|
|
633
1027
|
const newLines = [...nextState.lines];
|
|
634
1028
|
newLines[cursorRow] = lineContent + nextLineContent;
|
|
@@ -640,7 +1034,7 @@ export function textBufferReducer(state, action) {
|
|
|
640
1034
|
case 'kill_line_left': {
|
|
641
1035
|
const { cursorRow, cursorCol } = state;
|
|
642
1036
|
if (cursorCol > 0) {
|
|
643
|
-
const nextState =
|
|
1037
|
+
const nextState = pushUndoLocal(state);
|
|
644
1038
|
const lineContent = currentLine(cursorRow);
|
|
645
1039
|
const newLines = [...nextState.lines];
|
|
646
1040
|
newLines[cursorRow] = cpSlice(lineContent, cursorCol);
|
|
@@ -687,51 +1081,8 @@ export function textBufferReducer(state, action) {
|
|
|
687
1081
|
}
|
|
688
1082
|
case 'replace_range': {
|
|
689
1083
|
const { startRow, startCol, endRow, endCol, text } = action.payload;
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
startRow < 0 ||
|
|
693
|
-
startCol < 0 ||
|
|
694
|
-
endRow >= state.lines.length ||
|
|
695
|
-
(endRow < state.lines.length && endCol > currentLineLen(endRow))) {
|
|
696
|
-
return state; // Invalid range
|
|
697
|
-
}
|
|
698
|
-
const nextState = pushUndo(state);
|
|
699
|
-
const newLines = [...nextState.lines];
|
|
700
|
-
const sCol = clamp(startCol, 0, currentLineLen(startRow));
|
|
701
|
-
const eCol = clamp(endCol, 0, currentLineLen(endRow));
|
|
702
|
-
const prefix = cpSlice(currentLine(startRow), 0, sCol);
|
|
703
|
-
const suffix = cpSlice(currentLine(endRow), eCol);
|
|
704
|
-
const normalisedReplacement = text
|
|
705
|
-
.replace(/\r\n/g, '\n')
|
|
706
|
-
.replace(/\r/g, '\n');
|
|
707
|
-
const replacementParts = normalisedReplacement.split('\n');
|
|
708
|
-
// Replace the content
|
|
709
|
-
if (startRow === endRow) {
|
|
710
|
-
newLines[startRow] = prefix + normalisedReplacement + suffix;
|
|
711
|
-
}
|
|
712
|
-
else {
|
|
713
|
-
const firstLine = prefix + replacementParts[0];
|
|
714
|
-
if (replacementParts.length === 1) {
|
|
715
|
-
// Single line of replacement text, but spanning multiple original lines
|
|
716
|
-
newLines.splice(startRow, endRow - startRow + 1, firstLine + suffix);
|
|
717
|
-
}
|
|
718
|
-
else {
|
|
719
|
-
// Multi-line replacement text
|
|
720
|
-
const lastLine = replacementParts[replacementParts.length - 1] + suffix;
|
|
721
|
-
const middleLines = replacementParts.slice(1, -1);
|
|
722
|
-
newLines.splice(startRow, endRow - startRow + 1, firstLine, ...middleLines, lastLine);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
const finalCursorRow = startRow + replacementParts.length - 1;
|
|
726
|
-
const finalCursorCol = (replacementParts.length > 1 ? 0 : sCol) +
|
|
727
|
-
cpLen(replacementParts[replacementParts.length - 1]);
|
|
728
|
-
return {
|
|
729
|
-
...nextState,
|
|
730
|
-
lines: newLines,
|
|
731
|
-
cursorRow: finalCursorRow,
|
|
732
|
-
cursorCol: finalCursorCol,
|
|
733
|
-
preferredCol: null,
|
|
734
|
-
};
|
|
1084
|
+
const nextState = pushUndoLocal(state);
|
|
1085
|
+
return replaceRangeInternal(nextState, startRow, startCol, endRow, endCol, text);
|
|
735
1086
|
}
|
|
736
1087
|
case 'move_to_offset': {
|
|
737
1088
|
const { offset } = action.payload;
|
|
@@ -744,8 +1095,42 @@ export function textBufferReducer(state, action) {
|
|
|
744
1095
|
};
|
|
745
1096
|
}
|
|
746
1097
|
case 'create_undo_snapshot': {
|
|
747
|
-
return
|
|
1098
|
+
return pushUndoLocal(state);
|
|
748
1099
|
}
|
|
1100
|
+
// Vim-specific operations
|
|
1101
|
+
case 'vim_delete_word_forward':
|
|
1102
|
+
case 'vim_delete_word_backward':
|
|
1103
|
+
case 'vim_delete_word_end':
|
|
1104
|
+
case 'vim_change_word_forward':
|
|
1105
|
+
case 'vim_change_word_backward':
|
|
1106
|
+
case 'vim_change_word_end':
|
|
1107
|
+
case 'vim_delete_line':
|
|
1108
|
+
case 'vim_change_line':
|
|
1109
|
+
case 'vim_delete_to_end_of_line':
|
|
1110
|
+
case 'vim_change_to_end_of_line':
|
|
1111
|
+
case 'vim_change_movement':
|
|
1112
|
+
case 'vim_move_left':
|
|
1113
|
+
case 'vim_move_right':
|
|
1114
|
+
case 'vim_move_up':
|
|
1115
|
+
case 'vim_move_down':
|
|
1116
|
+
case 'vim_move_word_forward':
|
|
1117
|
+
case 'vim_move_word_backward':
|
|
1118
|
+
case 'vim_move_word_end':
|
|
1119
|
+
case 'vim_delete_char':
|
|
1120
|
+
case 'vim_insert_at_cursor':
|
|
1121
|
+
case 'vim_append_at_cursor':
|
|
1122
|
+
case 'vim_open_line_below':
|
|
1123
|
+
case 'vim_open_line_above':
|
|
1124
|
+
case 'vim_append_at_line_end':
|
|
1125
|
+
case 'vim_insert_at_line_start':
|
|
1126
|
+
case 'vim_move_to_line_start':
|
|
1127
|
+
case 'vim_move_to_line_end':
|
|
1128
|
+
case 'vim_move_to_first_nonwhitespace':
|
|
1129
|
+
case 'vim_move_to_first_line':
|
|
1130
|
+
case 'vim_move_to_last_line':
|
|
1131
|
+
case 'vim_move_to_line':
|
|
1132
|
+
case 'vim_escape_insert_mode':
|
|
1133
|
+
return handleVimAction(state, action);
|
|
749
1134
|
default: {
|
|
750
1135
|
const exhaustiveCheck = action;
|
|
751
1136
|
console.error(`Unknown action encountered: ${exhaustiveCheck}`);
|
|
@@ -798,22 +1183,23 @@ export function useTextBuffer({ initialText = '', initialCursorOffset = 0, viewp
|
|
|
798
1183
|
setVisualScrollRow(newVisualScrollRow);
|
|
799
1184
|
}
|
|
800
1185
|
}, [visualCursor, visualScrollRow, viewport]);
|
|
801
|
-
const insert = useCallback((ch) => {
|
|
1186
|
+
const insert = useCallback((ch, { paste = false } = {}) => {
|
|
802
1187
|
if (/[\n\r]/.test(ch)) {
|
|
803
1188
|
dispatch({ type: 'insert', payload: ch });
|
|
804
1189
|
return;
|
|
805
1190
|
}
|
|
806
1191
|
const minLengthToInferAsDragDrop = 3;
|
|
807
|
-
if (ch.length >= minLengthToInferAsDragDrop &&
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
1192
|
+
if (ch.length >= minLengthToInferAsDragDrop &&
|
|
1193
|
+
!shellModeActive &&
|
|
1194
|
+
paste) {
|
|
1195
|
+
let potentialPath = ch.trim();
|
|
1196
|
+
const quoteMatch = potentialPath.match(/^'(.*)'$/);
|
|
1197
|
+
if (quoteMatch) {
|
|
1198
|
+
potentialPath = quoteMatch[1];
|
|
813
1199
|
}
|
|
814
1200
|
potentialPath = potentialPath.trim();
|
|
815
1201
|
if (isValidPath(unescapePath(potentialPath))) {
|
|
816
|
-
ch = `@${potentialPath}`;
|
|
1202
|
+
ch = `@${potentialPath} `;
|
|
817
1203
|
}
|
|
818
1204
|
}
|
|
819
1205
|
let currentText = '';
|
|
@@ -866,6 +1252,104 @@ export function useTextBuffer({ initialText = '', initialCursorOffset = 0, viewp
|
|
|
866
1252
|
const killLineLeft = useCallback(() => {
|
|
867
1253
|
dispatch({ type: 'kill_line_left' });
|
|
868
1254
|
}, []);
|
|
1255
|
+
// Vim-specific operations
|
|
1256
|
+
const vimDeleteWordForward = useCallback((count) => {
|
|
1257
|
+
dispatch({ type: 'vim_delete_word_forward', payload: { count } });
|
|
1258
|
+
}, []);
|
|
1259
|
+
const vimDeleteWordBackward = useCallback((count) => {
|
|
1260
|
+
dispatch({ type: 'vim_delete_word_backward', payload: { count } });
|
|
1261
|
+
}, []);
|
|
1262
|
+
const vimDeleteWordEnd = useCallback((count) => {
|
|
1263
|
+
dispatch({ type: 'vim_delete_word_end', payload: { count } });
|
|
1264
|
+
}, []);
|
|
1265
|
+
const vimChangeWordForward = useCallback((count) => {
|
|
1266
|
+
dispatch({ type: 'vim_change_word_forward', payload: { count } });
|
|
1267
|
+
}, []);
|
|
1268
|
+
const vimChangeWordBackward = useCallback((count) => {
|
|
1269
|
+
dispatch({ type: 'vim_change_word_backward', payload: { count } });
|
|
1270
|
+
}, []);
|
|
1271
|
+
const vimChangeWordEnd = useCallback((count) => {
|
|
1272
|
+
dispatch({ type: 'vim_change_word_end', payload: { count } });
|
|
1273
|
+
}, []);
|
|
1274
|
+
const vimDeleteLine = useCallback((count) => {
|
|
1275
|
+
dispatch({ type: 'vim_delete_line', payload: { count } });
|
|
1276
|
+
}, []);
|
|
1277
|
+
const vimChangeLine = useCallback((count) => {
|
|
1278
|
+
dispatch({ type: 'vim_change_line', payload: { count } });
|
|
1279
|
+
}, []);
|
|
1280
|
+
const vimDeleteToEndOfLine = useCallback(() => {
|
|
1281
|
+
dispatch({ type: 'vim_delete_to_end_of_line' });
|
|
1282
|
+
}, []);
|
|
1283
|
+
const vimChangeToEndOfLine = useCallback(() => {
|
|
1284
|
+
dispatch({ type: 'vim_change_to_end_of_line' });
|
|
1285
|
+
}, []);
|
|
1286
|
+
const vimChangeMovement = useCallback((movement, count) => {
|
|
1287
|
+
dispatch({ type: 'vim_change_movement', payload: { movement, count } });
|
|
1288
|
+
}, []);
|
|
1289
|
+
// New vim navigation and operation methods
|
|
1290
|
+
const vimMoveLeft = useCallback((count) => {
|
|
1291
|
+
dispatch({ type: 'vim_move_left', payload: { count } });
|
|
1292
|
+
}, []);
|
|
1293
|
+
const vimMoveRight = useCallback((count) => {
|
|
1294
|
+
dispatch({ type: 'vim_move_right', payload: { count } });
|
|
1295
|
+
}, []);
|
|
1296
|
+
const vimMoveUp = useCallback((count) => {
|
|
1297
|
+
dispatch({ type: 'vim_move_up', payload: { count } });
|
|
1298
|
+
}, []);
|
|
1299
|
+
const vimMoveDown = useCallback((count) => {
|
|
1300
|
+
dispatch({ type: 'vim_move_down', payload: { count } });
|
|
1301
|
+
}, []);
|
|
1302
|
+
const vimMoveWordForward = useCallback((count) => {
|
|
1303
|
+
dispatch({ type: 'vim_move_word_forward', payload: { count } });
|
|
1304
|
+
}, []);
|
|
1305
|
+
const vimMoveWordBackward = useCallback((count) => {
|
|
1306
|
+
dispatch({ type: 'vim_move_word_backward', payload: { count } });
|
|
1307
|
+
}, []);
|
|
1308
|
+
const vimMoveWordEnd = useCallback((count) => {
|
|
1309
|
+
dispatch({ type: 'vim_move_word_end', payload: { count } });
|
|
1310
|
+
}, []);
|
|
1311
|
+
const vimDeleteChar = useCallback((count) => {
|
|
1312
|
+
dispatch({ type: 'vim_delete_char', payload: { count } });
|
|
1313
|
+
}, []);
|
|
1314
|
+
const vimInsertAtCursor = useCallback(() => {
|
|
1315
|
+
dispatch({ type: 'vim_insert_at_cursor' });
|
|
1316
|
+
}, []);
|
|
1317
|
+
const vimAppendAtCursor = useCallback(() => {
|
|
1318
|
+
dispatch({ type: 'vim_append_at_cursor' });
|
|
1319
|
+
}, []);
|
|
1320
|
+
const vimOpenLineBelow = useCallback(() => {
|
|
1321
|
+
dispatch({ type: 'vim_open_line_below' });
|
|
1322
|
+
}, []);
|
|
1323
|
+
const vimOpenLineAbove = useCallback(() => {
|
|
1324
|
+
dispatch({ type: 'vim_open_line_above' });
|
|
1325
|
+
}, []);
|
|
1326
|
+
const vimAppendAtLineEnd = useCallback(() => {
|
|
1327
|
+
dispatch({ type: 'vim_append_at_line_end' });
|
|
1328
|
+
}, []);
|
|
1329
|
+
const vimInsertAtLineStart = useCallback(() => {
|
|
1330
|
+
dispatch({ type: 'vim_insert_at_line_start' });
|
|
1331
|
+
}, []);
|
|
1332
|
+
const vimMoveToLineStart = useCallback(() => {
|
|
1333
|
+
dispatch({ type: 'vim_move_to_line_start' });
|
|
1334
|
+
}, []);
|
|
1335
|
+
const vimMoveToLineEnd = useCallback(() => {
|
|
1336
|
+
dispatch({ type: 'vim_move_to_line_end' });
|
|
1337
|
+
}, []);
|
|
1338
|
+
const vimMoveToFirstNonWhitespace = useCallback(() => {
|
|
1339
|
+
dispatch({ type: 'vim_move_to_first_nonwhitespace' });
|
|
1340
|
+
}, []);
|
|
1341
|
+
const vimMoveToFirstLine = useCallback(() => {
|
|
1342
|
+
dispatch({ type: 'vim_move_to_first_line' });
|
|
1343
|
+
}, []);
|
|
1344
|
+
const vimMoveToLastLine = useCallback(() => {
|
|
1345
|
+
dispatch({ type: 'vim_move_to_last_line' });
|
|
1346
|
+
}, []);
|
|
1347
|
+
const vimMoveToLine = useCallback((lineNumber) => {
|
|
1348
|
+
dispatch({ type: 'vim_move_to_line', payload: { lineNumber } });
|
|
1349
|
+
}, []);
|
|
1350
|
+
const vimEscapeInsertMode = useCallback(() => {
|
|
1351
|
+
dispatch({ type: 'vim_escape_insert_mode' });
|
|
1352
|
+
}, []);
|
|
869
1353
|
const openInExternalEditor = useCallback(async (opts = {}) => {
|
|
870
1354
|
const editor = opts.editor ??
|
|
871
1355
|
process.env['VISUAL'] ??
|
|
@@ -911,6 +1395,12 @@ export function useTextBuffer({ initialText = '', initialCursorOffset = 0, viewp
|
|
|
911
1395
|
}, [text, stdin, setRawMode]);
|
|
912
1396
|
const handleInput = useCallback((key) => {
|
|
913
1397
|
const { sequence: input } = key;
|
|
1398
|
+
if (key.paste) {
|
|
1399
|
+
// Do not do any other processing on pastes so ensure we handle them
|
|
1400
|
+
// before all other cases.
|
|
1401
|
+
insert(input, { paste: key.paste });
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
914
1404
|
if (key.name === 'return' ||
|
|
915
1405
|
input === '\r' ||
|
|
916
1406
|
input === '\n' ||
|
|
@@ -959,7 +1449,7 @@ export function useTextBuffer({ initialText = '', initialCursorOffset = 0, viewp
|
|
|
959
1449
|
else if (key.name === 'delete' || (key.ctrl && key.name === 'd'))
|
|
960
1450
|
del();
|
|
961
1451
|
else if (input && !key.ctrl && !key.meta) {
|
|
962
|
-
insert(input);
|
|
1452
|
+
insert(input, { paste: key.paste });
|
|
963
1453
|
}
|
|
964
1454
|
}, [newline, move, deleteWordLeft, deleteWordRight, backspace, del, insert]);
|
|
965
1455
|
const renderedVisualLines = useMemo(() => visualLines.slice(visualScrollRow, visualScrollRow + viewport.height), [visualLines, visualScrollRow, viewport.height]);
|
|
@@ -1004,6 +1494,39 @@ export function useTextBuffer({ initialText = '', initialCursorOffset = 0, viewp
|
|
|
1004
1494
|
killLineLeft,
|
|
1005
1495
|
handleInput,
|
|
1006
1496
|
openInExternalEditor,
|
|
1497
|
+
// Vim-specific operations
|
|
1498
|
+
vimDeleteWordForward,
|
|
1499
|
+
vimDeleteWordBackward,
|
|
1500
|
+
vimDeleteWordEnd,
|
|
1501
|
+
vimChangeWordForward,
|
|
1502
|
+
vimChangeWordBackward,
|
|
1503
|
+
vimChangeWordEnd,
|
|
1504
|
+
vimDeleteLine,
|
|
1505
|
+
vimChangeLine,
|
|
1506
|
+
vimDeleteToEndOfLine,
|
|
1507
|
+
vimChangeToEndOfLine,
|
|
1508
|
+
vimChangeMovement,
|
|
1509
|
+
vimMoveLeft,
|
|
1510
|
+
vimMoveRight,
|
|
1511
|
+
vimMoveUp,
|
|
1512
|
+
vimMoveDown,
|
|
1513
|
+
vimMoveWordForward,
|
|
1514
|
+
vimMoveWordBackward,
|
|
1515
|
+
vimMoveWordEnd,
|
|
1516
|
+
vimDeleteChar,
|
|
1517
|
+
vimInsertAtCursor,
|
|
1518
|
+
vimAppendAtCursor,
|
|
1519
|
+
vimOpenLineBelow,
|
|
1520
|
+
vimOpenLineAbove,
|
|
1521
|
+
vimAppendAtLineEnd,
|
|
1522
|
+
vimInsertAtLineStart,
|
|
1523
|
+
vimMoveToLineStart,
|
|
1524
|
+
vimMoveToLineEnd,
|
|
1525
|
+
vimMoveToFirstNonWhitespace,
|
|
1526
|
+
vimMoveToFirstLine,
|
|
1527
|
+
vimMoveToLastLine,
|
|
1528
|
+
vimMoveToLine,
|
|
1529
|
+
vimEscapeInsertMode,
|
|
1007
1530
|
};
|
|
1008
1531
|
return returnValue;
|
|
1009
1532
|
}
|