arrange_workspaces.clj
· 1.3 KiB · Clojure
原始文件
#!/usr/bin/env bb
(ns arrange-workspaces
(:require [babashka.process :as p]
[clojure.edn :as edn]))
(defonce config-path
(str (System/getenv "HOME")
"/.config/kanshi/workspaces.edn"))
(defn read-config
"Read the configuration from `config-path`"
[path]
(-> path
slurp
edn/read-string))
(defn niri-msg
"Generic function for `niri msg action`"
[action params]
(let [cmd (into ["niri" "msg" "--json" "action" (name action)] params)]
(->> cmd
(apply p/shell {:out :string :err :string})
(select-keys [:out :err]))))
(defn niri-move-to-monitor
"Move `workspace` to `monitor`."
[monitor workspace]
(niri-msg :move-workspace-to-monitor ["--reference" workspace monitor]))
(defn arrange [context]
(doseq [[monitor workspaces] context]
(let [f (partial niri-move-to-monitor monitor)]
(mapv f workspaces))))
(defn -main [args]
(try
(let [config (read-config config-path)
context (first args)]
(when-let [context-config (get config context nil)]
(println "Found" context "configuration")
(arrange context-config)))
(catch java.io.FileNotFoundException _
(.println System/err (str "Configuration " config-path " not found."))
(System/exit -1))))
(-main *command-line-args*)
| 1 | #!/usr/bin/env bb |
| 2 | |
| 3 | (ns arrange-workspaces |
| 4 | (:require [babashka.process :as p] |
| 5 | [clojure.edn :as edn])) |
| 6 | |
| 7 | (defonce config-path |
| 8 | (str (System/getenv "HOME") |
| 9 | "/.config/kanshi/workspaces.edn")) |
| 10 | |
| 11 | (defn read-config |
| 12 | "Read the configuration from `config-path`" |
| 13 | [path] |
| 14 | (-> path |
| 15 | slurp |
| 16 | edn/read-string)) |
| 17 | |
| 18 | (defn niri-msg |
| 19 | "Generic function for `niri msg action`" |
| 20 | [action params] |
| 21 | (let [cmd (into ["niri" "msg" "--json" "action" (name action)] params)] |
| 22 | (->> cmd |
| 23 | (apply p/shell {:out :string :err :string}) |
| 24 | (select-keys [:out :err])))) |
| 25 | |
| 26 | (defn niri-move-to-monitor |
| 27 | "Move `workspace` to `monitor`." |
| 28 | [monitor workspace] |
| 29 | (niri-msg :move-workspace-to-monitor ["--reference" workspace monitor])) |
| 30 | |
| 31 | (defn arrange [context] |
| 32 | (doseq [[monitor workspaces] context] |
| 33 | (let [f (partial niri-move-to-monitor monitor)] |
| 34 | (mapv f workspaces)))) |
| 35 | |
| 36 | (defn -main [args] |
| 37 | (try |
| 38 | (let [config (read-config config-path) |
| 39 | context (first args)] |
| 40 | (when-let [context-config (get config context nil)] |
| 41 | (println "Found" context "configuration") |
| 42 | (arrange context-config))) |
| 43 | (catch java.io.FileNotFoundException _ |
| 44 | (.println System/err (str "Configuration " config-path " not found.")) |
| 45 | (System/exit -1)))) |
| 46 | |
| 47 | (-main *command-line-args*) |
| 48 |
switch_workspace.clj
· 1.2 KiB · Clojure
原始文件
#!/usr/bin/env bb
(ns switch-workspace
(:require [babashka.process :as p]
[clojure.string :as s]
[cheshire.core :as j]))
(defn niri-msg
"Generic function for `niri msg action`"
[action params]
(let [cmd (into ["niri" "msg" "--json" (name action)] params)]
(as-> cmd $
(apply p/shell {:out :string :err :string} $)
(select-keys $ [:out :err]))))
(defn focused-or-nil?
"Return if a workspaces is focused or doesn't have a name."
[workspace]
(let [{:keys [name is_focused]} workspace]
(or (nil? name)
(true? is_focused))))
(defn niri-get-workspaces
"Get all the workspaces from niri"
[]
(as-> (niri-msg :workspaces nil) $
(:out $)
(j/parse-string $ keyword)
(remove focused-or-nil? $)
(map :name $)))
(defn niri-focus-workspace
"Set focus to the given namespace"
[workspace]
(niri-msg :action ["focus-workspace" workspace]))
(defn run-rofi
"Given a list of options, call rofi and return the selected one."
[options]
(as-> options $
(s/join "\n" $)
(p/shell {:out :string :in $} "rofi" "-dmenu")
(:out $)
(s/trim-newline $)))
(defn -main []
(-> (niri-get-workspaces)
(run-rofi)
(niri-focus-workspace)))
(-main)
| 1 | #!/usr/bin/env bb |
| 2 | (ns switch-workspace |
| 3 | (:require [babashka.process :as p] |
| 4 | [clojure.string :as s] |
| 5 | [cheshire.core :as j])) |
| 6 | |
| 7 | (defn niri-msg |
| 8 | "Generic function for `niri msg action`" |
| 9 | [action params] |
| 10 | (let [cmd (into ["niri" "msg" "--json" (name action)] params)] |
| 11 | (as-> cmd $ |
| 12 | (apply p/shell {:out :string :err :string} $) |
| 13 | (select-keys $ [:out :err])))) |
| 14 | |
| 15 | (defn focused-or-nil? |
| 16 | "Return if a workspaces is focused or doesn't have a name." |
| 17 | [workspace] |
| 18 | (let [{:keys [name is_focused]} workspace] |
| 19 | (or (nil? name) |
| 20 | (true? is_focused)))) |
| 21 | |
| 22 | (defn niri-get-workspaces |
| 23 | "Get all the workspaces from niri" |
| 24 | [] |
| 25 | (as-> (niri-msg :workspaces nil) $ |
| 26 | (:out $) |
| 27 | (j/parse-string $ keyword) |
| 28 | (remove focused-or-nil? $) |
| 29 | (map :name $))) |
| 30 | |
| 31 | (defn niri-focus-workspace |
| 32 | "Set focus to the given namespace" |
| 33 | [workspace] |
| 34 | (niri-msg :action ["focus-workspace" workspace])) |
| 35 | |
| 36 | (defn run-rofi |
| 37 | "Given a list of options, call rofi and return the selected one." |
| 38 | [options] |
| 39 | (as-> options $ |
| 40 | (s/join "\n" $) |
| 41 | (p/shell {:out :string :in $} "rofi" "-dmenu") |
| 42 | (:out $) |
| 43 | (s/trim-newline $))) |
| 44 | |
| 45 | (defn -main [] |
| 46 | (-> (niri-get-workspaces) |
| 47 | (run-rofi) |
| 48 | (niri-focus-workspace))) |
| 49 | |
| 50 | (-main) |
| 51 |