diff --git a/src/renderer/src/components/settings/TerminalAdvancedSection.test.tsx b/src/renderer/src/components/settings/TerminalAdvancedSection.test.tsx index f06fe63775a..facfa0e8e7f 100644 --- a/src/renderer/src/components/settings/TerminalAdvancedSection.test.tsx +++ b/src/renderer/src/components/settings/TerminalAdvancedSection.test.tsx @@ -3,14 +3,16 @@ import { act } from 'react' import { createRoot, type Root } from 'react-dom/client' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { getDefaultSettings } from '../../../../shared/constants' import type { GlobalSettings } from '../../../../shared/global-settings-types' +import { TERMINAL_DEFAULT_WORD_SEPARATOR } from '../../../../shared/terminal-word-separator' import { TerminalAdvancedSection } from './TerminalAdvancedSection' vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, defaultValue: string) => defaultValue })) -describe('TerminalAdvancedSection scrollback rows', () => { +describe('TerminalAdvancedSection', () => { let container: HTMLDivElement let root: Root @@ -26,11 +28,11 @@ describe('TerminalAdvancedSection scrollback rows', () => { document.body.replaceChildren() }) - function renderSection(updateSettings = vi.fn()): void { + function renderSection(updateSettings = vi.fn(), overrides: Partial = {}): void { act(() => { root.render( { expect(updateSettings).toHaveBeenCalledWith({ terminalScrollbackRows: 12345 }) expect(input.value).toBe('12345') }) + + it('shows the no-space hint for a custom separator and resets to the default', () => { + const updateSettings = vi.fn() + renderSection(updateSettings, { terminalWordSeparator: '()[]' }) + + const input = container.querySelector('input:not([type])') + expect(input?.value).toBe('()[]') + expect(container.textContent).toContain('No space included') + + const reset = [...container.querySelectorAll('button')].find((b) => b.textContent === 'Reset') + act(() => reset?.click()) + + expect(updateSettings).toHaveBeenCalledWith({ terminalWordSeparator: undefined }) + expect(input?.value).toBe(TERMINAL_DEFAULT_WORD_SEPARATOR) + expect(container.textContent).not.toContain('No space included') + expect([...container.querySelectorAll('button')].some((b) => b.textContent === 'Reset')).toBe( + false + ) + }) }) diff --git a/src/renderer/src/components/settings/TerminalAdvancedSection.tsx b/src/renderer/src/components/settings/TerminalAdvancedSection.tsx index bedfe467639..620a8865a49 100644 --- a/src/renderer/src/components/settings/TerminalAdvancedSection.tsx +++ b/src/renderer/src/components/settings/TerminalAdvancedSection.tsx @@ -6,6 +6,7 @@ import { DESKTOP_TERMINAL_SCROLLBACK_ROWS_MIN, normalizeDesktopTerminalScrollbackRows } from '../../../../shared/terminal-scrollback-policy' +import { Button } from '../ui/button' import { Input } from '../ui/input' import { ToggleGroup, ToggleGroupItem } from '../ui/toggle-group' import { @@ -35,6 +36,10 @@ function formatScrollbackRowsLabel(rows: number): string { return rows % 1_000 === 0 ? `${rows / 1_000}k` : String(rows) } +function toWordSeparatorSetting(draft: string): string | undefined { + return draft && draft !== TERMINAL_DEFAULT_WORD_SEPARATOR ? draft : undefined +} + export function TerminalAdvancedSection({ settings, updateSettings, @@ -58,6 +63,22 @@ export function TerminalAdvancedSection({ ) const scrollbackToggleValue = scrollbackMode === 'custom' ? 'custom' : isPreset ? `${scrollbackRows}` : 'custom' + const wordSeparator = settings.terminalWordSeparator + const [wordSeparatorDraft, setWordSeparatorDraft] = useState( + wordSeparator ?? TERMINAL_DEFAULT_WORD_SEPARATOR + ) + const [prevWordSeparator, setPrevWordSeparator] = useState(wordSeparator) + if (wordSeparator !== prevWordSeparator) { + setPrevWordSeparator(wordSeparator) + // Why: an emptied field stays empty while editing instead of snapping back to the default. + if (wordSeparator !== toWordSeparatorSetting(wordSeparatorDraft)) { + setWordSeparatorDraft(wordSeparator ?? TERMINAL_DEFAULT_WORD_SEPARATOR) + } + } + const commitWordSeparatorDraft = (draft: string): void => { + setWordSeparatorDraft(draft) + updateSettings({ terminalWordSeparator: toWordSeparatorSetting(draft) }) + } const powerShellImplementation = settings.terminalWindowsPowerShellImplementation ?? 'auto' const commitScrollbackRowsDraft = (): void => { const trimmed = scrollbackRowsDraft.trim() @@ -176,27 +197,47 @@ export function TerminalAdvancedSection({ { - const value = e.target.value - updateSettings({ terminalWordSeparator: value || undefined }) - }} - placeholder={TERMINAL_DEFAULT_WORD_SEPARATOR} - className="w-56 font-mono text-xs" - /> +
+
+ commitWordSeparatorDraft(e.target.value)} + variant="code" + spellCheck={false} + className="min-w-0 flex-1" + /> + {wordSeparatorDraft !== TERMINAL_DEFAULT_WORD_SEPARATOR ? ( + + ) : null} +
+ {wordSeparatorDraft && !wordSeparatorDraft.includes(' ') ? ( +

+ {translate( + 'settings.terminal.wordSeparators.noSpaceHint', + 'No space included — double-click will select across spaces.' + )} +

+ ) : null} +
} />
diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 1579037d638..15891367352 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -363,6 +363,10 @@ "openManageSessions": "Open Manage Sessions", "administratorSearchDescription": "See Orca’s Windows permissions or restart with administrator approval.", "administratorApproval": "Windows will ask for approval. Use your usual account." + }, + "wordSeparators": { + "description": "Characters treated as word boundaries for double-click selection, including space.", + "noSpaceHint": "No space included — double-click will select across spaces." } }, "appearance": { @@ -8592,7 +8596,6 @@ "a016ffbeed": "Auto uses Windows PowerShell now and switches to PowerShell 7+ when installed.", "5ed5c95344": "Choose between Windows PowerShell and PowerShell 7+ for new terminal panes.", "3d88af864d": "Choose whether the PowerShell shell option launches Windows PowerShell or PowerShell 7+ for new terminal panes.", - "8a956cc91e": "Characters treated as word boundaries for double-click selection.", "4bebcc2b2c": "Word Separators", "12e06178fa": "rows", "907b0b9d3e": "Custom", diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 3008a57f3c0..c979cafd422 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -8220,7 +8220,6 @@ "a016ffbeed": "Auto usa Windows PowerShell ahora y cambia a PowerShell 7+ cuando está instalado.", "5ed5c95344": "Elige entre Windows PowerShell y PowerShell 7+ para nuevos paneles de terminal.", "3d88af864d": "Elige si la opción de shell PowerShell inicia Windows PowerShell o PowerShell 7+ para nuevos paneles de terminal.", - "8a956cc91e": "Caracteres tratados como límites de palabras para la selección con doble clic.", "4bebcc2b2c": "Separadores de palabras", "12e06178fa": "filas", "907b0b9d3e": "Personalizado", diff --git a/src/renderer/src/i18n/locales/fr.json b/src/renderer/src/i18n/locales/fr.json index ee8f539dbbc..c07b4add695 100644 --- a/src/renderer/src/i18n/locales/fr.json +++ b/src/renderer/src/i18n/locales/fr.json @@ -8439,7 +8439,6 @@ "a016ffbeed": "Auto utilise Windows PowerShell pour le moment et bascule vers PowerShell 7+ une fois installé.", "5ed5c95344": "Choisissez entre Windows PowerShell et PowerShell 7+ pour les nouveaux volets de terminal.", "3d88af864d": "Choisissez si l'option de shell PowerShell lance Windows PowerShell ou PowerShell 7+ pour les nouveaux volets de terminal.", - "8a956cc91e": "Caractères traités comme séparateurs de mots pour la sélection par double-clic.", "4bebcc2b2c": "Séparateurs de mots", "12e06178fa": "lignes", "907b0b9d3e": "Personnalisé", diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 9854b50f3e6..463f9844972 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -8226,7 +8226,6 @@ "a016ffbeed": "Auto は現在 Windows PowerShell を使用し、インストールされると PowerShell 7 以降に切り替わります。", "5ed5c95344": "新規ターミナルペインについては、Windows PowerShell と PowerShell 7+ のどちらかを選択します。", "3d88af864d": "PowerShell シェルオプションで、新規ターミナルペインに対して Windows PowerShell を起動するか PowerShell 7+ を起動するかを選択します。", - "8a956cc91e": "文字はダブルクリック選択の単語境界として扱われます。", "4bebcc2b2c": "単語の区切り文字", "12e06178fa": "行", "907b0b9d3e": "カスタム", diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index 0f9d1138edf..8f09de280af 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -8189,7 +8189,6 @@ "a016ffbeed": "자동은 현재 Windows PowerShell을 사용하고, PowerShell 7+가 설치되면 전환합니다.", "5ed5c95344": "새 터미널 패널을 위해 Windows PowerShell과 PowerShell 7+ 중에서 선택하세요.", "3d88af864d": "PowerShell 셸 옵션이 새 터미널 패널에 대해 Windows PowerShell을 시작할지 아니면 PowerShell 7+를 시작할지 선택합니다.", - "8a956cc91e": "두 번 클릭 선택 시 단어 경계로 처리되는 문자입니다.", "4bebcc2b2c": "단어 구분 기호", "12e06178fa": "행", "907b0b9d3e": "사용자 지정", diff --git a/src/renderer/src/i18n/locales/pt.json b/src/renderer/src/i18n/locales/pt.json index 7d9256c7566..3e4f23407d3 100644 --- a/src/renderer/src/i18n/locales/pt.json +++ b/src/renderer/src/i18n/locales/pt.json @@ -4023,7 +4023,6 @@ "a016ffbeed": "Auto usa o Windows PowerShell agora e alterna para o PowerShell 7+ quando instalado.", "5ed5c95344": "Escolha entre Windows PowerShell e PowerShell 7+ para novos painéis de terminal.", "3d88af864d": "Escolha se a opção de shell PowerShell inicia o Windows PowerShell ou o PowerShell 7+ para novos painéis de terminal.", - "8a956cc91e": "Caracteres tratados como limites de palavra para seleção por clique duplo.", "4bebcc2b2c": "Separadores de Palavra", "12e06178fa": "linhas", "907b0b9d3e": "Personalizado", diff --git a/src/renderer/src/i18n/locales/ru.json b/src/renderer/src/i18n/locales/ru.json index 8f02fa15782..3b734a00ad6 100644 --- a/src/renderer/src/i18n/locales/ru.json +++ b/src/renderer/src/i18n/locales/ru.json @@ -8616,7 +8616,6 @@ "a016ffbeed": "Сейчас «Авто» использует Windows PowerShell и переключится на PowerShell 7+ после установки.", "5ed5c95344": "Выберите Windows PowerShell или PowerShell 7+ для новых панелей терминала.", "3d88af864d": "Выберите, какую оболочку запускает пункт PowerShell для новых панелей терминала: Windows PowerShell или PowerShell 7+.", - "8a956cc91e": "Символы границ слов для выделения двойным щелчком.", "4bebcc2b2c": "Разделители слов", "12e06178fa": "строк", "907b0b9d3e": "Пользовательские", diff --git a/src/renderer/src/i18n/locales/tr.json b/src/renderer/src/i18n/locales/tr.json index e7f2c1b6009..3c60b2c093e 100644 --- a/src/renderer/src/i18n/locales/tr.json +++ b/src/renderer/src/i18n/locales/tr.json @@ -8556,7 +8556,6 @@ "a016ffbeed": "Otomatik, şu anda Windows PowerShell'i kullanır ve kurulduğunda PowerShell 7+'a geçer.", "5ed5c95344": "Yeni terminal bölmeleri için Windows PowerShell ve PowerShell 7+ arasında seçim yapın.", "3d88af864d": "PowerShell kabuk seçeneğinin yeni terminal bölmeleri için Windows PowerShell mi yoksa PowerShell 7+ mı başlatacağını seçin.", - "8a956cc91e": "Çift tıklama seçiminde kelime sınırı olarak kabul edilen karakterler.", "4bebcc2b2c": "Kelime Ayırıcıları", "12e06178fa": "satır", "907b0b9d3e": "Özel", diff --git a/src/renderer/src/i18n/locales/zh-Hant.json b/src/renderer/src/i18n/locales/zh-Hant.json index 91486e23e57..be575242554 100644 --- a/src/renderer/src/i18n/locales/zh-Hant.json +++ b/src/renderer/src/i18n/locales/zh-Hant.json @@ -8545,7 +8545,6 @@ "a016ffbeed": "「自動」模式目前使用 Windows PowerShell,並在安裝後切換到 PowerShell 7+。", "5ed5c95344": "為新的終端機窗格選擇 Windows PowerShell 或 PowerShell 7+。", "3d88af864d": "使用 PowerShell shell 選項開啟新的終端機窗格時,選擇要啟動 Windows PowerShell 還是 PowerShell 7+。", - "8a956cc91e": "按兩下選取時視為字詞邊界的字元。", "4bebcc2b2c": "字詞分隔字元", "12e06178fa": "列", "907b0b9d3e": "自訂", diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index 90105605224..8b6d48c9e73 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -8189,7 +8189,6 @@ "a016ffbeed": "Auto 现在使用 Windows PowerShell,并在安装后切换到 PowerShell 7+。", "5ed5c95344": "为新的终端窗格选择 Windows PowerShell 和 PowerShell 7+。", "3d88af864d": "选择 PowerShell shell 选项是为新终端窗格启动 Windows PowerShell 还是 PowerShell 7+。", - "8a956cc91e": "双击选择时将字符视为单词边界。", "4bebcc2b2c": "单词分隔符", "12e06178fa": "行", "907b0b9d3e": "自定义",