Last active
December 14, 2015 11:28
-
-
Save Jared314/5079619 to your computer and use it in GitHub Desktop.
A get-indent function to get the amount of indention for the next line of clojure code, based on the previous line.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def closing {\) \( | |
\} \{ | |
\] \[}) | |
(def opening [\( \{ \[]) | |
(defn zero-or-more [x] (if (>= x 0) x 0)) | |
(defn indent-exception? [[a b]] (not (and (= a \') (= b \()))) | |
; warning: Very basic clojure language parsing. It does not handle strings. | |
(defn reverse-parse | |
([data] (reverse-parse data [])) | |
([data starting-stack] | |
(loop [pos (dec (.length data)) | |
stack starting-stack] | |
(if (< pos 0) | |
[pos stack] | |
(let [cur (.charAt data pos)] | |
(cond | |
(contains? closing cur) (recur (dec pos) (conj stack (closing cur))) | |
(= (peek stack) cur) (recur (dec pos) (pop stack)) | |
(some {cur true} opening) [pos stack] | |
:else (recur (dec pos) stack))))))) | |
(defn get-indent [data] | |
(let [pos (first (reverse-parse data))] | |
(if (= pos -1) | |
(count (re-find #"^\s+" data)) ;match indent | |
(if (indent-exception? [(.charAt data (zero-or-more (dec pos))) (.charAt data pos)]) | |
(let [m (re-matcher #"[,\s]+" (.substring data pos))] | |
(if (.find m) | |
(+ pos (.end m)) ;match first parameter position | |
pos)) | |
(inc pos))))) ;match inside delimiter position | |
(get-indent "(defn thing [x]") ; => 6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment