diff options
| author | Igor Soarez <igor@soarez.org> | 2026-10-19 19:14:17 +0300 |
|---|---|---|
| committer | Igor Soarez <igor@soarez.org> | 2026-10-19 19:14:17 +0300 |
| commit | 7081a103443bafa28d902529d502a89c2dccb79a (patch) | |
| tree | c0c49b3f78730169f971088abff5312e2f10ab7f /menubar | |
| parent | ea1dda2f056fdfd56bffe8b978c0b0786b82aa7d (diff) | |
menu rows show window names, not indexes
display target is session:window-name (pane index only when split);
switching keeps using the pane id. add --print debug mode to inspect the
rendered rows without opening the menu.
Diffstat (limited to 'menubar')
| -rw-r--r-- | menubar/main.swift | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/menubar/main.swift b/menubar/main.swift index 71bba46..b5a3059 100644 --- a/menubar/main.swift +++ b/menubar/main.swift @@ -70,20 +70,22 @@ final class Menubar: NSObject, NSApplicationDelegate, NSMenuDelegate { } private func fetchPanes() -> [PaneRow] { - let fmt = "#{pane_id}\t#{session_name}:#{window_index}.#{pane_index}\t#{@agent}\t#{@agent_state}\t#{@dingger_ack}\t#{window_panes}" + let fmt = "#{pane_id}\t#{@agent}\t#{@agent_state}\t#{@dingger_ack}\t#{session_name}\t#{window_name}\t#{window_panes}\t#{pane_index}" guard let out = runTmux(["-u", "list-panes", "-a", "-F", fmt]) else { return [] } return out.split(separator: "\n").compactMap { line in let fields = line.split(separator: "\t", omittingEmptySubsequences: false) - guard fields.count >= 6 else { return nil } - let agent = String(fields[2]) - let state = fields[3].isEmpty ? "unknown" : String(fields[3]) + guard fields.count >= 8 else { return nil } + let agent = String(fields[1]) + let state = fields[2].isEmpty ? "unknown" : String(fields[2]) // Only tracked panes with a live state belong in the menu. guard !agent.isEmpty, ["idle", "working", "blocked"].contains(state) else { return nil } - var target = "\(fields[1].split(separator: ".", maxSplits: 1).first ?? fields[1])" - if Int(fields[5]) ?? 1 > 1 { - target = String(fields[1]) + // Display target: session:window-name, with the pane index only + // when the window is split. (Switching uses the pane id.) + var target = "\(fields[4]):\(fields[5])" + if Int(fields[6]) ?? 1 > 1 { + target += ".\(fields[7])" } return PaneRow(paneId: String(fields[0]), target: target, agent: agent, state: state) } @@ -205,6 +207,26 @@ final class Menubar: NSObject, NSApplicationDelegate, NSMenuDelegate { // MARK: actions + func printPanesForDebug() { + let rows = fetchPanes() + let queue = fetchQueue() + if rows.isEmpty { print("(no agents)") } + for pane in rows { + let queued = queue.contains(pane.paneId) + print("\(emojilessState(pane.state, queued: queued)) \(pane.agent) \(pane.target)") + } + } + + private func emojilessState(_ state: String, queued: Bool) -> String { + switch (state, queued) { + case ("blocked", true): return "[blocked!]" + case ("idle", true): return "[waiting]" + case ("working", _): return "[working]" + case ("blocked", _): return "[blocked]" + default: return "[idle]" + } + } + @objc private func paneClicked(_ sender: NSMenuItem) { guard let paneId = sender.representedObject as? String else { return } // Ack like `dingger focus` does, so both counts drop together. @@ -225,4 +247,11 @@ let app = NSApplication.shared let delegate = Menubar() app.delegate = delegate app.setActivationPolicy(.accessory) + +// Debug: print the rows the menu would show and exit. +if CommandLine.arguments.contains("--print") { + delegate.printPanesForDebug() + exit(0) +} + app.run() |
