(import json) (defn item-with-id [id items] (find |(= ($ "id") id) items)) (defn contains? [id node] (if (= node :null) false (or (= (node "id") id) (contains? id (node "firstChild")) (contains? id (node "secondChild"))))) (defn partition-on-focused [focused-id {"firstChild" node-a "secondChild" node-b}] (if (contains? focused-id node-a) [node-a node-b] [node-b node-a])) (defn count-hidden [node] (match node :null 0 {"hidden" true} 1 {"firstChild" node-a "secondChild" node-b} (+ (count-hidden node-a) (count-hidden node-b)))) (defn collect-hidden [node] (def hidden @[]) (defn put-hidden [node] (match node :null nil {"hidden" true} (array/push hidden node) {"firstChild" node-a "secondChild" node-b} (do (put-hidden node-a) (put-hidden node-b)))) (put-hidden node) hidden) (defn fully-unhidden "Gets the first node with all children unhidden" [node] (match node :null nil {"firstChild" {"hidden" false} "secondChild" {"hidden" false}} node {"firstChild" {"hidden" true} "secondChild" second} (fully-unhidden second) {"firstChild" first "secondChild" {"hidden" true}} (fully-unhidden first))) (defn innermost-hidden [focused-id node] (match node :null nil {"hidden" true} node _ (let [[focused not-focused] (partition-on-focused focused-id node)] (or (innermost-hidden focused-id focused) (innermost-hidden focused-id not-focused))))) (defn rotate-clockwise [] (os/execute ["bspc" "node" "@/" "--rotate" "90"] :p)) (defn rotate-counterclockwise [] (os/execute ["bspc" "node" "@/" "--rotate" "-90"] :p)) (defn toggle-hidden [node] (os/execute ["bspc" "node" (string (node "id")) "--flag" "hidden"] :p)) (defn get-state [] (with [pipe (os/spawn ["bspc" "wm" "-d"] :p {:out :pipe})] (:read (pipe :out) :all))) (defn current-desktop [] (let [data (get-state) state (json/decode data) monitor (item-with-id (state "focusedMonitorId") (state "monitors"))] (item-with-id (monitor "focusedDesktopId") (monitor "desktops")))) (defn zoom-in [] (let [desktop (current-desktop) unhidden (fully-unhidden (desktop "root")) focused-id (desktop "focusedNodeId")] (match unhidden nil (print "Não há mais nós para esconder") {"firstChild" :null "secondChild" :null} (toggle-hidden unhidden) _ (let [[_ not-focused] (partition-on-focused focused-id unhidden)] (toggle-hidden not-focused) (rotate-counterclockwise))))) (defn zoom-out [] (let [desktop (current-desktop) node (innermost-hidden (desktop "focusedNodeId") (desktop "root"))] (when node (rotate-clockwise) (toggle-hidden node)))) (defn zoom-level [] (let [desktop (current-desktop)] (print (count-hidden (desktop "root"))))) (defn level-zero [] (let [desktop (current-desktop)] (each node (collect-hidden (desktop "root")) (rotate-clockwise) (toggle-hidden node)))) (defn main [& args] (if (= 1 (length args)) (print "Que comando você quer executar? `in` ou `out`?") (match (args 1) "in" (zoom-in) "out" (zoom-out) "zoom-level" (zoom-level) "level-zero" (level-zero) command (print "Comando não reconhecido: " command))))