@@ -81,14 +81,26 @@ function! s:IsEscaped(line_str, i_char)
8181 return (strlen (ln ) - strlen(trim(ln, '\', 2))) % 2
8282endfunction
8383
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 ()
8898 let pos = searchpairpos (' [([{"]' , ' ' , ' [)\]}"]' , ' b' )
8999 return pos != [0 , 0 ] && pos != s: in_form_current_form
90100endfunction
91101
102+ " Converts a cursor position into a characterwise cursor position (to handle
103+ " multibyte characters).
92104function ! s: PosToCharPos (pos)
93105 call cursor (a: pos )
94106 return getcursorcharpos ()[1 :2 ]
@@ -235,7 +247,6 @@ function! s:ListIndent(delim_pos)
235247
236248 let base_indent = s: PosToCharPos (a: delim_pos )[1 ]
237249 let ln = getline(a:delim_pos[0])
238- let delim_col = a: delim_pos [1 ]
239250
240251 " 1. Macro/rule indentation
241252 " if starts with a symbol, extract it.
@@ -250,7 +261,7 @@ function! s:ListIndent(delim_pos)
250261 " other indentation options.
251262
252263 " TODO: simplify this.
253- let syms = split (ln [delim_col :], '[[:space:],;()\[\]{}@\\"^~`]', 1)
264+ let syms = split (ln [a:delim_pos[1] :], '[[:space:],;()\[\]{}@\\"^~`]', 1)
254265
255266 if ! empty (syms)
256267 let sym = syms[0 ]
@@ -264,9 +275,7 @@ function! s:ListIndent(delim_pos)
264275
265276 " TODO: replace `clojure_fuzzy_indent_patterns` with `clojure_indent_patterns`
266277 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
270279 endfor
271280
272281 let rules = s: Conf (' clojure_indent_rules' , {})
@@ -277,22 +286,14 @@ function! s:ListIndent(delim_pos)
277286 endif
278287
279288 " 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?
281290 " - Indent subsequent lines to align with first operand.
282291 " else
283292 " - Indent 1 or 2 spaces.
284-
285293 let indent_style = s: Conf (' clojure_indent_style' , ' always-align' )
286294 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
296297 endif
297298
298299 " Fallback indentation for operands. When "clojure_indent_style" is
0 commit comments