@@ -81,6 +81,14 @@ 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 ()
88+ let pos = searchpairpos (' [([{"]' , ' ' , ' [)\]}"]' , ' b' )
89+ return pos != [0 , 0 ] && pos != s: in_form_current_form
90+ endfunction
91+
8492function ! s: PosToCharPos (pos)
8593 call cursor (a: pos )
8694 return getcursorcharpos ()[1 :2 ]
@@ -116,8 +124,6 @@ function! s:TokeniseLine(line_num)
116124 if token == # ' ;' | let possible_comment = 1 | endif
117125 endwhile
118126
119- " echom 'Tokens: ' string(tokens)
120-
121127 return [tokens, possible_comment]
122128endfunction
123129
@@ -185,6 +191,7 @@ function! s:InsideForm(lnum)
185191 let lnum -= 1
186192 endwhile
187193
194+ " TODO: can this conditional be simplified?
188195 if (in_string && first_string_pos != []) || (! empty (tokens) && tokens[0 ][0 ] == # ' "' )
189196 " Must have been in a multi-line string or regular expression
190197 " as the string was never closed.
@@ -236,24 +243,26 @@ function! s:ListIndent(delim_pos)
236243 " - Check against pattern rules and apply indent on match.
237244 " - Look up in rules table and apply indent on match.
238245 " else, not found, go to 2.
239- "
246+
240247 " TODO: handle complex indentation (e.g. letfn) and introduce
241248 " indentation config similar to Emacs' clojure-mode and cljfmt.
242249 " This new config option `clojure_indent_rules` should replace most
243250 " other indentation options.
244- "
245- " TODO: replace `clojure_fuzzy_indent_patterns` with `clojure_indent_patterns`
251+
252+ " TODO: simplify this.
246253 let syms = split (ln [delim_col:], '[[:space:],;()\[\]{}@\\"^~`]', 1)
254+
247255 if ! empty (syms)
248256 let sym = syms[0 ]
249- " TODO: strip #' and ' from front of symbol .
257+ " TODO: if prefixed with "#'" or "'" fallback to func indent .
250258 if sym = ~# ' \v^%([a-zA-Z!$&*_+=|<>?-]|[^\x00-\x7F])'
251259
252260 " TODO: handle namespaced and non-namespaced variants.
253261 if sym = ~# ' ./.'
254262 let [_namespace, name] = split (sym, ' /' )
255263 endif
256264
265+ " TODO: replace `clojure_fuzzy_indent_patterns` with `clojure_indent_patterns`
257266 for pat in s: Conf (' clojure_fuzzy_indent_patterns' , [])
258267 if sym = ~# pat
259268 return base_indent + 1
@@ -272,24 +281,18 @@ function! s:ListIndent(delim_pos)
272281 " - Indent subsequent lines to align with first operand.
273282 " else
274283 " - Indent 1 or 2 spaces.
284+
275285 let indent_style = s: Conf (' clojure_indent_style' , ' always-align' )
276286 if indent_style !=# ' always-indent'
277- let init_col = delim_col + 1
278- call cursor (a: delim_pos [0 ], init_col)
279-
280- " TODO: replace cursor translation with searching?
281- let ch = ln [delim_col]
282- if ch == # ' (' || ch == # ' [' || ch == # ' {'
283- normal ! % w
284- elseif ch !=# ' ;' && ch !=# ' "'
285- normal ! w
286- endif
287+ let lnr = a: delim_pos [0 ]
288+ call cursor (lnr , delim_col + 1 )
287289
288- let cur_pos = getcursorcharpos ()[1 :2 ]
289- if a: delim_pos [0 ] == cur_pos[0 ] && init_col != cur_pos[1 ]
290- " Align operands.
291- return cur_pos[1 ] - 1
292- endif
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
293296 endif
294297
295298 " Fallback indentation for operands. When "clojure_indent_style" is
0 commit comments