diff options
| author | Akshay Nair <phenax5@gmail.com> | 2026-06-26 13:50:48 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2026-06-26 13:50:48 +0530 |
| commit | d2f4982e389431b74357bbc108567ae0e1d912a5 (patch) | |
| tree | d9e18402fda762f5f8840d6974b89981625ce5f0 /scripts/git.clj | |
| parent | d2995bc1d5968b5e8d018135748c6768f920d3c8 (diff) | |
| download | kakoune-config-d2f4982e389431b74357bbc108567ae0e1d912a5.tar.gz kakoune-config-d2f4982e389431b74357bbc108567ae0e1d912a5.zip | |
Add open selection in git remote url
Diffstat (limited to 'scripts/git.clj')
| -rwxr-xr-x | scripts/git.clj | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/scripts/git.clj b/scripts/git.clj new file mode 100755 index 0000000..c1e450b --- /dev/null +++ b/scripts/git.clj @@ -0,0 +1,71 @@ +#!/usr/bin/env bb + +(require '[clojure.java.shell :refer [sh]]) +(require '[clojure.string :as str]) +(require '[clojure.java.io :as io]) + +(defn dirname [path] (.getParent (io/file path))) + +(defn git [dir & args] + (let [proc (apply sh "git" "-C" (or dir ".") args)] + (when (= (:exit proc) 0) + (str/trim (:out proc))))) + +(defn git-remote-origin [dir] + (not-empty (git dir "remote" "get-url" "origin"))) + +(defn git-first-remote [dir] + (some->> (git dir "remote" "-v") + str/split-lines + (keep #(re-matches #"^\w+\s+(.*)\s+\(fetch\)" %)) + first + second)) + +(defn prepare-link [remote-url rev file-path & [line-start line-end]] + (let [parse-path #(some->> (re-matches % remote-url) second) + line-hash (cond + (nil? line-start) nil + (= line-start line-end) (str "#L" line-start) + (some? line-end) (str "#L" line-start "-L" line-end) + (nil? line-end) (str "#L" line-start))] + (some->> + (cond + (empty? remote-url) nil + (.contains remote-url "github.com:") ["https://github.com" (parse-path #".*github.com:(.*)\.git$") "blob" rev (str file-path line-hash)] + (.contains remote-url "github.com/") ["https://github.com" (parse-path #".*github.com/(.*)(\.git)?$") "blob" rev (str file-path line-hash)] + (.contains remote-url "gitlab.com:") ["https://gitlab.com" (parse-path #".*gitlab.com:(.*)\.git$") "-/blob" rev (str file-path line-hash)] + (.contains remote-url "gitlab.com/") ["https://gitlab.com" (parse-path #".*gitlab.com/(.*)(\.git)?$") "-/blob" rev (str file-path line-hash)] + (.contains remote-url "git.sr.ht:") ["https://git.sr.ht" (parse-path #".*git.sr.ht:(.*)\.git$") "tree" rev (str file-path line-hash)] + (.contains remote-url "git.sr.ht/") ["https://git.sr.ht" (parse-path #".*git.sr.ht/(.*)(\.git)?$") "tree" rev (str file-path line-hash)] + :else nil) + (remove nil?) + (str/join "/")))) + +(defn git-current-rev [dir] (git dir "rev-parse" "--short" "HEAD")) + +(defn git-remote-url [dir file-path revision line-start line-end] + (some-> (or (git-remote-origin dir) (git-first-remote dir)) + (prepare-link revision file-path line-start line-end))) + +(defn git-root [path] + (let [file-dir (if (empty? path) "." (dirname path))] + (some->> (git file-dir "rev-parse" "--absolute-git-dir") + dirname))) + +(defn cmd-link [[file-path line-start line-end rev]] + (let [dir (git-root file-path) + revision (or rev (git-current-rev dir) "main") + relative-file-path (str/trim (:out (sh "realpath" "--relative-to" dir file-path))) + remote-url (git-remote-url dir relative-file-path revision line-start line-end)] + (println remote-url))) + +(def commands + {"link" cmd-link}) + +(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)))))) + |
