#!/usr/bin/env bb (require '[clojure.string :as str]) (require '[clojure.java.io :as io]) (def xdg-data-home (or (System/getenv "XDG_DATA_HOME") (str (System/getenv "HOME") "/.local/share"))) (def marks-root-dir (str xdg-data-home "/kak/marks")) (def path-key (str/replace (System/getenv "PWD") #"[^A-Za-z0-9._-]" "-")) (def marks-file-path (str marks-root-dir "/" path-key)) (defn get-marks [] (let [file (io/file marks-file-path)] (if (.exists file) (str/split-lines (str/trim (slurp file))) []))) (defn set-marks [marks] (.mkdirs (io/file marks-root-dir)) (spit marks-file-path (str/join "\n" marks))) (defn vec-push-at-pos [vector index new-value] (vec (concat (subvec vector 0 index) [new-value] (subvec vector index)))) (defn cmd-add [[new-mark posstr]] (let [pos (some-> posstr parse-long) marks (vec (remove #(= % new-mark) (get-marks))) pos-valid? (or (not (pos-int? pos)) (> pos (count marks)))] (set-marks (if pos-valid? (conj marks new-mark) (vec-push-at-pos marks (dec pos) new-mark))))) (defn cmd-get [[posstr]] (let [pos (some-> posstr parse-long) marks (get-marks)] (when-let [mark (and pos (nth marks (dec pos) nil))] (println mark)))) (defn cmd-delete [[mark]] (->> (get-marks) (remove #(= % mark)) set-marks)) (defn cmd-clear [_] (set-marks [])) (defn cmd-show [_] (->> (get-marks) (str/join "\n") println)) (defn cmd-show-path [_] (println marks-file-path)) (def commands {"add" cmd-add "get" cmd-get "delete" cmd-delete "clear" cmd-clear "show" cmd-show "show-path" cmd-show-path}) (let [[cmd & args] *command-line-args*] (if-let [command-fn (commands cmd)] (command-fn args) (binding [*out* *err*] (println (str "invalid command: " (or cmd ""))) (println (str "Valid commands: " (keys commands))))))