Skip to content

Commit c686dc8

Browse files
committed
Merge branch 'indent-blacklist'
Closes #7, reported by meh <http://meh.schizofreni.co/> * indent-blacklist: Add doc for new blacklist and patterns variables Extract implicit fuzzy indent blacklist patterns Change quote style, remove comment Strip namespace qualifiers from indent candidate
2 parents 38d71bc + 550973b commit c686dc8

2 files changed

Lines changed: 62 additions & 20 deletions

File tree

doc/clojure.txt

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,48 @@ Maximum scan distance of searchpairpos().
4747
let g:clojure_maxlines = 100
4848
<
4949

50-
*g:clojure_fuzzy_indent* *g:clojure_fuzzy_indent_patterns*
50+
*g:clojure_fuzzy_indent*
51+
*g:clojure_fuzzy_indent_patterns*
52+
*g:clojure_fuzzy_indent_blacklist*
5153

52-
Indent words that match patterns as if they are included in 'lispwords'
54+
The 'lispwords' option is a list of comma-separated words that mark special
55+
forms whose following lines must be indented as if the word is on the
56+
first line alone.
57+
58+
For example:
59+
>
60+
(defn good []
61+
"Correct indentation")
62+
63+
(defn bad []
64+
"Incorrect indentation")
65+
<
66+
67+
If you would like to match words that match a pattern, you can use the
68+
fuzzy indent feature. The defaults are:
5369
>
5470
" Default
5571
let g:clojure_fuzzy_indent = 1
56-
let g:clojure_fuzzy_indent_patterns = "with.*,def.*,let.*"
72+
let g:clojure_fuzzy_indent_patterns = ['^with', '^def', '^let']
73+
let g:clojure_fuzzy_indent_blacklist = ['^with-meta$', '-fn$']
74+
75+
" Legacy comma-delimited string version; the list format above is
76+
" recommended. Note that patterns are implicitly anchored with ^ and $.
77+
let g:clojure_fuzzy_indent_patterns = 'with.*,def.*,let.*'
5778
<
5879

80+
*g:clojure_fuzzy_indent_patterns* and *g:clojure_fuzzy_indent_blacklist* are
81+
*Lists* of patterns that will be matched against the unqualified symbol at the
82+
head of a list. This means that a pattern like "^foo" will match all these
83+
candidates: "foobar", "my.ns/foobar", and "#'foobar".
84+
85+
Each candidate word is tested for special treatment in this order:
86+
87+
1. Return true if word is literally in 'lispwords'
88+
2. Return false if word matches a pattern in *g:clojure_fuzzy_indent_blacklist*
89+
3. Return true if word matches a pattern in *g:clojure_fuzzy_indent_patterns*
90+
4. Return false and indent normally otherwise
91+
5992
*g:clojure_align_multiline_strings*
6093

6194
When indenting multiline strings, align subsequent lines to the column

indent/clojure.vim

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,19 @@ if exists("*searchpairpos")
3535
let g:clojure_fuzzy_indent = 1
3636
endif
3737

38-
if !exists("g:clojure_fuzzy_indent_patterns")
39-
let g:clojure_fuzzy_indent_patterns = "with.*,def.*,let.*"
38+
if !exists('g:clojure_fuzzy_indent_patterns')
39+
let g:clojure_fuzzy_indent_patterns = ['^with', '^def', '^let']
40+
endif
41+
42+
if !exists('g:clojure_fuzzy_indent_blacklist')
43+
let g:clojure_fuzzy_indent_blacklist = ['^with-meta$', '-fn$']
4044
endif
4145

4246
if !exists('g:clojure_special_indent_words')
4347
let g:clojure_special_indent_words = 'deftype,defrecord,reify,proxy,extend-type,extend-protocol,letfn'
4448
endif
4549

46-
if !exists("g:clojure_align_multiline_strings")
50+
if !exists('g:clojure_align_multiline_strings')
4751
let g:clojure_align_multiline_strings = 0
4852
endif
4953

@@ -64,6 +68,18 @@ if exists("*searchpairpos")
6468
\ s:SynIdName() !~? '\vstring|comment'
6569
endfunction
6670

71+
" Returns 1 if string matches a pattern in 'patterns', which may be a
72+
" list of patterns, or a comma-delimited string of implicitly anchored
73+
" patterns.
74+
function! s:MatchesOne(patterns, string)
75+
let list = type(a:patterns) == type([])
76+
\ ? a:patterns
77+
\ : map(split(a:patterns, ','), '"^" . v:val . "$"')
78+
for pat in list
79+
if a:string =~ pat | return 1 | endif
80+
endfor
81+
endfunction
82+
6783
function! s:SavePosition()
6884
let [ _b, l, c, _o ] = getpos(".")
6985
let b = bufnr("%")
@@ -261,26 +277,19 @@ if exists("*searchpairpos")
261277
return paren[1]
262278
endif
263279

264-
" Test words with any leading non-word chars stripped;
265-
" e.g. #'defn should indent like defn.
266-
let ww = substitute(w, '\v\W*(\w.*)', '\1', '')
280+
" Test words without namespace qualifiers and leading non-word chars.
281+
"
282+
" e.g. clojure.core/defn and #'defn should both indent like defn.
283+
let ww = substitute(w, '\v%(.*/|\W*)(.*)', '\1', '')
267284

268285
if &lispwords =~ '\<' . ww . '\>'
269286
return paren[1] + &shiftwidth - 1
270287
endif
271288

272-
" XXX: Slight glitch here with special cases. However it's only
273-
" a heureustic. Offline we can't do more.
274289
if g:clojure_fuzzy_indent
275-
\ && ww != 'with-meta'
276-
\ && ww != 'clojure.core/with-meta'
277-
for pat in split(g:clojure_fuzzy_indent_patterns, ",")
278-
if ww =~ '\(^\|/\)' . pat . '$'
279-
\ && ww !~ '\(^\|/\)' . pat . '\*$'
280-
\ && ww !~ '\(^\|/\)' . pat . '-fn$'
281-
return paren[1] + &shiftwidth - 1
282-
endif
283-
endfor
290+
\ && !s:MatchesOne(g:clojure_fuzzy_indent_blacklist, ww)
291+
\ && s:MatchesOne(g:clojure_fuzzy_indent_patterns, ww)
292+
return paren[1] + &shiftwidth - 1
284293
endif
285294

286295
normal! W

0 commit comments

Comments
 (0)