Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c06750a

Browse files
committed
Inherit the indent of the previous element at the same sexp level
The builtin 'lisp' indenter does this. See src/misc1.c:get_lisp_indent() Includes test case! Addresses #47
1 parent 82a5781 commit c06750a

File tree

4 files changed

+84
-15
lines changed

4 files changed

+84
-15
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(foo bar [✖])
2+
3+
;; vim:ft=clojure:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(foo bar [
2+
a
3+
b
4+
5+
c])
6+
7+
;; vim:ft=clojure:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(ns vim-clojure-static.indent-test
2+
(:require [clojure.test :refer [deftest]]
3+
[vim-clojure-static.test :refer [test-indent]]))
4+
5+
(deftest test-indentation
6+
(test-indent "is inherited from previous element"
7+
:in "test-inherit-indent.in"
8+
:out "test-inherit-indent.out"
9+
:keys "/✖\\<Esc>s\\<CR>\\<C-H>\\<C-H>\\<C-H>\\<C-H>a\\<CR>b\\<CR>\\<CR>c\\<Esc>"))

‎indent/clojure.vim

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,23 @@ if exists("*searchpairpos")
192192
return val
193193
endfunction
194194

195-
function! GetClojureIndent()
195+
" Returns 1 for opening brackets, -1 for _anything else_.
196+
function! s:bracket_type(char)
197+
return stridx('([{', a:char) > -1 ? 1 : -1
198+
endfunction
199+
200+
" Returns: [opening-bracket-lnum, indent]
201+
function! s:clojure_indent_pos()
196202
" Get rid of special case.
197203
if line(".") == 1
198-
return 0
204+
return [0, 0]
199205
endif
200206

201207
" We have to apply some heuristics here to figure out, whether to use
202208
" normal lisp indenting or not.
203209
let i = s:check_for_string()
204210
if i > -1
205-
return i + !!g:clojure_align_multiline_strings
211+
return [0, i + !!g:clojure_align_multiline_strings]
206212
endif
207213

208214
call cursor(0, 1)
@@ -219,19 +225,19 @@ if exists("*searchpairpos")
219225
" curly indent.
220226
if curly[0] > bracket[0] || curly[1] > bracket[1]
221227
if curly[0] > paren[0] || curly[1] > paren[1]
222-
return curly[1]
228+
return curly
223229
endif
224230
endif
225231

226232
" If the curly was not chosen, we take the bracket indent - if
227233
" there was one.
228234
if bracket[0] > paren[0] || bracket[1] > paren[1]
229-
return bracket[1]
235+
return bracket
230236
endif
231237

232238
" There are neither { nor [ nor (, ie. we are at the toplevel.
233239
if paren == [0, 0]
234-
return 0
240+
return paren
235241
endif
236242

237243
" Now we have to reimplement lispindent. This is surprisingly easy, as
@@ -250,12 +256,12 @@ if exists("*searchpairpos")
250256
call cursor(paren)
251257

252258
if s:is_method_special_case(paren)
253-
return paren[1] + &shiftwidth - 1
259+
return [paren[0], paren[1] + &shiftwidth - 1]
254260
endif
255261

256262
" In case we are at the last character, we use the paren position.
257263
if col("$") - 1 == paren[1]
258-
return paren[1]
264+
return paren
259265
endif
260266

261267
" In case after the paren is a whitespace, we search for the next word.
@@ -267,14 +273,14 @@ if exists("*searchpairpos")
267273
" If we moved to another line, there is no word after the (. We
268274
" use the ( position for indent.
269275
if line(".") > paren[0]
270-
return paren[1]
276+
return paren
271277
endif
272278

273279
" We still have to check, whether the keyword starts with a (, [ or {.
274280
" In that case we use the ( position for indent.
275281
let w = s:current_word()
276-
if stridx('([{', w[0]) > -1
277-
return paren[1]
282+
if s:bracket_type(w[0]) ==1
283+
return paren
278284
endif
279285

280286
" Test words without namespace qualifiers and leading reader macro
@@ -284,23 +290,67 @@ if exists("*searchpairpos")
284290
let ww = s:strip_namespace_and_macro_chars(w)
285291

286292
if &lispwords =~# '\V\<' . ww . '\>'
287-
return paren[1] + &shiftwidth - 1
293+
return [paren[0], paren[1] + &shiftwidth - 1]
288294
endif
289295

290296
if g:clojure_fuzzy_indent
291297
\ && !s:match_one(g:clojure_fuzzy_indent_blacklist, ww)
292298
\ && s:match_one(g:clojure_fuzzy_indent_patterns, ww)
293-
return paren[1] + &shiftwidth - 1
299+
return [paren[0], paren[1] + &shiftwidth - 1]
294300
endif
295301

296302
call search('\v\_s', 'cW')
297303
call search('\v\S', 'W')
298304
if paren[0] < line(".")
299-
return paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)
305+
return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)]
300306
endif
301307

302308
call search('\v\S', 'bW')
303-
return virtcol(".") + 1
309+
return [line('.'), virtcol('.') + 1]
310+
endfunction
311+
312+
function! GetClojureIndent()
313+
let lnum = line('.')
314+
let [opening_lnum, indent] = s:clojure_indent_pos()
315+
316+
" Return if there are no previous lines to inherit from
317+
if opening_lnum < 1 || opening_lnum >= lnum - 1
318+
return indent
319+
endif
320+
321+
let bracket_count = 0
322+
323+
" Take the indent of the first previous non-white line that is
324+
" at the same sexp level. cf. src/misc1.c:get_lisp_indent()
325+
while 1
326+
let lnum = prevnonblank(lnum - 1)
327+
let col = 1
328+
329+
if lnum <= opening_lnum
330+
break
331+
endif
332+
333+
call cursor(lnum, col)
334+
335+
" Handle bracket counting edge case
336+
if s:is_paren()
337+
let bracket_count += s:bracket_type(s:current_char())
338+
endif
339+
340+
while 1
341+
if search('\v[(\[{}\])]', '', lnum) < 1
342+
break
343+
elseif !s:ignored_region()
344+
let bracket_count += s:bracket_type(s:current_char())
345+
endif
346+
endwhile
347+
348+
if bracket_count == 0
349+
return indent(lnum)
350+
endif
351+
endwhile
352+
353+
return indent
304354
endfunction
305355

306356
setlocal indentexpr=GetClojureIndent()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /