Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions Sources/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,11 @@ struct ContentView: View {
@State private var commandPalettePendingActivation: CommandPalettePendingActivation?
@State private var commandPaletteResultsRevision: UInt64 = 0
@State private var commandPaletteUsageHistoryByCommandId: [String: CommandPaletteUsageEntry] = [:]
@State private var commandPaletteCommandSubmenu: CommandPaletteCommandSubmenu?
@State private var commandPaletteGhosttyThemeNames: [String] = []
@State private var commandPaletteGhosttyResolvedCurrentTheme: String?
@State private var commandPaletteGhosttyThemesAreLoading = false
@State private var commandPaletteGhosttyThemeLoadTask: Task<Void, Never>?
@State private var isFeedbackComposerPresented = false
@AppStorage(CommandPaletteRenameSelectionSettings.selectAllOnFocusKey)
private var commandPaletteRenameSelectAllOnFocus = CommandPaletteRenameSelectionSettings.defaultSelectAllOnFocus
Expand All @@ -1340,6 +1345,10 @@ struct ContentView: View {
@FocusState private var isCommandPaletteSearchFocused: Bool
@FocusState private var isCommandPaletteRenameFocused: Bool

private enum CommandPaletteCommandSubmenu {
case ghosttyThemes
}

private enum CommandPaletteMode {
case commands
case renameInput(CommandPaletteRenameTarget)
Expand Down Expand Up @@ -3097,6 +3106,14 @@ struct ContentView: View {
resetCommandPaletteSearchFocus()
}
.onChange(of: commandPaletteQuery) { _ in
if !commandPaletteQuery.hasPrefix(Self.commandPaletteCommandsPrefix) {
commandPaletteCommandSubmenu = nil
commandPaletteGhosttyThemeLoadTask?.cancel()
commandPaletteGhosttyThemeLoadTask = nil
commandPaletteGhosttyThemeNames = []
commandPaletteGhosttyResolvedCurrentTheme = nil
commandPaletteGhosttyThemesAreLoading = false
}
commandPaletteSelectedResultIndex = 0
commandPaletteSelectionAnchorCommandID = nil
commandPaletteHoveredResultIndex = nil
Expand Down Expand Up @@ -3247,6 +3264,9 @@ struct ContentView: View {
private var commandPaletteSearchPlaceholder: String {
switch commandPaletteListScope {
case .commands:
if commandPaletteCommandSubmenu == .ghosttyThemes {
return String(localized: "commandPalette.search.ghosttyThemesPlaceholder", defaultValue: "Search Ghostty themes")
}
return String(localized: "commandPalette.search.commandsPlaceholder", defaultValue: "Type a command")
case .switcher:
return String(localized: "commandPalette.search.switcherPlaceholder", defaultValue: "Search workspaces")
Expand All @@ -3256,6 +3276,9 @@ struct ContentView: View {
private var commandPaletteEmptyStateText: String {
switch commandPaletteListScope {
case .commands:
if commandPaletteCommandSubmenu == .ghosttyThemes {
return String(localized: "commandPalette.search.ghosttyThemesEmpty", defaultValue: "No Ghostty themes match your search.")
}
return String(localized: "commandPalette.search.commandsEmpty", defaultValue: "No commands match your search.")
case .switcher:
return String(localized: "commandPalette.search.switcherEmpty", defaultValue: "No workspaces match your search.")
Expand Down Expand Up @@ -3837,6 +3860,10 @@ struct ContentView: View {
}

private func commandPaletteCommands() -> [CommandPaletteCommand] {
if commandPaletteCommandSubmenu == .ghosttyThemes {
return commandPaletteGhosttyThemeCommands()
}

let context = commandPaletteContextSnapshot()
let contributions = commandPaletteCommandContributions()
var handlerRegistry = CommandPaletteHandlerRegistry()
Expand Down Expand Up @@ -3870,6 +3897,146 @@ struct ContentView: View {
return commands
}

private func commandPaletteGhosttyThemeCommands() -> [CommandPaletteCommand] {
let currentTheme = commandPaletteGhosttyResolvedCurrentTheme
let themes = commandPaletteGhosttyThemeNames
var commands: [CommandPaletteCommand] = []
commands.reserveCapacity(max(2, themes.count + 1))

commands.append(
CommandPaletteCommand(
id: "palette.ghosttyTheme.back",
rank: 0,
title: String(localized: "command.ghosttyTheme.back.title", defaultValue: "Back"),
subtitle: String(localized: "command.ghosttyTheme.back.subtitle", defaultValue: "Ghostty Themes"),
shortcutHint: nil,
keywords: ["back", "theme", "ghostty"],
dismissOnRun: false,
action: { exitCommandPaletteGhosttyThemeMenu() }
)
)

if commandPaletteGhosttyThemesAreLoading && themes.isEmpty {
commands.append(
CommandPaletteCommand(
id: "palette.ghosttyTheme.loading",
rank: 1,
title: String(localized: "command.ghosttyTheme.loading.title", defaultValue: "Loading Ghostty themes…"),
subtitle: String(localized: "command.ghosttyTheme.loading.subtitle", defaultValue: "Ghostty Theme"),
shortcutHint: nil,
keywords: ["loading", "theme", "ghostty"],
dismissOnRun: false,
action: {}
)
)
return commands
Comment on lines +3906 to +3932

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep submenu chrome out of the searchable result set.

Because Back and the loading sentinel are emitted as normal commands, typing a non-matching query during discovery can hide both rows and render the Ghostty empty state even though loading is still in progress. Pin those rows outside fuzzy search, or suppress the empty state while commandPaletteGhosttyThemesAreLoading is true.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/ContentView.swift` around lines 3906 - 3932, The Back and loading
sentinel commands ("palette.ghosttyTheme.back" and
"palette.ghosttyTheme.loading") are being added as normal searchable items which
allows a non-matching query to hide them and show an empty Ghostty state; change
the builder so these two entries are not subject to fuzzy filtering: either (A)
add the Back command and the loading sentinel after you run the query filter
(i.e., append them to the commands array post-filter) so they always appear
regardless of the search term, or (B) tag them as non-searchable/alwaysVisible
(e.g., set an isSearchable=false or alwaysVisible flag) and ensure the filtering
logic skips items with that flag; use the existing identifiers
commandPaletteGhosttyThemesAreLoading, themes,
exitCommandPaletteGhosttyThemeMenu(), and the command IDs above to locate where
to modify the append/filter logic and ensure the empty-state is suppressed while
commandPaletteGhosttyThemesAreLoading is true.

}

for (index, themeName) in themes.enumerated() {
let isCurrentTheme = currentTheme?.localizedCaseInsensitiveCompare(themeName) == .orderedSame

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✓ indicator never fires for light/dark variant themes

GhosttyConfig.load().theme returns the raw config value exactly as written in the file (e.g. "light:Nord,dark:Nord Dark"). The comparison against individual theme names like "Nord" will always be false for any user whose config uses the light:X,dark:Y variant syntax, so the ✓ indicator will never show for those users.

The fix is to resolve the raw value through GhosttyConfig.resolveThemeName before comparing:

let resolvedTheme = currentTheme.flatMap { raw in
    GhosttyConfig.resolveThemeName(
        from: raw,
        preferredColorScheme: GhosttyConfig.currentColorSchemePreference()
    )
}
let isCurrentTheme = resolvedTheme?.localizedCaseInsensitiveCompare(themeName) == .orderedSame

Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Resolved
commands.append(
CommandPaletteCommand(
id: commandPaletteGhosttyThemeCommandID(for: themeName),
rank: index + 1,
title: isCurrentTheme
? String(localized: "command.ghosttyTheme.current.title", defaultValue: "\(themeName) ✓")
: themeName,
subtitle: String(localized: "command.ghosttyTheme.subtitle", defaultValue: "Ghostty Theme"),
shortcutHint: nil,
keywords: ["theme", "ghostty", "appearance", themeName],
dismissOnRun: true,
action: { applyGhosttyThemeFromPalette(themeName) }
)
)
}

return commands
}

private func enterCommandPaletteGhosttyThemeMenu() {
commandPaletteCommandSubmenu = .ghosttyThemes
commandPaletteQuery = Self.commandPaletteCommandsPrefix
commandPaletteSelectedResultIndex = 0
commandPaletteSelectionAnchorCommandID = nil
refreshCommandPaletteGhosttyThemeData(force: true)
scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh: true)
Comment on lines +3977 to +3978

@coderabbitai coderabbitai Bot Mar 10, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Honor forceSearchCorpusRefresh with a synchronous seed.

These forced Ghostty submenu refreshes still stay in the .commands scope, so scheduleCommandPaletteResultsRefresh can reuse the previous commands preview path and briefly render [] or only Back before the detached search finishes. That makes the submenu flash blank/partial content instead of immediately showing Back/Loading or the loaded theme rows.

💡 Minimal fix
 private func scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh: Bool = false) {
     refreshCommandPaletteSearchCorpus(force: forceSearchCorpusRefresh)
@@
     commandPalettePendingActivation = nil
     cancelCommandPaletteSearch()
-    if Self.commandPaletteShouldSynchronouslySeedResults(
+    if forceSearchCorpusRefresh || Self.commandPaletteShouldSynchronouslySeedResults(
         hasVisibleResultsForScope: commandPaletteVisibleResultsScope == scope
     ) {
         let matches = Self.commandPaletteResolvedSearchMatches(
             searchCorpus: searchCorpus,
             query: query,

Also applies to: 4058-4060

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/ContentView.swift` around lines 3977 - 3978, The forced refresh path
is not seeding the command-preview synchronously, so
scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh: true) can still
render an empty/partial commands view; ensure that when forceSearchCorpusRefresh
is true you perform a synchronous seed/update of the command-preview path before
returning. Concretely: in the call-site where
refreshCommandPaletteGhosttyThemeData(force: true) and
scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh: true) are
invoked, make the seed of the commands preview happen synchronously (either by
calling the sync seeding helper or adding a synchronous code path in
scheduleCommandPaletteResultsRefresh keyed on forceSearchCorpusRefresh) so the
commands preview path is updated immediately (so UI shows Back/Loading or loaded
rows instead of []). Target the functions refreshCommandPaletteGhosttyThemeData
and scheduleCommandPaletteResultsRefresh and ensure forceSearchCorpusRefresh
triggers immediate seeding on the main actor/thread before any async detached
search runs.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on the UX flash — this is a valid observation. However, I'm intentionally not addressing this in this PR for the following reasons:

  1. Scope: The suggested fix modifies scheduleCommandPaletteResultsRefresh, which is shared infrastructure used by every command palette submenu, not just the Ghostty theme picker. Changing the synchronous seeding logic there to key off forceSearchCorpusRefresh alters the rendering behavior for all submenus that pass that flag — a change with broader blast radius than this feature PR warrants.

  2. Pre-existing behavior: The "brief flash" pattern is how all existing submenus behave today when entered with forceSearchCorpusRefresh: true. The theme submenu follows the same established contract. Fixing it in isolation for themes would be inconsistent; fixing it globally should be a deliberate, separately tested change.

  3. Risk vs. reward: The flash is sub-frame in practice (the sync corpus refresh happens on the same main actor call, so the search corpus is already populated before the detached search kicks off). The actual visible flicker, if any, is masked by the loading state we already display. Adding forceSearchCorpusRefresh as a sync-seed trigger could cause unintended double-renders in other submenu flows.

Will track this as a follow-up UX polish item. Thanks for the thorough analysis.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@debgotwired Thanks for the context and rationale — agreed on deferring this from the feature PR given the shared nature of scheduleCommandPaletteResultsRefresh.

If helpful, I can open a follow‑up issue that scopes a global, low‑risk improvement across all submenus. Proposed acceptance criteria:

  • On forceSearchCorpusRefresh: true, the command list seeds synchronously with the up‑to‑date corpus before any detached search runs, so the first paint shows stable rows (e.g., Back + Loading or actual items) without a transient empty state.
  • No regression to selection anchoring, pending activations, or requestID gating.
  • Covered with a test that enters a submenu and asserts the first visible result set is non‑empty when loading is in progress.

Optionally, the solution could be:

  • Either a new seed mode in scheduleCommandPaletteResultsRefresh (defaulting to current behavior) to keep backwards compatibility, or
  • A small helper that synchronously materializes preview results from the refreshed corpus before kicking off the async search, used by all call sites that do a forced refresh.

Would you like me to file that issue and assign it to you?


✏️ Learnings added
Learnt from: debgotwired
Repo: manaflow-ai/cmux PR: 1149
File: Sources/ContentView.swift:3977-3978
Timestamp: 2026-03-10T09:33:29.814Z
Learning: In manaflow-ai/cmux (Sources/ContentView.swift), scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh:) is shared command‑palette infrastructure across all submenus. Do not change its sync‑seeding behavior within feature‑scoped PRs; treat brief initial flashes as consistent with existing submenus. Any UX improvement (e.g., synchronous seeding on forced corpus refresh) should be implemented and tested globally in a dedicated follow‑up PR.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: atani
Repo: manaflow-ai/cmux PR: 819
File: Sources/ContentView.swift:3194-3196
Timestamp: 2026-03-04T14:05:48.668Z
Learning: In manaflow-ai/cmux (PR `#819`), Sources/ContentView.swift: The command palette’s external window labels intentionally use the global window index from the full orderedSummaries (index + 1), matching the Window menu in AppDelegate. Do not reindex after filtering out the current window to avoid mismatches (“Window 2” for an external window is expected).

Learnt from: apollow
Repo: manaflow-ai/cmux PR: 1089
File: Sources/ContentView.swift:6055-6057
Timestamp: 2026-03-09T02:09:08.742Z
Learning: In manaflow-ai/cmux (Sources/ContentView.swift), within CommandPaletteSwitcherSearchIndexer.metadataKeywordsForSearch(_:detail:), when tags are present, only add "tag" and "topic" to contextKeywords; do not append "claude" unconditionally to avoid false-positive switcher matches.

Learnt from: CR
Repo: manaflow-ai/cmux PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-05T00:05:51.436Z
Learning: Applies to **/GhosttyTerminalView.swift : `SurfaceSearchOverlay` must be mounted from `GhosttySurfaceScrollView` in `Sources/GhosttyTerminalView.swift` (AppKit portal layer), not from SwiftUI panel containers such as `Sources/Panels/TerminalPanelView.swift`

Learnt from: atani
Repo: manaflow-ai/cmux PR: 819
File: Sources/AppDelegate.swift:3491-3493
Timestamp: 2026-03-04T14:06:16.241Z
Learning: For manaflow-ai/cmux PR `#819` (Japanese i18n), keep scope limited to localization changes; UX enhancements like preferring workspace.customTitle in workspaceDisplayName() or altering move-target labels should be handled in a separate follow-up issue.

Learnt from: atani
Repo: manaflow-ai/cmux PR: 819
File: Sources/AppDelegate.swift:0-0
Timestamp: 2026-03-04T14:05:42.574Z
Learning: Guideline: In Swift files (cmux project), when handling pluralized strings, prefer using localization keys with the ICU-style plural forms .one and .other. For example, use keys like statusMenu.unreadCount.one for the singular case (1) and statusMenu.unreadCount.other for all other counts, and similarly for statusMenu.tooltip.unread.one/other. Rationale: ensures correct pluralization across locales and makes localization keys explicit. Review code to ensure any unread count strings and related tooltips follow this .one/.other key pattern and verify the correct value is chosen based on the count.

Learnt from: austinywang
Repo: manaflow-ai/cmux PR: 954
File: Sources/TerminalController.swift:0-0
Timestamp: 2026-03-05T22:04:34.712Z
Learning: Adopt the convention: for health/telemetry tri-state values in Swift, prefer Optionals (Bool?) over sentinel booleans. In TerminalController.swift, socketConnectable is Bool? and only set when socketProbePerformed is true; downstream logic must treat nil as 'not probed'. Ensure downstream code checks for nil before using a value and uses explicit non-nil checks to determine state, improving clarity and avoiding misinterpretation of default false.

Learnt from: moyashin63
Repo: manaflow-ai/cmux PR: 1074
File: Sources/AppDelegate.swift:7523-7545
Timestamp: 2026-03-09T01:38:24.337Z
Learning: When the command palette is visible (as in manaflow-ai/cmux Sources/AppDelegate.swift), ensure the shortcut handling consumes most Command shortcuts to protect the palette's text input. Specifically, do not allow UI zoom shortcuts (Cmd+Shift+= / Cmd+Shift+− / Cmd+Shift+0) to trigger while the palette is open. Do not reorder shortcut handlers (e.g., uiZoomShortcutAction(...)) to bypass this guard; users must close the palette before performing zoom actions. This guideline should apply to Swift source files handling global shortcuts within the app.

resetCommandPaletteSearchFocus()
syncCommandPaletteDebugStateForObservedWindow()
}

private func exitCommandPaletteGhosttyThemeMenu() {
commandPaletteCommandSubmenu = nil
commandPaletteGhosttyThemeLoadTask?.cancel()
commandPaletteGhosttyThemeLoadTask = nil
commandPaletteGhosttyThemeNames = []
commandPaletteGhosttyResolvedCurrentTheme = nil
commandPaletteGhosttyThemesAreLoading = false
commandPaletteQuery = Self.commandPaletteCommandsPrefix
commandPaletteSelectedResultIndex = 0
commandPaletteSelectionAnchorCommandID = nil
scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh: true)
resetCommandPaletteSearchFocus()
syncCommandPaletteDebugStateForObservedWindow()
}

private func applyGhosttyThemeFromPalette(_ themeName: String) {
do {
try GhosttyConfig.applyTheme(
themeName,
preferredColorScheme: GhosttyConfig.currentColorSchemePreference()
)
GhosttyConfig.invalidateLoadCache()
commandPaletteGhosttyResolvedCurrentTheme = themeName
GhosttyApp.shared.reloadConfiguration(source: "commandPalette.ghosttyTheme")
} catch {
NSSound.beep()
NSLog(
"commandPalette.ghosttyTheme.apply failed theme=%@ error=%@",
themeName,
error.localizedDescription
)
}
}

private func refreshCommandPaletteGhosttyThemeData(force: Bool = false) {
if !force,
(!commandPaletteGhosttyThemeNames.isEmpty || commandPaletteGhosttyThemesAreLoading) {
return
}

commandPaletteGhosttyThemeLoadTask?.cancel()
commandPaletteGhosttyThemesAreLoading = true
commandPaletteGhosttyThemeLoadTask = Task.detached(priority: .userInitiated) {
let preferredColorScheme = GhosttyConfig.currentColorSchemePreference()
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Resolved
let resolvedCurrentTheme = (
GhosttyConfig.load(useCache: false).theme.map {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Read AppKit appearance on the main actor

This detached background task calls GhosttyConfig.currentColorSchemePreference(), which reads NSApp?.effectiveAppearance (AppKit UI state), and GhosttyConfig.load(useCache: false) also defaults through that same path when no scheme is passed. Calling AppKit appearance APIs off-main can trigger thread-safety violations and intermittently resolve the wrong active variant; capture the color scheme on the main actor before launching the detached work and pass it through explicitly.

Useful? React with 👍 / 👎.

GhosttyConfig.resolveThemeName(
from: $0,
preferredColorScheme: preferredColorScheme
)
}
)?.trimmingCharacters(in: .whitespacesAndNewlines)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
let themes = GhosttyConfig.discoverThemeNames()

guard !Task.isCancelled else { return }

await MainActor.run {
guard commandPaletteCommandSubmenu == .ghosttyThemes else { return }
commandPaletteGhosttyThemeNames = themes
commandPaletteGhosttyResolvedCurrentTheme = resolvedCurrentTheme
commandPaletteGhosttyThemesAreLoading = false
commandPaletteGhosttyThemeLoadTask = nil
scheduleCommandPaletteResultsRefresh(forceSearchCorpusRefresh: true)
syncCommandPaletteDebugStateForObservedWindow()
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}
}
}

private func commandPaletteGhosttyThemeCommandID(for themeName: String) -> String {
let encoded = themeName.utf8.map { String(format: "%02x", $0) }.joined()
return "palette.ghosttyTheme.\(encoded)"
}

private func commandPaletteShortcutHint(
for contribution: CommandPaletteCommandContribution,
context: CommandPaletteContextSnapshot
Expand Down Expand Up @@ -4355,6 +4522,15 @@ struct ContentView: View {
)
)

contributions.append(
CommandPaletteCommandContribution(
commandId: "palette.ghosttyThemeMenu",
title: constant(String(localized: "command.ghosttyThemeMenu.title", defaultValue: "Ghostty Theme…")),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add new Ghostty menu keys to localization catalog

Per /workspace/cmux/AGENTS.md, all user-facing strings must be localized in Resources/Localizable.xcstrings for supported languages, but this commit introduces new keys (for example command.ghosttyThemeMenu.title) without adding catalog entries. I checked the catalog in this commit and these keys are absent, so the new Ghostty theme palette UI falls back to English instead of localized text.

Useful? React with 👍 / 👎.

subtitle: constant(String(localized: "command.ghosttyThemeMenu.subtitle", defaultValue: "Appearance")),
keywords: ["theme", "ghostty", "appearance", "color", "terminal"],
dismissOnRun: false
)
)
contributions.append(
CommandPaletteCommandContribution(
commandId: "palette.openWorkspacePullRequests",
Expand Down Expand Up @@ -4647,6 +4823,9 @@ struct ContentView: View {
}

private func registerCommandPaletteHandlers(_ registry: inout CommandPaletteHandlerRegistry) {
registry.register(commandId: "palette.ghosttyThemeMenu") {
enterCommandPaletteGhosttyThemeMenu()
}
registry.register(commandId: "palette.newWorkspace") {
tabManager.addWorkspace()
}
Expand Down Expand Up @@ -5403,6 +5582,12 @@ struct ContentView: View {

private func resetCommandPaletteListState(initialQuery: String) {
commandPaletteMode = .commands
commandPaletteCommandSubmenu = nil
commandPaletteGhosttyThemeLoadTask?.cancel()
commandPaletteGhosttyThemeLoadTask = nil
commandPaletteGhosttyThemeNames = []
commandPaletteGhosttyResolvedCurrentTheme = nil
commandPaletteGhosttyThemesAreLoading = false
commandPaletteQuery = initialQuery
commandPaletteRenameDraft = ""
commandPaletteSelectedResultIndex = 0
Expand All @@ -5428,6 +5613,12 @@ struct ContentView: View {
commandPaletteSearchRequestID &+= 1
isCommandPalettePresented = false
commandPaletteMode = .commands
commandPaletteCommandSubmenu = nil
commandPaletteGhosttyThemeLoadTask?.cancel()
commandPaletteGhosttyThemeLoadTask = nil
commandPaletteGhosttyThemeNames = []
commandPaletteGhosttyResolvedCurrentTheme = nil
commandPaletteGhosttyThemesAreLoading = false
commandPaletteQuery = ""
commandPaletteRenameDraft = ""
commandPaletteSelectedResultIndex = 0
Expand Down
Loading