Skip to content

Commit c3047be

Browse files
committed
Mimic multi-line string/regex indent behaviour of VS Code and Emacs
The `=` operator will no longer alter the indent of lines within a Clojure multi-line string or regular expression. The previous behaviour was annoying for writing detailed doc-strings, as it made reformatting the file with `gg=G` not possible as it would screw up the indentation within the doc-strings. Now the behaviour matches that of VS Code and Emacs.
1 parent d1ec02c commit c3047be

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

indent/clojure.vim

+29-12
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ function! s:Conf(opt, default)
4646
endfunction
4747

4848
function! s:ShouldAlignMultiLineStrings()
49+
" TODO: third option "-1" to default to "no indent", like traditional
50+
" lisps?
4951
return s:Conf('clojure_align_multiline_strings', 0)
5052
endfunction
5153

@@ -89,27 +91,42 @@ function! s:GetClojureIndent()
8991
" Find closest matching higher form.
9092
let [formtype, coord] = s:best_match
9193

92-
if formtype == 'top'
94+
if formtype ==# 'top'
9395
" At the top level, no indent.
9496
return 0
95-
elseif formtype == 'lst'
97+
elseif formtype ==# 'lst'
9698
" Inside a list.
9799
" TODO Begin analysis and apply rules!
98100
" echom getline(coord[0], v:lnum - 1)
99101
return coord[1] + 1
100-
elseif formtype == 'vec' || formtype == 'map'
102+
elseif formtype ==# 'vec' || formtype ==# 'map'
101103
" Inside a vector, map or set.
102104
return coord[1]
103-
elseif formtype == 'str'
104-
" Inside a string.
105-
" TODO: maintain string and regex indentation when `=` is pressed.
106-
return coord[1] - (s:ShouldAlignMultiLineStrings() ? 0 : 1)
107-
elseif formtype == 'reg'
108-
" Inside a regex.
109-
return coord[1] - (s:ShouldAlignMultiLineStrings() ? 0 : 2)
110-
else
111-
return -1
105+
elseif formtype ==# 'str' || formtype ==# 'reg'
106+
" Mimic multi-line string indentation behaviour in VS Code and
107+
" Emacs.
108+
"
109+
" Scenarios:
110+
" - "=" operator should NOT alter indentation within
111+
" multi-line strings.
112+
" - Changes made while in insert mode (e.g. "<CR>"), should
113+
" use standard string indent.
114+
" - All other commands from normal mode (e.g. "o" and "O")
115+
" should trigger normal string indent.
116+
117+
let m = mode()
118+
if m ==# 'i' || (m ==# 'n' && ! (v:operator ==# '=' && state() =~# 'o'))
119+
" If in insert mode, or (in normal mode and last
120+
" operator is not "=" and is not currently active.
121+
let l:indent = (s:ShouldAlignMultiLineStrings()
122+
\ ? 0
123+
\ : (formtype ==# 'reg' ? 2 : 1))
124+
return coord[1] - l:indent
125+
endif
112126
endif
127+
128+
" Keep existing indent.
129+
return -1
113130
endfunction
114131

115132
if exists("*searchpairpos")

0 commit comments

Comments
 (0)