@@ -15,15 +15,13 @@ let b:did_indent = 1
15
15
let s: save_cpo = &cpoptions
16
16
set cpoptions &vim
17
17
18
- let b: undo_indent = ' setlocal autoindent< smartindent< expandtab< softtabstop< shiftwidth< indentexpr< indentkeys<'
18
+ let b: undo_indent = ' setlocal autoindent< smartindent< expandtab< softtabstop< shiftwidth< indentexpr< indentkeys< lisp< '
19
19
20
- setlocal noautoindent nosmartindent
20
+ setlocal noautoindent nosmartindent nolisp
21
21
setlocal softtabstop = 2 shiftwidth = 2 expandtab
22
22
setlocal indentkeys = ! ,o ,O
23
23
24
- " TODO: ignore 'lisp' and 'lispwords' options (actually, turn them off?)
25
- " TODO: Optional Vim9script implementations of hotspot/bottleneck functions?
26
- " FIXME: fallback case when syntax highlighting is disabled.
24
+ " TODO: Write an optional Vim9 script version for better performance?
27
25
28
26
function ! s: GetSynIdName (line , col )
29
27
return synIDattr (synID (a: line , a: col , 0 ), ' name' )
@@ -37,11 +35,11 @@ function! s:IgnoredRegion()
37
35
return s: SyntaxMatch (' \(string\|regex\|comment\|character\)' , line (' .' ), col (' .' ))
38
36
endfunction
39
37
40
- function ! s: NotAStringDelimiter ()
38
+ function ! s: NotStringDelimiter ()
41
39
return ! s: SyntaxMatch (' stringdelimiter' , line (' .' ), col (' .' ))
42
40
endfunction
43
41
44
- function ! s: NotARegexpDelimiter ()
42
+ function ! s: NotRegexpDelimiter ()
45
43
return ! s: SyntaxMatch (' regexpdelimiter' , line (' .' ), col (' .' ))
46
44
endfunction
47
45
@@ -54,53 +52,53 @@ function! s:ShouldAlignMultiLineStrings()
54
52
endfunction
55
53
56
54
" Wrapper around "searchpairpos" that will automatically set "s:best_match" to
57
- " the closest pair match and continuously optimise the "stopline" value for
58
- " later searches. This results in a significant performance gain by reducing
59
- " the number of syntax lookups that need to take place.
60
- function ! s: CheckPair (name, start , end , skipfn )
55
+ " the closest pair match and optimises the "stopline" value for later
56
+ " searches. This results in a significant performance gain by reducing the
57
+ " number of syntax lookups that need to take place.
58
+ function ! s: CheckPair (name, start , end , SkipFn )
61
59
let prevln = s: best_match [1 ][0 ]
62
- let pos = searchpairpos (a: start , ' ' , a: end , ' bznW' , a: skipfn , prevln)
60
+ let pos = searchpairpos (a: start , ' ' , a: end , ' bznW' , a: SkipFn , prevln)
63
61
if prevln < pos[0 ] || (prevln == pos[0 ] && s: best_match [1 ][1 ] < pos[1 ])
64
62
let s: best_match = [a: name , pos]
65
63
endif
66
64
endfunction
67
65
68
66
function ! s: GetClojureIndent ()
69
- let lnum = v: lnum
70
-
71
67
" Move cursor to the first column of the line we want to indent.
72
- cursor (lnum, 0 )
68
+ call cursor (v: lnum , 0 )
73
69
74
70
let s: best_match = [' top' , [0 , 0 ]]
75
71
76
- call s: CheckPair (' lst' , ' (' , ' )' , function (' <SID>IgnoredRegion' ))
77
- call s: CheckPair (' map' , ' {' , ' }' , function (' <SID>IgnoredRegion' ))
78
- call s: CheckPair (' vec' , ' \[' , ' \]' , function (' <SID>IgnoredRegion' ))
72
+ let IgnoredRegionFn = function (' <SID>IgnoredRegion' )
73
+
74
+ call s: CheckPair (' lst' , ' (' , ' )' , IgnoredRegionFn)
75
+ call s: CheckPair (' map' , ' {' , ' }' , IgnoredRegionFn)
76
+ call s: CheckPair (' vec' , ' \[' , ' \]' , IgnoredRegionFn)
79
77
80
- let synname = s: GetSynIdName (lnum, col (' .' ))
78
+ let synname = s: GetSynIdName (v: lnum , col (' .' ))
81
79
if synname = ~? ' string'
82
- call s: CheckPair (' str' , ' "' , ' "' , function (' <SID>NotAStringDelimiter ' ))
80
+ call s: CheckPair (' str' , ' "' , ' "' , function (' <SID>NotStringDelimiter ' ))
83
81
elseif synname = ~? ' regex'
84
- call s: CheckPair (' reg' , ' #\zs"' , ' "' , function (' <SID>NotARegexpDelimiter ' ))
82
+ call s: CheckPair (' reg' , ' #\zs"' , ' "' , function (' <SID>NotRegexpDelimiter ' ))
85
83
endif
86
84
87
85
" Find closest matching higher form.
88
86
let [formtype, coord] = s: best_match
89
- " echom 'Match' formtype coord
90
87
91
88
if formtype == ' top'
92
89
" At the top level, no indent.
93
90
return 0
94
91
elseif formtype == ' lst'
95
92
" Inside a list.
96
93
" TODO Begin analysis and apply rules!
97
- " echom getline(coord[0], lnum - 1)
94
+ " echom getline(coord[0], v: lnum - 1)
98
95
return coord[1 ] + 1
99
96
elseif formtype == ' vec' || formtype == ' map'
100
97
" Inside a vector, map or set.
101
98
return coord[1 ]
102
99
elseif formtype == ' str'
103
100
" Inside a string.
101
+ " TODO: maintain string and regex indentation when `=` is pressed.
104
102
return coord[1 ] - (s: ShouldAlignMultiLineStrings () ? 0 : 1 )
105
103
elseif formtype == ' reg'
106
104
" Inside a regex.
@@ -110,16 +108,13 @@ function! s:GetClojureIndent()
110
108
return 2
111
109
endfunction
112
110
113
-
114
- setlocal indentexpr = s: GetClojureIndent ()
115
-
116
-
117
- " TODO: if exists("*searchpairpos")
118
- " In case we have searchpairpos not available we fall back to normal lisp
119
- " indenting.
120
- " setlocal indentexpr=
121
- " setlocal lisp
122
- " let b:undo_indent .= '| setlocal lisp<'
111
+ if exists (" *searchpairpos" )
112
+ setlocal indentexpr = s: GetClojureIndent ()
113
+ else
114
+ " If searchpairpos is not available, fallback to normal lisp
115
+ " indenting.
116
+ setlocal lisp indentexpr =
117
+ endif
123
118
124
119
let &cpoptions = s: save_cpo
125
120
unlet ! s: save_cpo
0 commit comments