From b974eb01b316a06cf1f76cdfbe364f8b2160a381 Mon Sep 17 00:00:00 2001 From: Alex Vear Date: Sun, 10 Jan 2021 18:35:46 +0000 Subject: [PATCH 1/2] Fix indentation of subforms inside `letfn` forms Fixes: guns/vim-clojure-static#56 Related: guns/vim-clojure-static#83 --- indent/clojure.vim | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/indent/clojure.vim b/indent/clojure.vim index ffa5820..75d82a0 100644 --- a/indent/clojure.vim +++ b/indent/clojure.vim @@ -169,7 +169,35 @@ if exists("*searchpairpos") call search('\S', 'W') let w = s:strip_namespace_and_macro_chars(s:current_word()) + if g:clojure_special_indent_words =~# '\V\<' . w . '\>' + + " `letfn` is a special-special-case. + if w ==# 'letfn' + " Earlier code left the cursor at: + " (letfn [...] ...) + " ^ + + " Search and get coordinates of first `[` + " (letfn [...] ...) + " ^ + call search('\[', 'W') + let pos = getcurpos() + let letfn_bracket = [pos[1], pos[2]] + + " Move cursor to start of the form this function was + " initially called on. Grab the coordinates of the + " closest outer `[`. + call cursor(a:position) + let outer_bracket = s:match_pairs('\[', '\]', 0) + + " If the located square brackets are not the same, + " don't use special-case formatting. + if outer_bracket != letfn_bracket + return 0 + endif + endif + return 1 endif From 89c9d71f522a7dd9f95d89a8b4355c2e78aa2cc3 Mon Sep 17 00:00:00 2001 From: Alex Vear Date: Sun, 10 Jan 2021 18:55:12 +0000 Subject: [PATCH 2/2] Add test cases for special case indentation --- clj/dev-resources/test-special-case-indent.in | 39 +++++++++++++++++++ .../test-special-case-indent.out | 39 +++++++++++++++++++ clj/test/vim_clojure_static/indent_test.clj | 5 +++ 3 files changed, 83 insertions(+) create mode 100644 clj/dev-resources/test-special-case-indent.in create mode 100644 clj/dev-resources/test-special-case-indent.out diff --git a/clj/dev-resources/test-special-case-indent.in b/clj/dev-resources/test-special-case-indent.in new file mode 100644 index 0000000..badbd79 --- /dev/null +++ b/clj/dev-resources/test-special-case-indent.in @@ -0,0 +1,39 @@ +(let [x (fn [y] 1)] + (->> "ola" + (x))) + +(letfn [(x [y] 1)] + (->> "ola" + (x))) + +(->> "ola" + (x)) + +(defn foo [] + (letfn [(x [y] 1)] + (->> "ola" + (x)))) + +(letfn [(twice [x] + (* x 2)) + (six-times [y] +(* (twice y) 3))] + (println "Twice 15 =" (twice 15)) + (println "Six times 15 =" (six-times 15))) + +(letfn [(twice [x] + (* x 2))] + (->> "ola" + (x))) + +(letfn [(foo [x y] + (->> x + y + :bar)) +(twice [x] + (* x 2)) + (six-times [y] +(* (twice y) 3))] + (foo #{:foo :bar :biz} :foo)) + +;; vim:ft=clojure: diff --git a/clj/dev-resources/test-special-case-indent.out b/clj/dev-resources/test-special-case-indent.out new file mode 100644 index 0000000..b7b0c0e --- /dev/null +++ b/clj/dev-resources/test-special-case-indent.out @@ -0,0 +1,39 @@ +(let [x (fn [y] 1)] + (->> "ola" + (x))) + +(letfn [(x [y] 1)] + (->> "ola" + (x))) + +(->> "ola" + (x)) + +(defn foo [] + (letfn [(x [y] 1)] + (->> "ola" + (x)))) + +(letfn [(twice [x] + (* x 2)) + (six-times [y] + (* (twice y) 3))] + (println "Twice 15 =" (twice 15)) + (println "Six times 15 =" (six-times 15))) + +(letfn [(twice [x] + (* x 2))] + (->> "ola" + (x))) + +(letfn [(foo [x y] + (->> x + y + :bar)) + (twice [x] + (* x 2)) + (six-times [y] + (* (twice y) 3))] + (foo #{:foo :bar :biz} :foo)) + +;; vim:ft=clojure: diff --git a/clj/test/vim_clojure_static/indent_test.clj b/clj/test/vim_clojure_static/indent_test.clj index 8b09194..dd00476 100644 --- a/clj/test/vim_clojure_static/indent_test.clj +++ b/clj/test/vim_clojure_static/indent_test.clj @@ -33,3 +33,8 @@ (test-indent "dispatch macro indentation is handled correctly" :in "test-dispatch-macro-indent.in" :out "test-dispatch-macro-indent.out")) + +(deftest test-special-case-indent + (test-indent "special case indentation is handled correctly" + :in "test-special-case-indent.in" + :out "test-special-case-indent.out"))