@@ -21,6 +21,9 @@ setlocal noautoindent nosmartindent nolisp
2121setlocal softtabstop = 2 shiftwidth = 2 expandtab
2222setlocal indentkeys = ! ,o ,O
2323
24+ " NOTE: To debug this code, make sure to "set debug+=msg" otherwise errors
25+ " will occur silently.
26+
2427" TODO: After all optimisations create Vim9script variant of the core algorithm.
2528
2629" Returns "1" if position "i_char" in "line_str" is preceded by an odd number
@@ -65,8 +68,9 @@ endfunction
6568
6669let s: pairs = {' (' : ' )' , ' [' : ' ]' , ' {' : ' }' }
6770
68- " TODO: refactor this procedure and optimise.
69- " This procedure is essentially a lightweight Clojure reader.
71+ " This procedure is kind of like a really lightweight Clojure reader. It
72+ " looks at the lines above the current line, tokenises them (from right to
73+ " left), and performs reductions to find the parent form and where it is.
7074function ! s: InsideForm (lnum)
7175 " Reset cursor to first column of the line we wish to indent.
7276 call cursor (a: lnum , 1 )
@@ -80,25 +84,29 @@ function! s:InsideForm(lnum)
8084 while lnum > 0
8185 " Reduce tokens from line "lnum" into "tokens".
8286 for tk in s: TokeniseLine (lnum)
83- " Keep track of the first string delimiter we see, as
84- " we'll need it later for multi-line strings/regexps.
85- if first_string_pos == [] && tk[0 ] == # ' "'
86- let first_string_pos = tk[1 ]
87- endif
87+ if tk[0 ] == # ' "'
88+ " Keep track of the first string delimiter we
89+ " see, as we'll need it later for multi-line
90+ " strings/regexps.
91+ if first_string_pos == []
92+ let first_string_pos = tk[1 ]
93+ endif
94+
95+ if ! empty (tokens) && tokens[-1 ][0 ] == # ' "'
96+ let in_string = 0
97+ call remove (tokens, -1 )
98+ else
99+ let in_string = 1
100+ call add (tokens, tk)
101+ endif
88102
89- " When in string ignore other tokens.
90- if in_string && tk[0 ] !=# ' "'
91103 continue
92- else
93- let in_string = 0
94104 endif
95105
96- " TODO: early termination?
97- if empty (tokens)
98- call add (tokens, tk)
99- elseif tk[0 ] == # ' "' && tokens[-1 ][0 ] == # ' "'
100- call remove (tokens, -1 )
101- elseif get (s: pairs , tk[0 ], ' ' ) == # tokens[-1 ][0 ]
106+ " When in string ignore other tokens.
107+ if in_string | continue | endif
108+
109+ if ! empty (tokens) && get (s: pairs , tk[0 ], ' ' ) == # tokens[-1 ][0 ]
102110 " Matching pair: drop the last item in tokens.
103111 call remove (tokens, -1 )
104112 else
@@ -184,6 +192,7 @@ function! s:ClojureIndent()
184192endfunction
185193
186194" TODO: set lispoptions if exists.
195+ " https://github.com/vim/vim/commit/49846fb1a31de99f49d6a7e70efe685197423c84
187196setlocal indentexpr = s: ClojureIndent ()
188197
189198let &cpoptions = s: save_cpo
0 commit comments