aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--menubar/main.swift43
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()