#!/usr/bin/nu let launcher_apps = open $"($env.HOME)/.config/switchrun/apps.nuon" def lookup_window_id [running_apps, app_id] { let matches = $running_apps | where app_id == $app_id if ($matches | is-empty) { "none" } else { $matches | get id | first | into string } } def switch_to [target_window_id: string] { let focus_cmd = {Action: { FocusWindow: { id: ($target_window_id | into int ) } } } $focus_cmd | to json -r | socat STDIO $env.NIRI_SOCKET } def launch [target_app_id: string] { let app = ( $launcher_apps | where app_id == $target_app_id | first ) print $app.exec print ...$app.args if $app != null { run-external $app.exec ...$app.args} else { print "no exec found" } } def main [target_app_id: string] { let running_apps = niri msg --json windows | from json let matches = $running_apps | where app_id == $target_app_id print $matches if ($matches | is-empty) { launch $target_app_id } else { let focused_matches = $matches | enumerate | where item.is_focused == true | get index if ($focused_matches | is-empty) { switch_to (($matches | first | get id) | into string) } else { # In the event of multiple matches, switch to the one after the focused one - wrapping around # That way we will cycle through them let target_index = ($focused_matches | first) - 1 print $target_index print ($matches | length) let target_window = if ($target_index < 0) { $matches | last } else { ($matches | get $target_index) } switch_to ($target_window.id | into string) } } } def "main list" [tag?: string] { let running_apps = niri msg --json windows | from json # Optionally narrow to apps carrying the requested tag. let filtered = (if ($tag | is-empty) { $launcher_apps } else { $launcher_apps | where { |app| ($tag in ($app.tags? | default [])) } }) if ($filtered | is-empty) { print $"No applications match tag '($tag)'" return } let apps = $filtered | each { |app| $app | insert window_id { lookup_window_id $running_apps $app.app_id } } # if the selected app_id is running then # focus it by its window id (first window id for that app id is fine) # if it's not running then launch it using the app's desktop entry # let app_lines = $apps | each { $"($in.name) - [($in.app_id), ($in.window_id)]" } let prompt = if ($tag | is-empty) { "Launch/Switch" } else { $"Launch/Switch [($tag)]" } let selection = $app_lines | each { echo $in } | str join "|" | rofi -dmenu -i -p $prompt -sep "|" let parsed = $selection | parse "{name} - [{app_id}, {window_id}]" | first let match = $apps | where app_id == $parsed.app_id | first if $parsed.window_id == "none" { launch $match.app_id } else { switch_to $match.window_id } }