blob: f7a3782e9b3ad4bcc0e5fe6abbf86a456475776c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#!/usr/bin/env bb
(require '[babashka.tasks :refer [shell]]
'[babashka.fs :as fs]
'[clojure.edn :as edn]
'[clojure.string :as str])
(def default-config
{:editor-command "nvim"
:default-target "nvim:"
:aliases []})
;; configuration helpers
(defn- deep-merge [v & vs]
(letfn [(rec-merge [v1 v2]
(if (and (map? v1) (map? v2))
(merge-with deep-merge v1 v2)
v2))]
(if (some identity vs)
(reduce #(rec-merge %1 %2) v vs)
(last vs))))
(defn- init-config [path]
(when-not (fs/exists? path)
(fs/create-dirs (fs/parent path))
(fs/create-file path)
(spit path default-config))
path)
;;; global config
(defn- global-config-path []
(let [env-vimnulti-config (System/getenv "VIMULTI_CONFIG")
env-xdg-config-home (System/getenv "XDG_CONFIG_HOME")
config-filename "config.edn"]
(or env-vimnulti-config
(if env-xdg-config-home
(str env-xdg-config-home "/vimulti/" config-filename)
config-filename))))
(def global-config (-> (global-config-path)
init-config
slurp
edn/read-string))
;;; load local config
(def config (cond-> global-config
(fs/exists? "vimulti.edn") (deep-merge (-> "vimulti.edn" slurp edn/read-string))))
;; git helpers
(defn- get-current-branch [dir]
(-> (shell {:dir dir
:out :string}
"git branch --show-current")
:out
str/trim-newline))
;; target should be a string like "app-name:branch" or "app-name@tag"
;; returns a map with keys :app-name :branch :tag...
(defn- parse-target-string [target-string]
(let [target (or target-string
(:default-target config)
"nvim:")
branch-style? (str/includes? target ":")
tag-style? (str/includes? target "@")
alias-style? (and (not branch-style?) (not tag-style?))]
(if alias-style?
;; if use alias style
(if-let [alias-config (get (:aliases config) target)]
alias-config
(do (println "No such alias or invalid target.")
(System/exit 1)))
;; if not alias style
(let [separator (if branch-style? #":" (if tag-style? #"@" #" "))
target-array (str/split target separator)
app-name (if (= (first target-array) "") "nvim" (first target-array))
repo (fs/path (System/getProperty "user.home") ".config" app-name)
no-mark (= (count target-array) 1)]
(when (> (count target-array) 2)
(println "Invalid target string.")
(System/exit 1))
(cond-> {:app-name app-name}
branch-style? (assoc :branch (when-not no-mark (last target-array)))
tag-style? (assoc :tag (when-not no-mark (last target-array)))
(fs/exists? repo) (assoc :repo repo))))))
;; main
;; target should be a string like "app-name:branch" or "app-name@tag"
(let [[target & args] *command-line-args*
target-map (parse-target-string target)
current-branch (get-current-branch (:repo target-map))]
(when-let [switch-to (or (:branch target-map)
(:tag target-map))]
(let [tag? (boolean (:tag target-map))]
(shell {:dir (:repo target-map)}
(str "git switch " switch-to (if tag? "--detach" "")))))
(shell {:extra-env {"NVIM_APPNAME" (:app-name target-map)}}
(:editor-command config) (apply str args))
(shell {:dir (:repo target-map)}
(str "git switch " current-branch)))
|