feat: add code block line wrap toggle

Adds a chat code block wrap toggle in markdown code block headers
Persists and restores the setting across desktop/web settings
Adds localized labels and OpenChamber search entry for the new option
This commit is contained in:
Bohdan Triapitsyn
2026-07-08 14:46:44 +03:00
parent 859b4529da
commit 8b7448bcf0
30 changed files with 166 additions and 9 deletions
+1
View File
@@ -645,6 +645,7 @@ export interface SettingsPayload {
showOpenCodeUpdateNotifications?: boolean;
openCodeUpdateToastDismissedVersion?: string;
showToolFileIcons?: boolean;
codeBlockLineWrap?: boolean;
showTurnChangedFiles?: boolean;
showExpandedBashTools?: boolean;
showExpandedEditTools?: boolean;
+1
View File
@@ -136,6 +136,7 @@ export type DesktopSettings = {
showOpenCodeUpdateNotifications?: boolean;
openCodeUpdateToastDismissedVersion?: string;
showToolFileIcons?: boolean;
codeBlockLineWrap?: boolean;
showTurnChangedFiles?: boolean;
showExpandedBashTools?: boolean;
showExpandedEditTools?: boolean;
@@ -1737,6 +1737,8 @@ export const settingsDict = {
'settings.openchamber.visual.field.expandedEditorToolbar': 'Always show editor toolbar (docked under the file tabs)',
'settings.openchamber.visual.field.wideChatLayoutAria': 'Wide chat layout',
'settings.openchamber.visual.field.wideChatLayout': 'Wide Chat Layout',
'settings.openchamber.visual.field.codeBlockLineWrapAria': 'Wrap code block lines',
'settings.openchamber.visual.field.codeBlockLineWrap': 'Wrap Code Block Lines',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsAria': 'Inline assistant actions',
'settings.openchamber.visual.field.showSplitAssistantMessageActions': 'Inline Assistant Actions',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': 'Show Copy Answer, Save as image, and Read aloud on assistant text blocks that appear before later tool calls in the same response.',
+2
View File
@@ -2670,6 +2670,8 @@ export const dict = {
'sortableTabsStrip.aria.tabs': 'Tabs',
'openChamberLogo.aria.logo': 'OpenChamber logo',
'markdownRenderer.table.actions.copyTitle': 'Copy table',
'markdownRenderer.code.actions.enableWrapTitle': 'Enable line wrap',
'markdownRenderer.code.actions.disableWrapTitle': 'Disable line wrap',
'markdownRenderer.table.actions.downloadTitle': 'Download table',
'markdownRenderer.table.toast.downloadedAsFormat': 'Table downloaded as {format}',
'markdownRenderer.mermaid.actions.copyTitle': 'Copy',
@@ -1708,6 +1708,8 @@ export const settingsDict = {
"settings.openchamber.visual.field.showSplitAssistantMessageActions": "Acciones en línea del asistente",
"settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip": "Muestra Copiar respuesta, Guardar como imagen y Leer en voz alta en bloques de texto del asistente que aparecen antes de llamadas a herramientas posteriores dentro de la misma respuesta.",
"settings.openchamber.visual.field.showToolFileIconsAria": "Mostrar iconos de archivos de herramientas",
"settings.openchamber.visual.field.codeBlockLineWrapAria": "Ajustar líneas de bloques de código",
"settings.openchamber.visual.field.codeBlockLineWrap": "Ajustar líneas de bloques de código",
"settings.openchamber.visual.field.showToolFileIcons": "Mostrar iconos de archivos de herramientas",
"settings.openchamber.visual.field.showTurnChangedFilesAria": "Mostrar archivos cambiados en turnos completados",
"settings.openchamber.visual.field.showTurnChangedFiles": "Mostrar archivos cambiados en turnos completados",
+2
View File
@@ -2636,6 +2636,8 @@ export const dict: Record<I18nKey, string> = {
"sortableTabsStrip.aria.tabs": "Pestañas",
"openChamberLogo.aria.logo": "Logo de OpenChamber",
"markdownRenderer.table.actions.copyTitle": "Copiar tabla",
"markdownRenderer.code.actions.enableWrapTitle": "Activar ajuste de línea",
"markdownRenderer.code.actions.disableWrapTitle": "Desactivar ajuste de línea",
"markdownRenderer.table.actions.downloadTitle": "Descargar tabla",
"markdownRenderer.table.toast.downloadedAsFormat": "Tabla descargada como {format}",
"markdownRenderer.mermaid.actions.copyTitle": "Copiar",
@@ -1644,6 +1644,8 @@ export const settingsDict = {
'settings.openchamber.visual.field.showSplitAssistantMessageActions': 'Actions intégrées de l\'assistant',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': 'Afficher Copier la réponse, Enregistrer en image et Lire à haute voix sur les blocs de texte de l\'assistant qui apparaissent avant les appels d\'outil suivants dans la même réponse.',
'settings.openchamber.visual.field.showToolFileIconsAria': 'Afficher les icônes des fichiers d\'outils',
'settings.openchamber.visual.field.codeBlockLineWrapAria': 'Renvoyer à la ligne les blocs de code',
'settings.openchamber.visual.field.codeBlockLineWrap': 'Renvoyer à la ligne les blocs de code',
'settings.openchamber.visual.field.showToolFileIcons': 'Afficher les icônes des fichiers d\'outils',
'settings.openchamber.visual.field.showDotfilesAria': 'Afficher les fichiers de points',
'settings.openchamber.visual.field.showDotfiles': 'Afficher les fichiers cachés',
+2
View File
@@ -2440,6 +2440,8 @@ export const dict = {
'sortableTabsStrip.aria.tabs': 'Onglets',
'openChamberLogo.aria.logo': 'Logo OpenChamber',
'markdownRenderer.table.actions.copyTitle': 'Copier le tableau',
'markdownRenderer.code.actions.enableWrapTitle': 'Activer le retour à la ligne',
'markdownRenderer.code.actions.disableWrapTitle': 'Désactiver le retour à la ligne',
'markdownRenderer.table.actions.downloadTitle': 'Télécharger le tableau',
'markdownRenderer.table.toast.downloadedAsFormat': 'Table téléchargée sous le nom {format}',
'markdownRenderer.mermaid.actions.copyTitle': 'Copie',
@@ -1741,6 +1741,8 @@ export const settingsDict = {
'settings.openchamber.visual.field.showSplitAssistantMessageActions': 'インラインアシスタントアクション',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': '同じ応答内の後のツール呼び出しの前に表示されるアシスタントテキストブロックに、回答コピー、画像保存、読み上げを表示します。',
'settings.openchamber.visual.field.showToolFileIconsAria': 'ツールファイルアイコンを表示',
'settings.openchamber.visual.field.codeBlockLineWrapAria': 'コードブロックの行を折り返す',
'settings.openchamber.visual.field.codeBlockLineWrap': 'コードブロックの行を折り返す',
'settings.openchamber.visual.field.showToolFileIcons': 'ツールファイルアイコンを表示',
'settings.openchamber.visual.field.showTurnChangedFilesAria': '完了したターンの変更ファイルを表示',
'settings.openchamber.visual.field.showTurnChangedFiles': '完了したターンの変更ファイルを表示',
+2
View File
@@ -2666,6 +2666,8 @@ export const dict: Record<I18nKey, string> = {
'sortableTabsStrip.aria.tabs': 'タブ',
'openChamberLogo.aria.logo': 'OpenChamberロゴ',
'markdownRenderer.table.actions.copyTitle': 'テーブルをコピー',
'markdownRenderer.code.actions.enableWrapTitle': '行折り返しを有効にする',
'markdownRenderer.code.actions.disableWrapTitle': '行折り返しを無効にする',
'markdownRenderer.table.actions.downloadTitle': 'テーブルをダウンロード',
'markdownRenderer.table.toast.downloadedAsFormat': 'テーブルを{format}としてダウンロードしました',
'markdownRenderer.mermaid.actions.copyTitle': 'コピー',
@@ -1708,6 +1708,8 @@ export const settingsDict = {
'settings.openchamber.visual.field.showSplitAssistantMessageActions': '인라인 어시스턴트 작업',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': '같은 응답에서 이후 도구 호출 앞에 나타나는 어시스턴트 텍스트 블록에 답변 복사, 이미지로 저장, 소리 내어 읽기 작업을 표시합니다.',
'settings.openchamber.visual.field.showToolFileIconsAria': '도구 파일 아이콘 표시',
'settings.openchamber.visual.field.codeBlockLineWrapAria': '코드 블록 줄 바꿈',
'settings.openchamber.visual.field.codeBlockLineWrap': '코드 블록 줄 바꿈',
'settings.openchamber.visual.field.showToolFileIcons': '도구 파일 아이콘 표시',
'settings.openchamber.visual.field.showTurnChangedFilesAria': '완료된 턴의 변경 파일 표시',
'settings.openchamber.visual.field.showTurnChangedFiles': '완료된 턴의 변경 파일 표시',
+2
View File
@@ -2670,6 +2670,8 @@ export const dict: Record<I18nKey, string> = {
'sortableTabsStrip.aria.tabs': '탭',
'openChamberLogo.aria.logo': 'OpenChamber 로고',
'markdownRenderer.table.actions.copyTitle': '표 복사',
'markdownRenderer.code.actions.enableWrapTitle': '줄 바꿈 켜기',
'markdownRenderer.code.actions.disableWrapTitle': '줄 바꿈 끄기',
'markdownRenderer.table.actions.downloadTitle': '표 다운로드',
'markdownRenderer.table.toast.downloadedAsFormat': '{format} 형식으로 다운로드됨',
'markdownRenderer.mermaid.actions.copyTitle': '복사',
@@ -989,6 +989,8 @@ export const settingsDict = {
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': 'Pokaż Kopiuj odpowiedź, Zapisz jako obraz i Odczytaj na głos w blokach tekstu asystenta, które pojawiają się przed późniejszymi wywołaniami narzędzi w tej samej odpowiedzi.',
'settings.openchamber.visual.field.showToolFileIcons': 'Pokaż ikony plików narzędzi',
'settings.openchamber.visual.field.showToolFileIconsAria': 'Pokaż ikony plików narzędzi',
'settings.openchamber.visual.field.codeBlockLineWrapAria': 'Zawijaj wiersze bloków kodu',
'settings.openchamber.visual.field.codeBlockLineWrap': 'Zawijaj wiersze bloków kodu',
'settings.openchamber.visual.field.showTurnChangedFiles': 'Pokaż zmienione pliki w ukończonych turach',
'settings.openchamber.visual.field.showTurnChangedFilesAria': 'Pokaż zmienione pliki w ukończonych turach',
'settings.openchamber.visual.field.spacingDensity': 'Gęstość odstępów',
+2
View File
@@ -2161,6 +2161,8 @@ export const dict: Record<I18nKey, string> = {
'markdownRenderer.mermaid.actions.downloadSvgTitle': 'Pobierz SVG',
'markdownRenderer.mermaid.toast.downloadFailed': 'Nie udało się pobrać diagramu',
'markdownRenderer.table.actions.copyTitle': 'Kopiuj tabelę',
'markdownRenderer.code.actions.enableWrapTitle': 'Włącz zawijanie wierszy',
'markdownRenderer.code.actions.disableWrapTitle': 'Wyłącz zawijanie wierszy',
'markdownRenderer.table.actions.downloadTitle': 'Pobierz tabelę',
'markdownRenderer.table.toast.downloadedAsFormat': 'Tabela została pobrana jako {format}',
'mcpDropdown.actions.openAria': 'Serwery MCP',
@@ -1708,6 +1708,8 @@ export const settingsDict = {
"settings.openchamber.visual.field.showSplitAssistantMessageActions": "Ações inline do assistente",
"settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip": "Mostra Copiar resposta, Salvar como imagem e Ler em voz alta em blocos de texto do assistente que aparecem antes de chamadas de ferramenta posteriores na mesma resposta.",
"settings.openchamber.visual.field.showToolFileIconsAria": "Mostrar ícones de arquivos de ferramentas",
"settings.openchamber.visual.field.codeBlockLineWrapAria": "Quebrar linhas de blocos de código",
"settings.openchamber.visual.field.codeBlockLineWrap": "Quebrar linhas de blocos de código",
"settings.openchamber.visual.field.showToolFileIcons": "Mostrar ícones de arquivos de ferramentas",
"settings.openchamber.visual.field.showTurnChangedFilesAria": "Mostrar arquivos alterados em turnos concluídos",
"settings.openchamber.visual.field.showTurnChangedFiles": "Mostrar arquivos alterados em turnos concluídos",
@@ -2636,6 +2636,8 @@ export const dict: Record<I18nKey, string> = {
"sortableTabsStrip.aria.tabs": "Abas",
"openChamberLogo.aria.logo": "Logo do OpenChamber",
"markdownRenderer.table.actions.copyTitle": "Copiar tabela",
"markdownRenderer.code.actions.enableWrapTitle": "Ativar quebra de linha",
"markdownRenderer.code.actions.disableWrapTitle": "Desativar quebra de linha",
"markdownRenderer.table.actions.downloadTitle": "Baixar tabela",
"markdownRenderer.table.toast.downloadedAsFormat": "Tabela baixada como {format}",
"markdownRenderer.mermaid.actions.copyTitle": "Copiar",
@@ -1708,6 +1708,8 @@ export const settingsDict = {
"settings.openchamber.visual.field.showSplitAssistantMessageActions": "Вбудовані дії асистента",
"settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip": "Показує «Скопіювати відповідь», «Зберегти як зображення» та озвучення для текстових блоків асистента, які з’являються перед пізнішими викликами інструментів у тій самій відповіді.",
"settings.openchamber.visual.field.showToolFileIconsAria": "Показати значки файлів інструментів",
"settings.openchamber.visual.field.codeBlockLineWrapAria": "Переносити рядки блоків коду",
"settings.openchamber.visual.field.codeBlockLineWrap": "Переносити рядки блоків коду",
"settings.openchamber.visual.field.showToolFileIcons": "Показати значки файлів інструментів",
"settings.openchamber.visual.field.showTurnChangedFilesAria": "Показати змінені файли для завершених ходів",
"settings.openchamber.visual.field.showTurnChangedFiles": "Показати змінені файли для завершених ходів",
+2
View File
@@ -2636,6 +2636,8 @@ export const dict: Record<I18nKey, string> = {
"sortableTabsStrip.aria.tabs": "Вкладки",
"openChamberLogo.aria.logo": "Логотип OpenChamber",
"markdownRenderer.table.actions.copyTitle": "Скопіювати таблицю",
"markdownRenderer.code.actions.enableWrapTitle": "Увімкнути перенесення рядків",
"markdownRenderer.code.actions.disableWrapTitle": "Вимкнути перенесення рядків",
"markdownRenderer.table.actions.downloadTitle": "Завантажити таблицю",
"markdownRenderer.table.toast.downloadedAsFormat": "Таблицю завантажено як {format}",
"markdownRenderer.mermaid.actions.copyTitle": "Копіювати",
@@ -1708,6 +1708,8 @@ export const settingsDict = {
'settings.openchamber.visual.field.showSplitAssistantMessageActions': '内联助手操作',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': '在同一条回复中,如果助手文本块后面还有工具调用,则显示“复制回答”“保存为图片”和“朗读”操作。',
'settings.openchamber.visual.field.showToolFileIconsAria': '显示工具文件图标',
'settings.openchamber.visual.field.codeBlockLineWrapAria': '代码块自动换行',
'settings.openchamber.visual.field.codeBlockLineWrap': '代码块自动换行',
'settings.openchamber.visual.field.showToolFileIcons': '显示工具文件图标',
'settings.openchamber.visual.field.showTurnChangedFilesAria': '显示已完成回合的更改文件',
'settings.openchamber.visual.field.showTurnChangedFiles': '显示已完成回合的更改文件',
@@ -2636,6 +2636,8 @@ export const dict: Record<I18nKey, string> = {
'sortableTabsStrip.aria.tabs': '标签页',
'openChamberLogo.aria.logo': 'OpenChamber 标志',
'markdownRenderer.table.actions.copyTitle': '复制表格',
'markdownRenderer.code.actions.enableWrapTitle': '启用自动换行',
'markdownRenderer.code.actions.disableWrapTitle': '禁用自动换行',
'markdownRenderer.table.actions.downloadTitle': '下载表格',
'markdownRenderer.table.toast.downloadedAsFormat': '表格已下载为 {format}',
'markdownRenderer.mermaid.actions.copyTitle': '复制',
@@ -1624,6 +1624,8 @@
'settings.openchamber.visual.field.showSplitAssistantMessageActions': '行內助理操作',
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': '在同一則回覆中,如果助理文字區塊後方還有工具呼叫,則顯示「複製回答」「儲存為圖片」和「朗讀」操作。',
'settings.openchamber.visual.field.showToolFileIconsAria': '顯示工具檔案圖示',
'settings.openchamber.visual.field.codeBlockLineWrapAria': '程式碼區塊自動換行',
'settings.openchamber.visual.field.codeBlockLineWrap': '程式碼區塊自動換行',
'settings.openchamber.visual.field.showToolFileIcons': '顯示工具檔案圖示',
'settings.openchamber.visual.field.showTurnChangedFilesAria': '顯示已完成回合的變更檔案',
'settings.openchamber.visual.field.showTurnChangedFiles': '顯示已完成回合的變更檔案',
@@ -2633,6 +2633,8 @@ export const dict: Record<I18nKey, string> = {
'sortableTabsStrip.aria.tabs': '分頁',
'openChamberLogo.aria.logo': 'OpenChamber 標誌',
'markdownRenderer.table.actions.copyTitle': '複製表格',
'markdownRenderer.code.actions.enableWrapTitle': '啟用自動換行',
'markdownRenderer.code.actions.disableWrapTitle': '停用自動換行',
'markdownRenderer.table.actions.downloadTitle': '下載表格',
'markdownRenderer.table.toast.downloadedAsFormat': '表格已下載為 {format}',
'markdownRenderer.mermaid.actions.copyTitle': '複製',
+6
View File
@@ -507,6 +507,9 @@ const applyDesktopUiPreferences = (settings: DesktopSettings) => {
if (typeof settings.showToolFileIcons === 'boolean' && settings.showToolFileIcons !== store.showToolFileIcons) {
store.setShowToolFileIcons(settings.showToolFileIcons);
}
if (typeof settings.codeBlockLineWrap === 'boolean' && settings.codeBlockLineWrap !== store.codeBlockLineWrap) {
store.setCodeBlockLineWrap(settings.codeBlockLineWrap);
}
if (typeof settings.showTurnChangedFiles === 'boolean' && settings.showTurnChangedFiles !== store.showTurnChangedFiles) {
store.setShowTurnChangedFiles(settings.showTurnChangedFiles);
}
@@ -1044,6 +1047,9 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
if (typeof candidate.showToolFileIcons === 'boolean') {
result.showToolFileIcons = candidate.showToolFileIcons;
}
if (typeof candidate.codeBlockLineWrap === 'boolean') {
result.codeBlockLineWrap = candidate.codeBlockLineWrap;
}
if (typeof candidate.showTurnChangedFiles === 'boolean') {
result.showTurnChangedFiles = candidate.showTurnChangedFiles;
}
+6
View File
@@ -203,6 +203,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.openchamber.visual.field.wideChatLayout',
keywords: ['layout', 'wide', 'messages'],
},
{
id: 'chat.code-block-line-wrap',
page: 'chat',
titleKey: 'settings.openchamber.visual.field.codeBlockLineWrap',
keywords: ['code', 'wrap', 'line wrap', 'markdown'],
},
{
id: 'chat.inline-assistant-actions',
page: 'chat',