@@ -81,14 +81,26 @@ function! s:IsEscaped(line_str, i_char)
81
81
return (strlen (ln ) - strlen(trim(ln, '\', 2))) % 2
82
82
endfunction
83
83
84
- " TODO: better comment and function name.
85
- " Used to check if in the current form for list function indentation.
86
- let s: in_form_current_form = [0 , 0 ]
87
- function ! s: InForm ()
84
+ " Used during list function indentation. Returns the position of the first
85
+ " operand in the list on the first line of the form at "pos".
86
+ function ! s: FirstFnArgPos (pos)
87
+ " TODO: ignore comments.
88
+ " TODO: handle escaped characters!
89
+ let lnr = a: pos [0 ]
90
+ let s: in_form_current_form = a: pos
91
+ call cursor (lnr , a: pos [1 ] + 1 )
92
+ return searchpos (' [ ,]\+\zs' , ' z' , lnr , 0 , function (' <SID>IsSubForm' ))
93
+ endfunction
94
+
95
+ " Used by "s:FirstFnArgPos" function to skip over subforms as the first value
96
+ " in a list form.
97
+ function ! s: IsSubForm ()
88
98
let pos = searchpairpos (' [([{"]' , ' ' , ' [)\]}"]' , ' b' )
89
99
return pos != [0 , 0 ] && pos != s: in_form_current_form
90
100
endfunction
91
101
102
+ " Converts a cursor position into a characterwise cursor position (to handle
103
+ " multibyte characters).
92
104
function ! s: PosToCharPos (pos)
93
105
call cursor (a: pos )
94
106
return getcursorcharpos ()[1 :2 ]
@@ -235,7 +247,6 @@ function! s:ListIndent(delim_pos)
235
247
236
248
let base_indent = s: PosToCharPos (a: delim_pos )[1 ]
237
249
let ln = getline(a:delim_pos[0])
238
- let delim_col = a: delim_pos [1 ]
239
250
240
251
" 1. Macro/rule indentation
241
252
" if starts with a symbol, extract it.
@@ -250,7 +261,7 @@ function! s:ListIndent(delim_pos)
250
261
" other indentation options.
251
262
252
263
" TODO: simplify this.
253
- let syms = split (ln [delim_col :], '[[:space:],;()\[\]{}@\\"^~`]', 1)
264
+ let syms = split (ln [a:delim_pos[1] :], '[[:space:],;()\[\]{}@\\"^~`]', 1)
254
265
255
266
if ! empty (syms)
256
267
let sym = syms[0 ]
@@ -264,9 +275,7 @@ function! s:ListIndent(delim_pos)
264
275
265
276
" TODO: replace `clojure_fuzzy_indent_patterns` with `clojure_indent_patterns`
266
277
for pat in s: Conf (' clojure_fuzzy_indent_patterns' , [])
267
- if sym = ~# pat
268
- return base_indent + 1
269
- endif
278
+ if sym = ~# pat | return base_indent + 1 | endif
270
279
endfor
271
280
272
281
let rules = s: Conf (' clojure_indent_rules' , {})
@@ -277,22 +286,14 @@ function! s:ListIndent(delim_pos)
277
286
endif
278
287
279
288
" 2. Function indentation
280
- " if first operand is on the same line? (Treat metadata as args.)
289
+ " if first operand is on the same line?
281
290
" - Indent subsequent lines to align with first operand.
282
291
" else
283
292
" - Indent 1 or 2 spaces.
284
-
285
293
let indent_style = s: Conf (' clojure_indent_style' , ' always-align' )
286
294
if indent_style !=# ' always-indent'
287
- let lnr = a: delim_pos [0 ]
288
- call cursor (lnr , delim_col + 1 )
289
-
290
- " TODO: ignore comments.
291
- " TODO: handle escaped characters!
292
- let s: in_form_current_form = a: delim_pos
293
- let ln_s = searchpos (' [ ,]\+\zs' , ' z' , lnr , 0 , function (' <SID>InForm' ))
294
-
295
- if ln_s != [0 , 0 ] | return s: PosToCharPos (ln_s)[1 ] - 1 | endif
295
+ let pos = s: FirstFnArgPos (a: delim_pos )
296
+ if pos != [0 , 0 ] | return s: PosToCharPos (pos)[1 ] - 1 | endif
296
297
endif
297
298
298
299
" Fallback indentation for operands. When "clojure_indent_style" is
0 commit comments