diff --git a/Resources/Localizable.xcstrings b/Resources/Localizable.xcstrings index 05ac85643db6..2c610b7b301a 100644 --- a/Resources/Localizable.xcstrings +++ b/Resources/Localizable.xcstrings @@ -10109,7 +10109,6 @@ } } }, - "command.openHistoryPane.title": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"ja":{"stringUnit":{"state":"translated","value":"履歴をペインで開く"}},"ar":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"bs":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"da":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"de":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"es":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"fr":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"it":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"ko":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"nb":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"pl":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"ru":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"th":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"tr":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"uk":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Open History as Pane"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Open History as Pane"}}}}, "command.openVaultPane.title": { "extractionState": "manual", "localizations": { @@ -45091,13 +45090,12 @@ "menu.history.noFocusBackHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"No Back History"}},"ja":{"stringUnit":{"state":"translated","value":"戻る履歴がありません"}},"ar":{"stringUnit":{"state":"translated","value":"No Back History"}},"bs":{"stringUnit":{"state":"translated","value":"No Back History"}},"da":{"stringUnit":{"state":"translated","value":"No Back History"}},"de":{"stringUnit":{"state":"translated","value":"No Back History"}},"es":{"stringUnit":{"state":"translated","value":"No Back History"}},"fr":{"stringUnit":{"state":"translated","value":"No Back History"}},"it":{"stringUnit":{"state":"translated","value":"No Back History"}},"ko":{"stringUnit":{"state":"translated","value":"No Back History"}},"nb":{"stringUnit":{"state":"translated","value":"No Back History"}},"pl":{"stringUnit":{"state":"translated","value":"No Back History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"No Back History"}},"ru":{"stringUnit":{"state":"translated","value":"No Back History"}},"th":{"stringUnit":{"state":"translated","value":"No Back History"}},"tr":{"stringUnit":{"state":"translated","value":"No Back History"}},"uk":{"stringUnit":{"state":"translated","value":"No Back History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"No Back History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"No Back History"}}}}, "menu.history.noFocusForwardHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"No Forward History"}},"ja":{"stringUnit":{"state":"translated","value":"進む履歴がありません"}},"ar":{"stringUnit":{"state":"translated","value":"No Forward History"}},"bs":{"stringUnit":{"state":"translated","value":"No Forward History"}},"da":{"stringUnit":{"state":"translated","value":"No Forward History"}},"de":{"stringUnit":{"state":"translated","value":"No Forward History"}},"es":{"stringUnit":{"state":"translated","value":"No Forward History"}},"fr":{"stringUnit":{"state":"translated","value":"No Forward History"}},"it":{"stringUnit":{"state":"translated","value":"No Forward History"}},"ko":{"stringUnit":{"state":"translated","value":"No Forward History"}},"nb":{"stringUnit":{"state":"translated","value":"No Forward History"}},"pl":{"stringUnit":{"state":"translated","value":"No Forward History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"No Forward History"}},"ru":{"stringUnit":{"state":"translated","value":"No Forward History"}},"th":{"stringUnit":{"state":"translated","value":"No Forward History"}},"tr":{"stringUnit":{"state":"translated","value":"No Forward History"}},"uk":{"stringUnit":{"state":"translated","value":"No Forward History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"No Forward History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"No Forward History"}}}}, "menu.history.noFocusHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"No Focus History"}},"ja":{"stringUnit":{"state":"translated","value":"フォーカス履歴がありません"}},"ar":{"stringUnit":{"state":"translated","value":"No Focus History"}},"bs":{"stringUnit":{"state":"translated","value":"No Focus History"}},"da":{"stringUnit":{"state":"translated","value":"No Focus History"}},"de":{"stringUnit":{"state":"translated","value":"No Focus History"}},"es":{"stringUnit":{"state":"translated","value":"No Focus History"}},"fr":{"stringUnit":{"state":"translated","value":"No Focus History"}},"it":{"stringUnit":{"state":"translated","value":"No Focus History"}},"ko":{"stringUnit":{"state":"translated","value":"No Focus History"}},"nb":{"stringUnit":{"state":"translated","value":"No Focus History"}},"pl":{"stringUnit":{"state":"translated","value":"No Focus History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"No Focus History"}},"ru":{"stringUnit":{"state":"translated","value":"No Focus History"}},"th":{"stringUnit":{"state":"translated","value":"No Focus History"}},"tr":{"stringUnit":{"state":"translated","value":"No Focus History"}},"uk":{"stringUnit":{"state":"translated","value":"No Focus History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"No Focus History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"No Focus History"}}}}, - "menu.history.openFullHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"ja":{"stringUnit":{"state":"translated","value":"すべての履歴を開く…"}},"ar":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"bs":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"da":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"de":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"es":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"fr":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"it":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"ko":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"nb":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"pl":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"ru":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"th":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"tr":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"uk":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Open Full History…"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Open Full History…"}}}}, "menu.history.recentlyFocused": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"ja":{"stringUnit":{"state":"translated","value":"最近フォーカスした項目"}},"ar":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"bs":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"da":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"de":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"es":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"fr":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"it":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"ko":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"nb":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"pl":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"ru":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"th":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"tr":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"uk":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Recently Focused"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Recently Focused"}}}}, "menu.history.recentlyFocused.subtitle": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"ja":{"stringUnit":{"state":"translated","value":"最近フォーカスした移動先"}},"ar":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"bs":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"da":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"de":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"es":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"fr":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"it":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"ko":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"nb":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"pl":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"ru":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"th":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"tr":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"uk":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Most recent focus targets"}}}}, "menu.history.menuItemSubtitleFormat": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"ja":{"stringUnit":{"state":"translated","value":"%1$@、%2$@"}},"ar":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"bs":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"da":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"de":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"es":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"fr":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"it":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"ko":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"nb":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"pl":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"pt-BR":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"ru":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"th":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"tr":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"uk":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"%1$@, %2$@"}}}}, "menu.history.showFullFocusBackHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"ja":{"stringUnit":{"state":"translated","value":"戻る履歴をすべて表示"}},"ar":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"bs":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"da":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"de":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"es":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"fr":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"it":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"ko":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"nb":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"pl":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"ru":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"th":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"tr":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"uk":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Show Full Back History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Show Full Back History"}}}}, - "menu.history.showFullFocusForwardHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"ja":{"stringUnit":{"state":"translated","value":"進む履歴をすべて表示"}},"ar":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"bs":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"da":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"de":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"es":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"fr":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"it":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"ko":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"nb":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"pl":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"ru":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"th":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"tr":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"uk":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}}}}, "menu.history.showFullFocusHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Show Full History"}},"ja":{"stringUnit":{"state":"translated","value":"すべての履歴を表示"}},"ar":{"stringUnit":{"state":"translated","value":"Show Full History"}},"bs":{"stringUnit":{"state":"translated","value":"Show Full History"}},"da":{"stringUnit":{"state":"translated","value":"Show Full History"}},"de":{"stringUnit":{"state":"translated","value":"Show Full History"}},"es":{"stringUnit":{"state":"translated","value":"Show Full History"}},"fr":{"stringUnit":{"state":"translated","value":"Show Full History"}},"it":{"stringUnit":{"state":"translated","value":"Show Full History"}},"ko":{"stringUnit":{"state":"translated","value":"Show Full History"}},"nb":{"stringUnit":{"state":"translated","value":"Show Full History"}},"pl":{"stringUnit":{"state":"translated","value":"Show Full History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Show Full History"}},"ru":{"stringUnit":{"state":"translated","value":"Show Full History"}},"th":{"stringUnit":{"state":"translated","value":"Show Full History"}},"tr":{"stringUnit":{"state":"translated","value":"Show Full History"}},"uk":{"stringUnit":{"state":"translated","value":"Show Full History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Show Full History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Show Full History"}}}}, + "menu.history.showFullFocusForwardHistory": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"ja":{"stringUnit":{"state":"translated","value":"進む履歴をすべて表示"}},"ar":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"bs":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"da":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"de":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"es":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"fr":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"it":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"ko":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"nb":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"pl":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"ru":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"th":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"tr":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"uk":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Show Full Forward History"}}}}, "menu.history.recentlyClosed": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"ja":{"stringUnit":{"state":"translated","value":"最近閉じた項目"}},"ar":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"bs":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"da":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"de":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"es":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"fr":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"it":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"ko":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"nb":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"pl":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"ru":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"th":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"tr":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"uk":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Recently Closed"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Recently Closed"}}}}, "menu.history.recentlyClosed.subtitle": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"ja":{"stringUnit":{"state":"translated","value":"タブ、ワークスペース、ウィンドウ"}},"ar":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"bs":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"da":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"de":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"es":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"fr":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"it":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"ko":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"nb":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"pl":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"ru":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"th":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"tr":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"uk":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Tabs, workspaces, and windows"}}}}, "menu.history.recentlyClosed.clearAll": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Clear All"}},"ja":{"stringUnit":{"state":"translated","value":"すべて消去"}},"ar":{"stringUnit":{"state":"translated","value":"Clear All"}},"bs":{"stringUnit":{"state":"translated","value":"Clear All"}},"da":{"stringUnit":{"state":"translated","value":"Clear All"}},"de":{"stringUnit":{"state":"translated","value":"Clear All"}},"es":{"stringUnit":{"state":"translated","value":"Clear All"}},"fr":{"stringUnit":{"state":"translated","value":"Clear All"}},"it":{"stringUnit":{"state":"translated","value":"Clear All"}},"ko":{"stringUnit":{"state":"translated","value":"Clear All"}},"nb":{"stringUnit":{"state":"translated","value":"Clear All"}},"pl":{"stringUnit":{"state":"translated","value":"Clear All"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Clear All"}},"ru":{"stringUnit":{"state":"translated","value":"Clear All"}},"th":{"stringUnit":{"state":"translated","value":"Clear All"}},"tr":{"stringUnit":{"state":"translated","value":"Clear All"}},"uk":{"stringUnit":{"state":"translated","value":"Clear All"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Clear All"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Clear All"}}}}, @@ -45111,7 +45109,6 @@ "menu.history.recentlyClosed.panel.markdown": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Markdown"}},"ja":{"stringUnit":{"state":"translated","value":"Markdown"}},"ar":{"stringUnit":{"state":"translated","value":"Markdown"}},"bs":{"stringUnit":{"state":"translated","value":"Markdown"}},"da":{"stringUnit":{"state":"translated","value":"Markdown"}},"de":{"stringUnit":{"state":"translated","value":"Markdown"}},"es":{"stringUnit":{"state":"translated","value":"Markdown"}},"fr":{"stringUnit":{"state":"translated","value":"Markdown"}},"it":{"stringUnit":{"state":"translated","value":"Markdown"}},"ko":{"stringUnit":{"state":"translated","value":"Markdown"}},"nb":{"stringUnit":{"state":"translated","value":"Markdown"}},"pl":{"stringUnit":{"state":"translated","value":"Markdown"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Markdown"}},"ru":{"stringUnit":{"state":"translated","value":"Markdown"}},"th":{"stringUnit":{"state":"translated","value":"Markdown"}},"tr":{"stringUnit":{"state":"translated","value":"Markdown"}},"uk":{"stringUnit":{"state":"translated","value":"Markdown"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Markdown"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Markdown"}}}}, "menu.history.recentlyClosed.panel.terminal": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Terminal"}},"ja":{"stringUnit":{"state":"translated","value":"ターミナル"}},"ar":{"stringUnit":{"state":"translated","value":"Terminal"}},"bs":{"stringUnit":{"state":"translated","value":"Terminal"}},"da":{"stringUnit":{"state":"translated","value":"Terminal"}},"de":{"stringUnit":{"state":"translated","value":"Terminal"}},"es":{"stringUnit":{"state":"translated","value":"Terminal"}},"fr":{"stringUnit":{"state":"translated","value":"Terminal"}},"it":{"stringUnit":{"state":"translated","value":"Terminal"}},"ko":{"stringUnit":{"state":"translated","value":"Terminal"}},"nb":{"stringUnit":{"state":"translated","value":"Terminal"}},"pl":{"stringUnit":{"state":"translated","value":"Terminal"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Terminal"}},"ru":{"stringUnit":{"state":"translated","value":"Terminal"}},"th":{"stringUnit":{"state":"translated","value":"Terminal"}},"tr":{"stringUnit":{"state":"translated","value":"Terminal"}},"uk":{"stringUnit":{"state":"translated","value":"Terminal"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Terminal"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Terminal"}}}}, "menu.history.recentlyClosed.panel.tool": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Tool"}},"ja":{"stringUnit":{"state":"translated","value":"ツール"}},"ar":{"stringUnit":{"state":"translated","value":"Tool"}},"bs":{"stringUnit":{"state":"translated","value":"Tool"}},"da":{"stringUnit":{"state":"translated","value":"Tool"}},"de":{"stringUnit":{"state":"translated","value":"Tool"}},"es":{"stringUnit":{"state":"translated","value":"Tool"}},"fr":{"stringUnit":{"state":"translated","value":"Tool"}},"it":{"stringUnit":{"state":"translated","value":"Tool"}},"ko":{"stringUnit":{"state":"translated","value":"Tool"}},"nb":{"stringUnit":{"state":"translated","value":"Tool"}},"pl":{"stringUnit":{"state":"translated","value":"Tool"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Tool"}},"ru":{"stringUnit":{"state":"translated","value":"Tool"}},"th":{"stringUnit":{"state":"translated","value":"Tool"}},"tr":{"stringUnit":{"state":"translated","value":"Tool"}},"uk":{"stringUnit":{"state":"translated","value":"Tool"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Tool"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Tool"}}}}, - "menu.history.recentlyClosed.showFull": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"ja":{"stringUnit":{"state":"translated","value":"最近閉じた項目をすべて表示"}},"ar":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"bs":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"da":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"de":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"es":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"fr":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"it":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"ko":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"nb":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"pl":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"pt-BR":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"ru":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"th":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"tr":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"uk":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"Show Full Recently Closed"}}}}, "menu.history.recentlyClosed.window.oneWorkspace": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"1 workspace"}},"ja":{"stringUnit":{"state":"translated","value":"1 個のワークスペース"}},"ar":{"stringUnit":{"state":"translated","value":"1 workspace"}},"bs":{"stringUnit":{"state":"translated","value":"1 workspace"}},"da":{"stringUnit":{"state":"translated","value":"1 workspace"}},"de":{"stringUnit":{"state":"translated","value":"1 workspace"}},"es":{"stringUnit":{"state":"translated","value":"1 workspace"}},"fr":{"stringUnit":{"state":"translated","value":"1 workspace"}},"it":{"stringUnit":{"state":"translated","value":"1 workspace"}},"ko":{"stringUnit":{"state":"translated","value":"1 workspace"}},"nb":{"stringUnit":{"state":"translated","value":"1 workspace"}},"pl":{"stringUnit":{"state":"translated","value":"1 workspace"}},"pt-BR":{"stringUnit":{"state":"translated","value":"1 workspace"}},"ru":{"stringUnit":{"state":"translated","value":"1 workspace"}},"th":{"stringUnit":{"state":"translated","value":"1 workspace"}},"tr":{"stringUnit":{"state":"translated","value":"1 workspace"}},"uk":{"stringUnit":{"state":"translated","value":"1 workspace"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"1 workspace"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"1 workspace"}}}}, "menu.history.recentlyClosed.window.workspaceCount": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"ja":{"stringUnit":{"state":"translated","value":"%d 個のワークスペース"}},"ar":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"bs":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"da":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"de":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"es":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"fr":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"it":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"ko":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"nb":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"pl":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"pt-BR":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"ru":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"th":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"tr":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"uk":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"%d workspaces"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"%d workspaces"}}}}, "menu.history.recentlyClosed.window.workspaceCount.one": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"1 workspace"}},"ja":{"stringUnit":{"state":"translated","value":"1 個のワークスペース"}},"ar":{"stringUnit":{"state":"translated","value":"1 workspace"}},"bs":{"stringUnit":{"state":"translated","value":"1 workspace"}},"da":{"stringUnit":{"state":"translated","value":"1 workspace"}},"de":{"stringUnit":{"state":"translated","value":"1 workspace"}},"es":{"stringUnit":{"state":"translated","value":"1 workspace"}},"fr":{"stringUnit":{"state":"translated","value":"1 workspace"}},"it":{"stringUnit":{"state":"translated","value":"1 workspace"}},"ko":{"stringUnit":{"state":"translated","value":"1 workspace"}},"nb":{"stringUnit":{"state":"translated","value":"1 workspace"}},"pl":{"stringUnit":{"state":"translated","value":"1 workspace"}},"pt-BR":{"stringUnit":{"state":"translated","value":"1 workspace"}},"ru":{"stringUnit":{"state":"translated","value":"1 workspace"}},"th":{"stringUnit":{"state":"translated","value":"1 workspace"}},"tr":{"stringUnit":{"state":"translated","value":"1 workspace"}},"uk":{"stringUnit":{"state":"translated","value":"1 workspace"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"1 workspace"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"1 workspace"}}}}, @@ -110431,29 +110428,6 @@ } } }, - "shortcut.switchRightSidebarToHistory.label": { - "extractionState": "manual", - "localizations": { - "en": { - "stringUnit": { - "state": "translated", - "value": "Show Sidebar History" - } - }, - "ja": { - "stringUnit": { - "state": "translated", - "value": "サイドバーの履歴を表示" - } - }, - "ko": { - "stringUnit": { - "state": "translated", - "value": "사이드바 기록 표시" - } - } - } - }, "menu.view.focusRightSidebar": { "extractionState": "manual", "localizations": { @@ -113193,7 +113167,6 @@ } } }, - "rightSidebar.mode.history": {"extractionState":"manual","localizations":{"en":{"stringUnit":{"state":"translated","value":"History"}},"ja":{"stringUnit":{"state":"translated","value":"履歴"}},"ar":{"stringUnit":{"state":"translated","value":"History"}},"bs":{"stringUnit":{"state":"translated","value":"History"}},"da":{"stringUnit":{"state":"translated","value":"History"}},"de":{"stringUnit":{"state":"translated","value":"History"}},"es":{"stringUnit":{"state":"translated","value":"History"}},"fr":{"stringUnit":{"state":"translated","value":"History"}},"it":{"stringUnit":{"state":"translated","value":"History"}},"ko":{"stringUnit":{"state":"translated","value":"History"}},"nb":{"stringUnit":{"state":"translated","value":"History"}},"pl":{"stringUnit":{"state":"translated","value":"History"}},"pt-BR":{"stringUnit":{"state":"translated","value":"History"}},"ru":{"stringUnit":{"state":"translated","value":"History"}},"th":{"stringUnit":{"state":"translated","value":"History"}},"tr":{"stringUnit":{"state":"translated","value":"History"}},"uk":{"stringUnit":{"state":"translated","value":"History"}},"zh-Hans":{"stringUnit":{"state":"translated","value":"History"}},"zh-Hant":{"stringUnit":{"state":"translated","value":"History"}}}}, "dock.action.focusControl": { "extractionState": "manual", "localizations": { diff --git a/Sources/AppDelegate+HistoryPane.swift b/Sources/AppDelegate+HistoryPane.swift deleted file mode 100644 index 062e3c0312d6..000000000000 --- a/Sources/AppDelegate+HistoryPane.swift +++ /dev/null @@ -1,23 +0,0 @@ -import AppKit - -extension AppDelegate { - @discardableResult - func openHistoryPane( - preferredTabManager: TabManager? = nil, - preferredWindow: NSWindow? = nil - ) -> Bool { - let manager = preferredTabManager - ?? activeTabManagerForCommands(preferredWindow: preferredWindow ?? NSApp.keyWindow ?? NSApp.mainWindow) - guard let workspace = manager?.selectedWorkspace, - let paneId = workspace.bonsplitController.focusedPaneId ?? workspace.bonsplitController.allPaneIds.first else { - return false - } - - workspace.clearSplitZoom() - return workspace.openOrFocusRightSidebarToolSurface( - inPane: paneId, - mode: .history, - focus: true - ) != nil - } -} diff --git a/Sources/ContentView+RightSidebarCommandPalette.swift b/Sources/ContentView+RightSidebarCommandPalette.swift index 66e17c603a67..5aeb65451087 100644 --- a/Sources/ContentView+RightSidebarCommandPalette.swift +++ b/Sources/ContentView+RightSidebarCommandPalette.swift @@ -131,8 +131,6 @@ extension ContentView { return "palette.showRightSidebarFeed" case .dock: return "palette.showRightSidebarDock" - case .history: - return "palette.showHistoryPane" } } @@ -154,8 +152,6 @@ extension ContentView { return "palette.openFindPane" case .sessions: return "palette.openVaultPane" - case .history: - return "palette.openHistoryPane" case .feed, .dock: return nil } @@ -169,8 +165,6 @@ extension ContentView { return String(localized: "command.openFindPane.title", defaultValue: "Open Find as Pane") case .sessions: return String(localized: "command.openVaultPane.title", defaultValue: "Open Vault as Pane") - case .history: - return String(localized: "command.openHistoryPane.title", defaultValue: "Open History as Pane") case .feed, .dock: return nil } diff --git a/Sources/HistoryPanelView.swift b/Sources/HistoryPanelView.swift deleted file mode 100644 index 5e430fbd9a36..000000000000 --- a/Sources/HistoryPanelView.swift +++ /dev/null @@ -1,385 +0,0 @@ -import AppKit -import SwiftUI - -enum HistoryDayGrouping { - static func matches(query: String, fields: [String]) -> Bool { - let terms = query - .trimmingCharacters(in: .whitespacesAndNewlines) - .split(whereSeparator: { $0.isWhitespace }) - .map(String.init) - guard !terms.isEmpty else { return true } - - let haystack = fields.joined(separator: " ") - return terms.allSatisfy { term in - haystack.localizedCaseInsensitiveContains(term) - } - } - - static func dayTitle( - for date: Date, - now: Date = Date(), - calendar: Calendar = .current - ) -> String { - if calendar.isDate(date, inSameDayAs: now) { - return String(localized: "historyPane.day.today", defaultValue: "Today") - } - - if let yesterday = calendar.date(byAdding: .day, value: -1, to: now), - calendar.isDate(date, inSameDayAs: yesterday) { - return String(localized: "historyPane.day.yesterday", defaultValue: "Yesterday") - } - - return Self.dayFormatter.string(from: date) - } - - private static let dayFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.dateStyle = .full - formatter.timeStyle = .none - return formatter - }() -} - -struct HistoryPanelView: View { - @ObservedObject private var closedStore = ClosedItemHistoryStore.shared - @EnvironmentObject private var tabManager: TabManager - - let focusSearchToken: Int - let onFocus: () -> Void - let onOpenClosedItem: (UUID) -> Bool - let onOpenFocusedItem: (FocusHistoryMenuItem) -> Bool - let onClearClosedItems: () -> Void - - @State private var query = "" - @FocusState private var isSearchFieldFocused: Bool - - var body: some View { - let closedSnapshot = closedStore.menuSnapshot() - let focusedBackSnapshot = tabManager.focusHistoryMenuSnapshot(direction: .back) - let focusedForwardSnapshot = tabManager.focusHistoryMenuSnapshot(direction: .forward) - let _ = closedStore.revision - let _ = tabManager.focusHistoryRevision - let closedGroups = groupedRows( - closedSnapshot.items.map(Self.closedRow), - query: query - ) - let focusedGroups = groupedRows( - (focusedBackSnapshot.items + focusedForwardSnapshot.items).map(Self.focusedRow), - query: query - ) - let hasAnyRows = !closedSnapshot.items.isEmpty || - !focusedBackSnapshot.items.isEmpty || - !focusedForwardSnapshot.items.isEmpty - let hasVisibleRows = !closedGroups.isEmpty || !focusedGroups.isEmpty - - VStack(spacing: 0) { - header( - hasClosedItems: !closedSnapshot.items.isEmpty - ) - - searchField - .padding(.horizontal, 12) - .padding(.bottom, 10) - - if !hasAnyRows { - emptyState(String(localized: "historyPane.empty", defaultValue: "No history yet")) - } else if !hasVisibleRows { - emptyState(String(localized: "historyPane.noResults", defaultValue: "No matching history")) - } else { - ScrollView { - LazyVStack(alignment: .leading, spacing: 18) { - if !closedGroups.isEmpty { - historySection( - title: String(localized: "menu.history.recentlyClosed", defaultValue: "Recently Closed"), - groups: closedGroups - ) - } - - if !focusedGroups.isEmpty { - historySection( - title: String(localized: "menu.history.recentlyFocused", defaultValue: "Recently Focused"), - groups: focusedGroups - ) - } - } - .padding(.horizontal, 12) - .padding(.bottom, 18) - } - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .contentShape(Rectangle()) - .onTapGesture(perform: onFocus) - .onAppear { - guard focusSearchToken > 0 else { return } - focusSearchField() - } - .onChange(of: focusSearchToken) { _, _ in - focusSearchField() - } - } - - private func header(hasClosedItems: Bool) -> some View { - HStack(spacing: 10) { - Image(systemName: "clock.arrow.circlepath") - .font(.system(size: 13, weight: .medium)) - .foregroundStyle(.secondary) - - Text(String(localized: "menu.history.title", defaultValue: "History")) - .font(.system(size: 13, weight: .semibold)) - - Spacer(minLength: 8) - - Button(String(localized: "historyPane.clearClosed", defaultValue: "Clear Closed")) { - onClearClosedItems() - } - .disabled(!hasClosedItems) - .buttonStyle(.borderless) - .font(.system(size: 12)) - .help(String(localized: "historyPane.clearClosed.help", defaultValue: "Clear recently closed history")) - } - .padding(.horizontal, 12) - .padding(.vertical, 10) - .overlay(alignment: .bottom) { - Rectangle() - .fill(Color.primary.opacity(0.08)) - .frame(height: 1) - } - .accessibilityIdentifier("HistoryPane.Header") - } - - private var searchField: some View { - HStack(spacing: 7) { - Image(systemName: "magnifyingglass") - .font(.system(size: 12, weight: .medium)) - .foregroundStyle(.secondary) - - TextField(String(localized: "historyPane.search.placeholder", defaultValue: "Search history"), text: $query) - .textFieldStyle(.plain) - .font(.system(size: 13)) - .focused($isSearchFieldFocused) - - if !query.isEmpty { - Button { - query = "" - } label: { - Image(systemName: "xmark.circle.fill") - .font(.system(size: 12, weight: .medium)) - .foregroundStyle(.secondary) - } - .buttonStyle(.plain) - .help(String(localized: "historyPane.search.clear", defaultValue: "Clear search")) - } - } - .padding(.horizontal, 9) - .padding(.vertical, 7) - .background( - RoundedRectangle(cornerRadius: 6) - .fill(Color.primary.opacity(0.06)) - ) - .padding(.top, 10) - .accessibilityIdentifier("HistoryPane.SearchField") - } - - private func focusSearchField() { - Task { @MainActor in - isSearchFieldFocused = true - } - } - - private func emptyState(_ title: String) -> some View { - Text(title) - .font(.system(size: 13)) - .foregroundStyle(.secondary) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) - .padding(20) - .accessibilityIdentifier("HistoryPane.EmptyState") - } - - private func historySection(title: String, groups: [HistoryPaneDayGroup]) -> some View { - VStack(alignment: .leading, spacing: 10) { - Text(title) - .font(.system(size: 12, weight: .semibold)) - .foregroundStyle(.secondary) - .textCase(.uppercase) - .padding(.horizontal, 2) - - ForEach(groups) { group in - VStack(alignment: .leading, spacing: 4) { - Text(group.title) - .font(.system(size: 12, weight: .medium)) - .foregroundStyle(.secondary) - .padding(.horizontal, 2) - .padding(.top, 2) - - LazyVStack(alignment: .leading, spacing: 1) { - ForEach(group.rows) { row in - HistoryPaneRowView(row: row) { - switch row.kind { - case .closed(let id): - if !onOpenClosedItem(id) { - NSSound.beep() - } - case .focused(let item): - if !onOpenFocusedItem(item) { - NSSound.beep() - } - } - } - } - } - } - } - } - } - - private func groupedRows(_ rows: [HistoryPaneRow], query: String) -> [HistoryPaneDayGroup] { - let calendar = Calendar.current - let filteredRows = rows - .filter { row in - HistoryDayGrouping.matches( - query: query, - fields: [row.title, row.subtitle, row.detail, row.badge] - ) - } - .sorted { lhs, rhs in lhs.timestamp > rhs.timestamp } - - let grouped = Dictionary(grouping: filteredRows) { row in - calendar.startOfDay(for: row.timestamp) - } - - return grouped.keys - .sorted(by: >) - .compactMap { day in - guard let rows = grouped[day], !rows.isEmpty else { return nil } - return HistoryPaneDayGroup( - day: day, - title: HistoryDayGrouping.dayTitle(for: day, calendar: calendar), - rows: rows - ) - } - } - - private static func closedRow(_ item: ClosedItemHistoryMenuItem) -> HistoryPaneRow { - let time = item.closedAt.formatted(date: .omitted, time: .shortened) - return HistoryPaneRow( - id: "closed-\(item.id.uuidString)", - title: item.title, - subtitle: item.detail, - detail: String( - format: String(localized: "historyPane.closedAtFormat", defaultValue: "Closed %@"), - time - ), - badge: String(localized: "menu.history.recentlyClosed", defaultValue: "Recently Closed"), - timestamp: item.closedAt, - kind: .closed(item.id) - ) - } - - private static func focusedRow(_ item: FocusHistoryMenuItem) -> HistoryPaneRow { - let time = item.focusedAt.formatted(date: .omitted, time: .shortened) - let badge: String - switch item.position { - case .older: - badge = String(localized: "menu.history.focusBack", defaultValue: "Focus Back") - case .newer: - badge = String(localized: "menu.history.focusForward", defaultValue: "Focus Forward") - } - - return HistoryPaneRow( - id: "focused-\(item.position)-\(item.historyIndex)", - title: item.workspaceTitle, - subtitle: item.panelTitle ?? badge, - detail: String( - format: String(localized: "historyPane.focusedAtFormat", defaultValue: "Focused %@"), - time - ), - badge: badge, - timestamp: item.focusedAt, - kind: .focused(item) - ) - } -} - -private struct HistoryPaneDayGroup: Identifiable { - var id: TimeInterval { day.timeIntervalSinceReferenceDate } - let day: Date - let title: String - let rows: [HistoryPaneRow] -} - -private struct HistoryPaneRow: Identifiable { - enum Kind { - case closed(UUID) - case focused(FocusHistoryMenuItem) - } - - let id: String - let title: String - let subtitle: String - let detail: String - let badge: String - let timestamp: Date - let kind: Kind -} - -private struct HistoryPaneRowView: View { - let row: HistoryPaneRow - let action: () -> Void - - @State private var isHovered = false - - var body: some View { - Button(action: action) { - HStack(alignment: .center, spacing: 10) { - VStack(alignment: .leading, spacing: 2) { - Text(row.title) - .font(.system(size: 13, weight: .medium)) - .foregroundStyle(.primary) - .lineLimit(1) - - Text(row.subtitle) - .font(.system(size: 12)) - .foregroundStyle(.secondary) - .lineLimit(1) - } - - Spacer(minLength: 8) - - VStack(alignment: .trailing, spacing: 2) { - Text(row.badge) - .font(.system(size: 10, weight: .medium)) - .foregroundStyle(.secondary) - .lineLimit(1) - - Text(row.detail) - .font(.system(size: 11)) - .foregroundStyle(.secondary) - .lineLimit(1) - } - } - .padding(.horizontal, 8) - .padding(.vertical, 6) - .contentShape(Rectangle()) - } - .buttonStyle(HistoryPaneRowButtonStyle(isHovered: isHovered)) - .onHover { isHovered = $0 } - .accessibilityIdentifier("HistoryPane.Row.\(row.id)") - } -} - -private struct HistoryPaneRowButtonStyle: ButtonStyle { - let isHovered: Bool - - func makeBody(configuration: Configuration) -> some View { - configuration.label - .background( - RoundedRectangle(cornerRadius: 6) - .fill( - Color.primary.opacity( - configuration.isPressed ? 0.11 : (isHovered ? 0.07 : 0) - ) - ) - ) - } -} diff --git a/Sources/KeyboardShortcutContext.swift b/Sources/KeyboardShortcutContext.swift index 7f7b2fbec2fb..43e9d3f48482 100644 --- a/Sources/KeyboardShortcutContext.swift +++ b/Sources/KeyboardShortcutContext.swift @@ -49,7 +49,7 @@ extension KeyboardShortcutSettings.Action { var shortcutContext: ShortcutContext { switch self { - case .switchRightSidebarToFiles, .switchRightSidebarToFind, .switchRightSidebarToSessions, .switchRightSidebarToFeed, .switchRightSidebarToDock, .switchRightSidebarToHistory: + case .switchRightSidebarToFiles, .switchRightSidebarToFind, .switchRightSidebarToSessions, .switchRightSidebarToFeed, .switchRightSidebarToDock: return .rightSidebarFocus case .renameTab, .renameWorkspace: return .nonBrowserPanel diff --git a/Sources/KeyboardShortcutSettings.swift b/Sources/KeyboardShortcutSettings.swift index 2bc0c54473be..1e925dbf86b8 100644 --- a/Sources/KeyboardShortcutSettings.swift +++ b/Sources/KeyboardShortcutSettings.swift @@ -88,7 +88,6 @@ enum KeyboardShortcutSettings { case switchRightSidebarToSessions case switchRightSidebarToFeed case switchRightSidebarToDock - case switchRightSidebarToHistory case triggerFlash // Navigation @@ -178,7 +177,6 @@ enum KeyboardShortcutSettings { case .switchRightSidebarToSessions: return String(localized: "shortcut.switchRightSidebarToSessions.label", defaultValue: "Show Sidebar Vault") case .switchRightSidebarToFeed: return String(localized: "shortcut.switchRightSidebarToFeed.label", defaultValue: "Show Sidebar Feed") case .switchRightSidebarToDock: return String(localized: "shortcut.switchRightSidebarToDock.label", defaultValue: "Show Sidebar Dock") - case .switchRightSidebarToHistory: return String(localized: "shortcut.switchRightSidebarToHistory.label", defaultValue: "Show Sidebar History") case .triggerFlash: return String(localized: "shortcut.flashFocusedPanel.label", defaultValue: "Flash Focused Panel") case .nextSurface: return String(localized: "shortcut.nextSurface.label", defaultValue: "Next Surface") case .prevSurface: return String(localized: "shortcut.previousSurface.label", defaultValue: "Previous Surface") @@ -239,8 +237,7 @@ enum KeyboardShortcutSettings { .switchRightSidebarToFind, .switchRightSidebarToSessions, .switchRightSidebarToFeed, - .switchRightSidebarToDock, - .switchRightSidebarToHistory: + .switchRightSidebarToDock: return false default: return true @@ -307,8 +304,6 @@ enum KeyboardShortcutSettings { return StoredShortcut(key: "4", command: false, shift: false, option: false, control: true) case .switchRightSidebarToDock: return StoredShortcut(key: "5", command: false, shift: false, option: false, control: true) - case .switchRightSidebarToHistory: - return StoredShortcut(key: "6", command: false, shift: false, option: false, control: true) case .triggerFlash: return StoredShortcut(key: "h", command: true, shift: true, option: false, control: false) case .nextSidebarTab: diff --git a/Sources/MainWindowFocusController.swift b/Sources/MainWindowFocusController.swift index 161c4a7145a3..98b1f9bc7b7d 100644 --- a/Sources/MainWindowFocusController.swift +++ b/Sources/MainWindowFocusController.swift @@ -55,7 +55,6 @@ final class MainWindowFocusController { private weak var fileSearchHost: FileExplorerContainerView? private weak var feedHost: FeedKeyboardFocusView? private weak var dockHost: DockKeyboardFocusView? - private weak var historyHost: RightSidebarHistoryFocusAnchorView? private(set) var intent: MainWindowKeyboardFocusIntent? { didSet { @@ -110,7 +109,7 @@ final class MainWindowFocusController { fileExplorerHost = host case .find: fileSearchHost = host - case .sessions, .feed, .dock, .history: + case .sessions, .feed, .dock: break } focusRegisteredRightSidebarEndpointIfNeeded(mode: mode) @@ -127,11 +126,6 @@ final class MainWindowFocusController { focusRegisteredRightSidebarEndpointIfNeeded(mode: .dock) } - func registerHistoryHost(_ host: RightSidebarHistoryFocusAnchorView) { - historyHost = host - focusRegisteredRightSidebarEndpointIfNeeded(mode: .history) - } - func noteRightSidebarInteraction(mode: RightSidebarMode) { rememberedRightSidebarMode = mode rightSidebarFocusState = .focused(mode: mode, target: .host) @@ -201,9 +195,6 @@ final class MainWindowFocusController { if dockHost?.ownsKeyboardFocus(responder) == true { return true } - if historyHost?.ownsKeyboardFocus(responder) == true { - return true - } return false } @@ -656,8 +647,6 @@ final class MainWindowFocusController { return focusFirstItem ? .firstItem : .host case .dock: return focusFirstItem ? .firstItem : .host - case .history: - return focusFirstItem ? .searchField : .host } } @@ -682,11 +671,6 @@ final class MainWindowFocusController { dockHost?.focusFirstItemFromCoordinator() } return dockHost?.focusHostFromCoordinator() == true - case .history: - if target == .searchField { - return historyHost?.focusSearchFromCoordinator() == true - } - return historyHost?.focusHostFromCoordinator() == true } } @@ -757,9 +741,6 @@ final class MainWindowFocusController { if dockHost?.ownsKeyboardFocus(responder) == true { return .dock } - if historyHost?.ownsKeyboardFocus(responder) == true { - return .history - } return nil } diff --git a/Sources/RightSidebarMode+Availability.swift b/Sources/RightSidebarMode+Availability.swift index 80b7c669020f..7886818e2a9d 100644 --- a/Sources/RightSidebarMode+Availability.swift +++ b/Sources/RightSidebarMode+Availability.swift @@ -13,8 +13,6 @@ extension RightSidebarMode { return .feed case "dock": return .dock - case "history": - return .history default: return nil } @@ -38,8 +36,6 @@ extension RightSidebarMode { return true case .dock: return dockEnabled - case .history: - return true } } } diff --git a/Sources/RightSidebarPanelView.swift b/Sources/RightSidebarPanelView.swift index ae2cffe7e828..c3f65c82cf85 100644 --- a/Sources/RightSidebarPanelView.swift +++ b/Sources/RightSidebarPanelView.swift @@ -15,7 +15,6 @@ nonisolated enum RightSidebarMode: String, CaseIterable, Codable, Sendable { case sessions case feed case dock - case history var label: String { switch self { @@ -24,7 +23,6 @@ nonisolated enum RightSidebarMode: String, CaseIterable, Codable, Sendable { case .sessions: return String(localized: "rightSidebar.mode.sessions", defaultValue: "Vault") case .feed: return String(localized: "rightSidebar.mode.feed", defaultValue: "Feed") case .dock: return String(localized: "rightSidebar.mode.dock", defaultValue: "Dock") - case .history: return String(localized: "rightSidebar.mode.history", defaultValue: "History") } } @@ -35,7 +33,6 @@ nonisolated enum RightSidebarMode: String, CaseIterable, Codable, Sendable { case .sessions: return "books.vertical" case .feed: return "dot.radiowaves.left.and.right" case .dock: return "dock.rectangle" - case .history: return "clock.arrow.circlepath" } } @@ -46,13 +43,12 @@ nonisolated enum RightSidebarMode: String, CaseIterable, Codable, Sendable { case .sessions: return .switchRightSidebarToSessions case .feed: return .switchRightSidebarToFeed case .dock: return .switchRightSidebarToDock - case .history: return .switchRightSidebarToHistory } } } extension RightSidebarMode { - static let paneModes: [RightSidebarMode] = [.files, .find, .sessions, .history] + static let paneModes: [RightSidebarMode] = [.files, .find, .sessions] var canOpenAsPane: Bool { Self.paneModes.contains(self) @@ -79,9 +75,6 @@ extension RightSidebarMode { RightSidebarMode.dock.isAvailable() { return .dock } - if KeyboardShortcutSettings.shortcut(for: .switchRightSidebarToHistory).matches(event: event) { - return .history - } return nil } } @@ -172,7 +165,6 @@ struct RightSidebarPanelView: View { } @State private var focusShortcutHintMonitor = WindowScopedShortcutHintModifierMonitor(activation: .commandOnly) @State private var closeShortcutHintMonitor = WindowScopedShortcutHintModifierMonitor(activation: .commandOnly) - @State private var historySearchFocusToken = 0 @StateObject private var dockStore = DockControlsStore() @ObservedObject private var keyboardShortcutSettingsObserver = KeyboardShortcutSettingsObserver.shared private let alwaysShowShortcutHints = ShortcutHintDebugSettings.alwaysShowHints() @@ -415,40 +407,6 @@ struct RightSidebarPanelView: View { FeedPanelView() case .dock: DockPanelView(rootDirectory: sessionIndexDirectory, workspaceId: workspaceId, store: dockStore) - case .history: - HistoryPanelView( - focusSearchToken: historySearchFocusToken, - onFocus: { - AppDelegate.shared?.noteRightSidebarKeyboardFocusIntent( - mode: .history, - in: NSApp.keyWindow ?? NSApp.mainWindow - ) - }, - onOpenClosedItem: { itemId in - AppDelegate.shared?.reopenClosedHistoryItem( - id: itemId, - preferredTabManager: tabManager - ) == true - }, - onOpenFocusedItem: { item in - tabManager.navigateToFocusHistoryMenuItem(item) - }, - onClearClosedItems: { - if let appDelegate = AppDelegate.shared { - appDelegate.clearRecentlyClosedHistory(preferredTabManager: tabManager) - } else { - ClosedItemHistoryStore.shared.removeAll() - tabManager.clearRecentlyClosedBrowserPanelHistory() - } - } - ) - .environmentObject(tabManager) - .background( - RightSidebarHistoryFocusBridge { - historySearchFocusToken &+= 1 - } - .frame(width: 0, height: 0) - ) } } @@ -481,81 +439,6 @@ struct RightSidebarPanelView: View { } } -private struct RightSidebarHistoryFocusBridge: NSViewRepresentable { - let onFocusSearch: () -> Void - - func makeNSView(context: Context) -> RightSidebarHistoryFocusAnchorView { - let view = RightSidebarHistoryFocusAnchorView() - view.onFocusSearch = onFocusSearch - return view - } - - func updateNSView(_ nsView: RightSidebarHistoryFocusAnchorView, context: Context) { - nsView.onFocusSearch = onFocusSearch - nsView.registerWithKeyboardFocusCoordinatorIfNeeded() - } - - static func dismantleNSView(_ nsView: RightSidebarHistoryFocusAnchorView, coordinator: ()) { - nsView.onFocusSearch = nil - } -} - -final class RightSidebarHistoryFocusAnchorView: NSView { - var onFocusSearch: (() -> Void)? - override var acceptsFirstResponder: Bool { true } - - override func viewDidMoveToWindow() { - super.viewDidMoveToWindow() - registerWithKeyboardFocusCoordinatorIfNeeded() - } - - func registerWithKeyboardFocusCoordinatorIfNeeded() { - guard let window else { return } - AppDelegate.shared?.keyboardFocusCoordinator(for: window)?.registerHistoryHost(self) - } - - func focusSearchFromCoordinator() -> Bool { - onFocusSearch?() - return focusHostFromCoordinator() - } - - func focusHostFromCoordinator() -> Bool { - guard let window else { return false } - return window.makeFirstResponder(self) - } - - func ownsKeyboardFocus(_ responder: NSResponder) -> Bool { - if responder === self { return true } - guard let responderView = Self.view(for: responder), - let root = focusRootView else { return false } - return responderView === root || responderView.isDescendant(of: root) - } - - private static func view(for responder: NSResponder) -> NSView? { - if let view = responder as? NSView { - return view - } - if let textView = responder as? NSTextView, - let delegateView = textView.delegate as? NSView { - return delegateView - } - return nil - } - - private var focusRootView: NSView? { - guard let superview else { return nil } - var current: NSView? = superview - while let view = current { - let typeName = String(describing: type(of: view)) - if typeName.contains("NSHosting") || typeName.contains("ViewHost") { - return view - } - current = view.superview - } - return superview - } -} - private struct RightSidebarKeyboardFocusBridge: NSViewRepresentable { func makeNSView(context: Context) -> RightSidebarKeyboardFocusView { let view = RightSidebarKeyboardFocusView(frame: NSRect(x: 0, y: 0, width: 1, height: 1)) diff --git a/Sources/RightSidebarToolPanel.swift b/Sources/RightSidebarToolPanel.swift index a5832f421dc2..979858f75d9c 100644 --- a/Sources/RightSidebarToolPanel.swift +++ b/Sources/RightSidebarToolPanel.swift @@ -9,12 +9,10 @@ final class RightSidebarToolPanel: Panel, ObservableObject { let mode: RightSidebarMode @Published private(set) var focusFlashToken: Int = 0 - @Published private(set) var historySearchFocusToken: Int = 0 private weak var workspace: Workspace? private weak var fileExplorerContainerView: FileExplorerContainerView? private weak var sessionIndexFocusAnchorView: RightSidebarToolFocusAnchorView? - private weak var historyFocusAnchorView: RightSidebarToolFocusAnchorView? private var fileExplorerStoreStorage: FileExplorerStore? private var fileExplorerStateStorage: FileExplorerState? private var sessionIndexStoreStorage: SessionIndexStore? @@ -75,10 +73,6 @@ final class RightSidebarToolPanel: Panel, ObservableObject { sessionIndexFocusAnchorView = anchor } - fileprivate func attachHistoryFocusAnchor(_ anchor: RightSidebarToolFocusAnchorView?) { - historyFocusAnchorView = anchor - } - func syncWorkspaceRoot(from workspace: Workspace) { switch mode { case .files, .find: @@ -87,7 +81,7 @@ final class RightSidebarToolPanel: Panel, ObservableObject { case .sessions: guard let store = sessionIndexStoreStorage else { return } syncSessionIndexRoot(from: workspace, store: store) - case .feed, .dock, .history: + case .feed, .dock: break } } @@ -112,7 +106,6 @@ final class RightSidebarToolPanel: Panel, ObservableObject { func close() { fileExplorerContainerView = nil sessionIndexFocusAnchorView = nil - historyFocusAnchorView = nil fileExplorerStoreStorage?.applyWorkspaceRoot(.none) sessionIndexStoreStorage?.setCurrentDirectoryIfChanged(nil) workspaceObservationCancellable = nil @@ -128,11 +121,6 @@ final class RightSidebarToolPanel: Panel, ObservableObject { guard let anchor = sessionIndexFocusAnchorView, let window = anchor.window else { return } _ = window.makeFirstResponder(anchor) - case .history: - historySearchFocusToken &+= 1 - guard let anchor = historyFocusAnchorView, - let window = anchor.window else { return } - _ = window.makeFirstResponder(anchor) case .feed, .dock: break } @@ -155,9 +143,6 @@ final class RightSidebarToolPanel: Panel, ObservableObject { case .sessions: guard sessionIndexFocusAnchorView?.ownsKeyboardFocus(responder) == true else { return nil } return .panel - case .history: - guard historyFocusAnchorView?.ownsKeyboardFocus(responder) == true else { return nil } - return .panel case .feed, .dock: return nil } @@ -284,32 +269,6 @@ struct RightSidebarToolPanelView: View { RightSidebarToolFocusAnchor(onViewChange: panel.attachSessionIndexFocusAnchor) .frame(width: 0, height: 0) ) - case .history: - HistoryPanelView( - focusSearchToken: panel.historySearchFocusToken, - onFocus: requestPanelFocusIfNeeded, - onOpenClosedItem: { itemId in - AppDelegate.shared?.reopenClosedHistoryItem( - id: itemId, - preferredTabManager: tabManager - ) == true - }, - onOpenFocusedItem: { item in - tabManager.navigateToFocusHistoryMenuItem(item) - }, - onClearClosedItems: { - if let appDelegate = AppDelegate.shared { - appDelegate.clearRecentlyClosedHistory(preferredTabManager: tabManager) - } else { - ClosedItemHistoryStore.shared.removeAll() - tabManager.clearRecentlyClosedBrowserPanelHistory() - } - } - ) - .background( - RightSidebarToolFocusAnchor(onViewChange: panel.attachHistoryFocusAnchor) - .frame(width: 0, height: 0) - ) case .feed, .dock: EmptyView() } diff --git a/Sources/SessionPersistence.swift b/Sources/SessionPersistence.swift index 4878dbeace03..279abc1840f5 100644 --- a/Sources/SessionPersistence.swift +++ b/Sources/SessionPersistence.swift @@ -1398,7 +1398,21 @@ struct SessionFilePreviewPanelSnapshot: Codable, Sendable { } struct SessionRightSidebarToolPanelSnapshot: Codable, Sendable { - var mode: RightSidebarMode + var mode: RightSidebarMode? + + init(mode: RightSidebarMode?) { + self.mode = mode + } + + private enum CodingKeys: String, CodingKey { + case mode + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let raw = try container.decodeIfPresent(String.self, forKey: .mode) + self.mode = raw.flatMap { RightSidebarMode(rawValue: $0) } + } } struct SessionNotificationSnapshot: Codable, Sendable { diff --git a/Sources/cmuxApp+HistoryMenu.swift b/Sources/cmuxApp+HistoryMenu.swift index 49c43cc1a3f7..ac283b1b55ef 100644 --- a/Sources/cmuxApp+HistoryMenu.swift +++ b/Sources/cmuxApp+HistoryMenu.swift @@ -39,8 +39,6 @@ extension cmuxApp { snapshot: recentlyClosedSnapshot ) - openFullHistoryButton(manager: historyTabManager) - Divider() splitCommandButton(title: String(localized: "menu.file.restorePreviousAppLaunch", defaultValue: "Restore Previous Launch"), shortcut: menuShortcut(for: .reopenPreviousSession)) { @@ -74,13 +72,6 @@ extension cmuxApp { } .disabled(!item.isNavigable) } - - if snapshot.isLimited { - openFullHistoryButton( - title: String(localized: "menu.history.showFullFocusHistory", defaultValue: "Show Full History"), - manager: manager - ) - } } } @@ -109,13 +100,6 @@ extension cmuxApp { } } } - - if snapshot.isLimited { - openFullHistoryButton( - title: String(localized: "menu.history.recentlyClosed.showFull", defaultValue: "Show Full Recently Closed"), - manager: manager - ) - } } } @@ -151,14 +135,4 @@ extension cmuxApp { ) } - private func openFullHistoryButton( - title: String = String(localized: "menu.history.openFullHistory", defaultValue: "Open Full History…"), - manager: TabManager - ) -> some View { - Button(title) { - if AppDelegate.shared?.openHistoryPane(preferredTabManager: manager) != true { - NSSound.beep() - } - } - } } diff --git a/cmux.xcodeproj/project.pbxproj b/cmux.xcodeproj/project.pbxproj index abd489cf1b1e..5755fed8cbcb 100644 --- a/cmux.xcodeproj/project.pbxproj +++ b/cmux.xcodeproj/project.pbxproj @@ -203,7 +203,6 @@ A5001003 /* TabManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5001013 /* TabManager.swift */; }; F0C05170000000000000002 /* FocusHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C05170000000000000001 /* FocusHistory.swift */; }; C10D51700000000000000002 /* ClosedItemHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10D51700000000000000001 /* ClosedItemHistory.swift */; }; - C10D51800000000000000002 /* HistoryPanelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10D51800000000000000001 /* HistoryPanelView.swift */; }; C3677003000000000000001 /* TabManager+CompatibilityTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3677003000000000000002 /* TabManager+CompatibilityTypes.swift */; }; D7AB00000000000000000013 /* TabManager+DetachedWorkspace.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7AB00000000000000000014 /* TabManager+DetachedWorkspace.swift */; }; D7AB00000000000000000015 /* Workspace+DetachedSurfaceTransfer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7AB00000000000000000016 /* Workspace+DetachedSurfaceTransfer.swift */; }; @@ -234,7 +233,6 @@ 2907A0012907A0012907A001 /* AppDelegate+RecoverableMainWindowRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2907A0022907A0022907A002 /* AppDelegate+RecoverableMainWindowRoutes.swift */; }; C4160A030000000000000001 /* AppDelegate+ClosedItemHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4160A030000000000000002 /* AppDelegate+ClosedItemHistory.swift */; }; C4160A040000000000000001 /* AppDelegate+FocusHistoryContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4160A040000000000000002 /* AppDelegate+FocusHistoryContextMenu.swift */; }; - C4160A050000000000000001 /* AppDelegate+HistoryPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4160A050000000000000002 /* AppDelegate+HistoryPane.swift */; }; C10D00010000000000000001 /* CloudVMActionLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10D00020000000000000002 /* CloudVMActionLauncher.swift */; }; A5001094 /* NotificationsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5001091 /* NotificationsPage.swift */; }; A5001095 /* TerminalNotificationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5001092 /* TerminalNotificationStore.swift */; }; @@ -758,7 +756,6 @@ A5001013 /* TabManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabManager.swift; sourceTree = ""; }; F0C05170000000000000001 /* FocusHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusHistory.swift; sourceTree = ""; }; C10D51700000000000000001 /* ClosedItemHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosedItemHistory.swift; sourceTree = ""; }; - C10D51800000000000000001 /* HistoryPanelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryPanelView.swift; sourceTree = ""; }; C3677003000000000000002 /* TabManager+CompatibilityTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TabManager+CompatibilityTypes.swift"; sourceTree = ""; }; E3309A04 /* TabManager+EqualizeSplits.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TabManager+EqualizeSplits.swift"; sourceTree = ""; }; E3309A0E /* SplitEqualizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitEqualizer.swift; sourceTree = ""; }; @@ -826,7 +823,6 @@ 2907A0022907A0022907A002 /* AppDelegate+RecoverableMainWindowRoutes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+RecoverableMainWindowRoutes.swift"; sourceTree = ""; }; C4160A030000000000000002 /* AppDelegate+ClosedItemHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+ClosedItemHistory.swift"; sourceTree = ""; }; C4160A040000000000000002 /* AppDelegate+FocusHistoryContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+FocusHistoryContextMenu.swift"; sourceTree = ""; }; - C4160A050000000000000002 /* AppDelegate+HistoryPane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+HistoryPane.swift"; sourceTree = ""; }; A5001091 /* NotificationsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsPage.swift; sourceTree = ""; }; A5001092 /* TerminalNotificationStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalNotificationStore.swift; sourceTree = ""; }; A5001097 /* TerminalNotificationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalNotificationPolicy.swift; sourceTree = ""; }; @@ -1357,7 +1353,6 @@ A5001013 /* TabManager.swift */, F0C05170000000000000001 /* FocusHistory.swift */, C10D51700000000000000001 /* ClosedItemHistory.swift */, - C10D51800000000000000001 /* HistoryPanelView.swift */, C3677003000000000000002 /* TabManager+CompatibilityTypes.swift */, E3309A04 /* TabManager+EqualizeSplits.swift */, E3309A0E /* SplitEqualizer.swift */, @@ -1447,7 +1442,6 @@ 2907A0022907A0022907A002 /* AppDelegate+RecoverableMainWindowRoutes.swift */, C4160A030000000000000002 /* AppDelegate+ClosedItemHistory.swift */, C4160A040000000000000002 /* AppDelegate+FocusHistoryContextMenu.swift */, - C4160A050000000000000002 /* AppDelegate+HistoryPane.swift */, C10D00020000000000000002 /* CloudVMActionLauncher.swift */, B37A00000000000000000006 /* MainWindowFocusTypes.swift */, 2F0C05000000000000000001 /* MainWindowFocusController.swift */, @@ -2128,7 +2122,6 @@ A5001003 /* TabManager.swift in Sources */, F0C05170000000000000002 /* FocusHistory.swift in Sources */, C10D51700000000000000002 /* ClosedItemHistory.swift in Sources */, - C10D51800000000000000002 /* HistoryPanelView.swift in Sources */, C3677003000000000000001 /* TabManager+CompatibilityTypes.swift in Sources */, E3309A03 /* TabManager+EqualizeSplits.swift in Sources */, E3309A0D /* SplitEqualizer.swift in Sources */, @@ -2221,7 +2214,6 @@ 2907A0012907A0012907A001 /* AppDelegate+RecoverableMainWindowRoutes.swift in Sources */, C4160A030000000000000001 /* AppDelegate+ClosedItemHistory.swift in Sources */, C4160A040000000000000001 /* AppDelegate+FocusHistoryContextMenu.swift in Sources */, - C4160A050000000000000001 /* AppDelegate+HistoryPane.swift in Sources */, C10D00010000000000000001 /* CloudVMActionLauncher.swift in Sources */, B37A00000000000000000005 /* MainWindowFocusTypes.swift in Sources */, 2F0C05000000000000000002 /* MainWindowFocusController.swift in Sources */, diff --git a/cmuxTests/FileExplorerStateModePersistenceTests.swift b/cmuxTests/FileExplorerStateModePersistenceTests.swift index bc4c8c991ab9..9aab0ee65f40 100644 --- a/cmuxTests/FileExplorerStateModePersistenceTests.swift +++ b/cmuxTests/FileExplorerStateModePersistenceTests.swift @@ -52,7 +52,6 @@ final class FileExplorerStateModePersistenceTests: XCTestCase { XCTAssertEqual(RightSidebarMode.from(cliArgument: "sessions"), .sessions) XCTAssertEqual(RightSidebarMode.from(cliArgument: "feed"), .feed) XCTAssertEqual(RightSidebarMode.from(cliArgument: "dock"), .dock) - XCTAssertEqual(RightSidebarMode.from(cliArgument: "history"), .history) XCTAssertEqual(RightSidebarMode.from(cliArgument: " Vault "), .sessions) XCTAssertNil(RightSidebarMode.from(cliArgument: "unknown")) } diff --git a/cmuxTests/RightSidebarCommandPaletteTests.swift b/cmuxTests/RightSidebarCommandPaletteTests.swift index ee54cc580d00..c98c8b991f2b 100644 --- a/cmuxTests/RightSidebarCommandPaletteTests.swift +++ b/cmuxTests/RightSidebarCommandPaletteTests.swift @@ -35,10 +35,9 @@ final class RightSidebarCommandPaletteTests: XCTestCase { XCTAssertTrue(contribution.enablement(context)) } - XCTAssertEqual(contributions.count, 5) + XCTAssertEqual(contributions.count, 4) XCTAssertNotNil(contributionsByID[ContentView.commandPaletteRightSidebarModeCommandID(.feed)]) XCTAssertNil(contributionsByID[ContentView.commandPaletteRightSidebarModeCommandID(.dock)]) - XCTAssertNotNil(contributionsByID[ContentView.commandPaletteRightSidebarModeCommandID(.history)]) } } @@ -58,14 +57,6 @@ final class RightSidebarCommandPaletteTests: XCTestCase { } } - func testCommandPaletteIncludesHistoryPaneCommand() throws { - let descriptors = ContentView.commandPaletteRightSidebarToolPaneCommandDescriptors() - let historyDescriptor = try XCTUnwrap(descriptors.first { $0.mode == .history }) - - XCTAssertEqual(historyDescriptor.commandId, "palette.openHistoryPane") - XCTAssertEqual(historyDescriptor.title, String(localized: "command.openHistoryPane.title", defaultValue: "Open History as Pane")) - } - func testCommandPaletteUnreadActionsUseConfigurableShortcutActions() { XCTAssertEqual( ContentView.commandPaletteShortcutAction(forCommandID: "palette.toggleUnread"), diff --git a/cmuxTests/ShortcutAndCommandPaletteTests.swift b/cmuxTests/ShortcutAndCommandPaletteTests.swift index bac5af718918..762d733d4b16 100644 --- a/cmuxTests/ShortcutAndCommandPaletteTests.swift +++ b/cmuxTests/ShortcutAndCommandPaletteTests.swift @@ -1092,7 +1092,6 @@ final class RightSidebarModeShortcutHintTests: XCTestCase { .switchRightSidebarToSessions, .switchRightSidebarToFeed, .switchRightSidebarToDock, - .switchRightSidebarToHistory, ] private var originalSettingsFileStore: KeyboardShortcutSettingsFileStore! private var savedShortcutData: [KeyboardShortcutSettings.Action: Data?] = [:] @@ -1144,7 +1143,6 @@ final class RightSidebarModeShortcutHintTests: XCTestCase { XCTAssertEqual(RightSidebarMode.sessions.shortcutAction, .switchRightSidebarToSessions) XCTAssertEqual(RightSidebarMode.feed.shortcutAction, .switchRightSidebarToFeed) XCTAssertEqual(RightSidebarMode.dock.shortcutAction, .switchRightSidebarToDock) - XCTAssertEqual(RightSidebarMode.history.shortcutAction, .switchRightSidebarToHistory) } func testModeShortcutsUsePrivateControlDigitDefaults() { @@ -1168,10 +1166,6 @@ final class RightSidebarModeShortcutHintTests: XCTestCase { RightSidebarMode.modeShortcut(for: makeKeyDownEvent(key: "5", modifiers: [.control], keyCode: 23)), .dock ) - XCTAssertEqual( - RightSidebarMode.modeShortcut(for: makeKeyDownEvent(key: "6", modifiers: [.control], keyCode: 22)), - .history - ) } func testModeShortcutUsesConfiguredBindings() { @@ -1229,10 +1223,6 @@ final class RightSidebarModeShortcutHintTests: XCTestCase { RightSidebarMode.modeShortcut(for: makeKeyDownEvent(key: "5", modifiers: [.control], keyCode: 23)), .dock ) - XCTAssertEqual( - RightSidebarMode.modeShortcut(for: makeKeyDownEvent(key: "6", modifiers: [.control], keyCode: 22)), - .history - ) } func testFocusRightSidebarShortcutCanBeOverwrittenForHintRendering() { @@ -1417,46 +1407,6 @@ final class MainWindowFocusControllerRightSidebarHideTests: XCTestCase { XCTAssertTrue(window.firstResponder === focusHost) } - @MainActor - func testPendingHistoryFocusCompletesWhenHistorySearchHostRegisters() { - let fileExplorerState = FileExplorerState() - let window = NSWindow( - contentRect: NSRect(x: 0, y: 0, width: 240, height: 180), - styleMask: [.titled], - backing: .buffered, - defer: false - ) - let contentView = NSView(frame: window.contentView?.bounds ?? .zero) - window.contentView = contentView - let controller = MainWindowFocusController( - windowId: UUID(), - window: window, - tabManager: TabManager(), - fileExplorerState: fileExplorerState - ) - - XCTAssertTrue(controller.focusRightSidebar(mode: .history, focusFirstItem: true)) - XCTAssertEqual(controller.debugPendingRightSidebarFocusMode, .history) - - var searchFocusRequests = 0 - let focusHost = RightSidebarHistoryFocusAnchorView(frame: NSRect(x: 0, y: 0, width: 24, height: 24)) - focusHost.onFocusSearch = { - searchFocusRequests += 1 - } - defer { - _ = window.makeFirstResponder(nil) - focusHost.removeFromSuperview() - window.contentView = nil - window.orderOut(nil) - } - contentView.addSubview(focusHost) - controller.registerHistoryHost(focusHost) - - XCTAssertNil(controller.debugPendingRightSidebarFocusMode) - XCTAssertTrue(window.firstResponder === focusHost) - XCTAssertEqual(searchFocusRequests, 1) - } - @MainActor func testFocusShortcutToggleClearsRightSidebarIntentWhenTerminalIsUnavailable() { let controller = MainWindowFocusController( diff --git a/cmuxTests/TabManagerSessionSnapshotTests.swift b/cmuxTests/TabManagerSessionSnapshotTests.swift index ef4584021970..b5554f8e5853 100644 --- a/cmuxTests/TabManagerSessionSnapshotTests.swift +++ b/cmuxTests/TabManagerSessionSnapshotTests.swift @@ -1118,26 +1118,10 @@ final class TabManagerSessionSnapshotTests: XCTestCase { XCTAssertTrue(item.menuSubtitle.contains(String(localized: "menu.history.recentlyClosed.kind.tab", defaultValue: "Tab"))) } - func testHistorySearchMatchesAcrossTitleAndKind() { - XCTAssertTrue(HistoryDayGrouping.matches(query: "timed tab", fields: ["Timed Panel", "Tab"])) - XCTAssertTrue(HistoryDayGrouping.matches(query: "workspace", fields: ["Recovered", "Workspace"])) - XCTAssertFalse(HistoryDayGrouping.matches(query: "browser", fields: ["Timed Panel", "Tab"])) - } - - func testHistoryDayGroupingLabelsTodayAndYesterday() throws { - var calendar = Calendar(identifier: .gregorian) - calendar.timeZone = try XCTUnwrap(TimeZone(secondsFromGMT: 0)) - let now = Date(timeIntervalSince1970: 1_700_000_000) - let yesterday = try XCTUnwrap(calendar.date(byAdding: .day, value: -1, to: now)) - - XCTAssertEqual( - HistoryDayGrouping.dayTitle(for: now, now: now, calendar: calendar), - String(localized: "historyPane.day.today", defaultValue: "Today") - ) - XCTAssertEqual( - HistoryDayGrouping.dayTitle(for: yesterday, now: now, calendar: calendar), - String(localized: "historyPane.day.yesterday", defaultValue: "Yesterday") - ) + func testRightSidebarToolSnapshotTolerantlyDecodesObsoleteHistoryMode() throws { + let json = #"{"mode":"history"}"#.data(using: .utf8)! + let snapshot = try JSONDecoder().decode(SessionRightSidebarToolPanelSnapshot.self, from: json) + XCTAssertNil(snapshot.mode) } func testReopenSpecificRecentlyClosedRowRestoresOnlyThatRecord() throws { diff --git a/cmuxTests/WorkspaceUnitTests.swift b/cmuxTests/WorkspaceUnitTests.swift index 65fcb719c45f..1d4fbf9f7b06 100644 --- a/cmuxTests/WorkspaceUnitTests.swift +++ b/cmuxTests/WorkspaceUnitTests.swift @@ -423,7 +423,6 @@ final class WorkspaceRenameShortcutDefaultsTests: XCTestCase { (.switchRightSidebarToSessions, "3"), (.switchRightSidebarToFeed, "4"), (.switchRightSidebarToDock, "5"), - (.switchRightSidebarToHistory, "6"), ] for (action, key) in modeSwitchActions { @@ -992,8 +991,7 @@ final class KeyboardShortcutSettingsFileStoreTests: XCTestCase { "switchRightSidebarToFind": "ctrl+5", "switchRightSidebarToSessions": "ctrl+6", "switchRightSidebarToFeed": "ctrl+7", - "switchRightSidebarToDock": "ctrl+8", - "switchRightSidebarToHistory": "ctrl+9" + "switchRightSidebarToDock": "ctrl+8" } } """, @@ -1030,10 +1028,6 @@ final class KeyboardShortcutSettingsFileStoreTests: XCTestCase { store.override(for: .switchRightSidebarToDock), StoredShortcut(key: "8", command: false, shift: false, option: false, control: true) ) - XCTAssertEqual( - store.override(for: .switchRightSidebarToHistory), - StoredShortcut(key: "9", command: false, shift: false, option: false, control: true) - ) } func testSettingsFileStoreParsesWorkspaceWorkingDirectoryInheritanceSetting() throws { @@ -5097,45 +5091,6 @@ final class WorkspacePanelGitBranchTests: XCTestCase { XCTAssertEqual(workspace.focusedPanelId, firstPanel.id) } - func testHistoryToolSurfaceOpensAsReusableBonsplitPane() { - let workspace = Workspace() - guard let paneId = workspace.bonsplitController.focusedPaneId else { - XCTFail("Expected focused pane") - return - } - - guard let firstPanel = workspace.openOrFocusRightSidebarToolSurface( - inPane: paneId, - mode: .history, - focus: true - ) else { - XCTFail("Expected History tool surface to be created") - return - } - guard let secondPanel = workspace.openOrFocusRightSidebarToolSurface( - inPane: paneId, - mode: .history, - focus: true - ) else { - XCTFail("Expected existing History tool surface to be focused") - return - } - - XCTAssertEqual(firstPanel.id, secondPanel.id) - XCTAssertEqual(firstPanel.displayTitle, String(localized: "rightSidebar.mode.history", defaultValue: "History")) - XCTAssertEqual(firstPanel.displayIcon, "clock.arrow.circlepath") - XCTAssertGreaterThanOrEqual(firstPanel.historySearchFocusToken, 1) - XCTAssertEqual( - workspace.surfaceIdFromPanelId(firstPanel.id).flatMap { workspace.bonsplitController.tab($0)?.kind }, - Workspace.SurfaceKind.rightSidebarTool - ) - XCTAssertEqual(workspace.focusedPanelId, firstPanel.id) - - let previousFocusToken = firstPanel.historySearchFocusToken - workspace.focusPanel(firstPanel.id) - XCTAssertGreaterThan(firstPanel.historySearchFocusToken, previousFocusToken) - } - func testClosingFocusedSplitRestoresBranchForRemainingFocusedPanel() { let workspace = Workspace() guard let firstPanelId = workspace.focusedPanelId else { diff --git a/web/data/cmux.schema.json b/web/data/cmux.schema.json index 04beff841c79..75fc183b787d 100644 --- a/web/data/cmux.schema.json +++ b/web/data/cmux.schema.json @@ -949,7 +949,6 @@ "switchRightSidebarToSessions", "switchRightSidebarToFeed", "switchRightSidebarToDock", - "switchRightSidebarToHistory", "triggerFlash", "nextSurface", "prevSurface",