Created
May 15, 2025 00:40
-
-
Save jbrechtel/0760530561554931748d6e4e2b394fea to your computer and use it in GitHub Desktop.
Switch Run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ { name: "Firefox - Personal" | |
, app_id: "firefox_personal" | |
, exec: "/usr/lib/firefox/firefox" | |
, args: ["--class=firefox", "-P", "personal", "--name=firefox_personal"] | |
} | |
, { name: "Firefox - Work" | |
, app_id: "firefox_work" | |
, exec: "/usr/lib/firefox/firefox" | |
, args: ["--class=firefox", "-P", "flipstone", "--name=firefox_work"] | |
} | |
, { name: "Slack" | |
, app_id: "Slack" | |
, exec: "/usr/bin/slack" | |
, args: ["--ozone-platform=wayland", "-s", "%U"] | |
} | |
, { name: "Emacs" | |
, app_id: "emacs" | |
, exec: "emacsclient" | |
, args: ["--alternate-editor=", "--create-frame"] | |
} | |
# These details were extracted from the .desktop file created after using Chromium's "install as app" feature on the Gather site | |
, { name: "Gather" | |
, app_id: "chrome-lomadbaljkledafpiopomkmeoccppjpk-Default" | |
, exec: "/opt/google/chrome/google-chrome" | |
, args: ["--ozone-platform=wayland", "--profile-directory=Default", "--app-id=lomadbaljkledafpiopomkmeoccppjpk"] | |
} | |
, { name: "Signal" | |
, app_id: "signal" | |
, exec: "signal-desktop" | |
, args: ["--ozone-platform=wayland", "--", "%u"] | |
} | |
, { name: "Chromium" | |
, app_id: "chromium" | |
, exec: "chromium" | |
, args: ["--ozone-platform=wayland"] | |
} | |
, { name: "Thunar (file manager)" | |
, app_id: "thunar" | |
, exec: "thunar" | |
, args: [] | |
} | |
, { name: "Obsidian" | |
, app_id: "obsidian" | |
, exec: "/usr/bin/obsidian" | |
, args: [] | |
} | |
, { name: "WezTerm" | |
, app_id: "org.wezfurlong.wezterm" | |
, exec: "/usr/bin/wezterm" | |
, args: [] | |
} | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/nu | |
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 launcher_apps = open $"($env.HOME)/.config/switchrun/apps.nuon" | |
let app = ( | |
$launcher_apps | | |
where app_id == $target_app_id | | |
first | |
) | |
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) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment