@@ -41,7 +41,7 @@ function! s:SyntaxMatch(pattern, line, col)
41
41
endfunction
42
42
43
43
function ! s: IgnoredRegion ()
44
- return s: SyntaxMatch (' \vstring |regex|comment|character' , line (' .' ), col (' .' ))
44
+ return s: SyntaxMatch (' \(string\ |regex\ |comment\ |character\) ' , line (' .' ), col (' .' ))
45
45
endfunction
46
46
47
47
function ! s: NotAStringDelimiter ()
@@ -80,47 +80,59 @@ function! s:ClosestMatch(match1, match2)
80
80
endif
81
81
endfunction
82
82
83
+ " Wrapper around "searchpairpos" that will automatically set "s:best_match" to
84
+ " the closest pair match and continuously optimise the "stopline" value for
85
+ " later searches. This results in a significant performance gain by reducing
86
+ " the number of syntax lookups that need to take place.
87
+ function ! s: CheckPair (name, start , end , skipfn)
88
+ let pos = searchpairpos (a: start , ' ' , a: end , ' bznW' , a: skipfn , s: best_match [1 ][0 ])
89
+ let s: best_match = s: ClosestMatch (s: best_match , [a: name , pos])
90
+ endfunction
91
+
83
92
" Only need to search up. Never down.
84
93
function ! s: GetClojureIndent ()
85
94
let lnum = v: lnum
86
95
87
96
" Move cursor to the first column of the line we want to indent.
88
97
cursor (lnum, 0 )
89
98
90
- let matches = [
91
- \ [' lst' , searchpairpos ( ' (' , ' ' , ' )' , ' bznW' , function (' <SID>IgnoredRegion' ))],
92
- \ [' vec' , searchpairpos (' \[' , ' ' , ' \]' , ' bznW' , function (' <SID>IgnoredRegion' ))],
93
- \ [' map' , searchpairpos ( ' {' , ' ' , ' }' , ' bznW' , function (' <SID>IgnoredRegion' ))],
94
- \ [' reg' , s: IsInRegex () ? searchpairpos (' #\zs"' , ' ' , ' "' , ' bznW' , function (' <SID>NotARegexpDelimiter' )) : [0 , 0 ]],
95
- \ [' str' , s: IsInString () ? searchpairpos (' "' , ' ' , ' "' , ' bznW' , function (' <SID>NotAStringDelimiter' )) : [0 , 0 ]]
96
- \ ]
97
- echom ' Matches' matches
99
+ let s: best_match = [' top' , [0 , 0 ]]
100
+
101
+ call s: CheckPair (' lst' , ' (' , ' )' , function (' <SID>IgnoredRegion' ))
102
+ call s: CheckPair (' vec' , ' \[' , ' \]' , function (' <SID>IgnoredRegion' ))
103
+ call s: CheckPair (' map' , ' {' , ' }' , function (' <SID>IgnoredRegion' ))
104
+
105
+ if s: IsInString ()
106
+ call s: CheckPair (' str' , ' "' , ' "' , function (' <SID>NotAStringDelimiter' ))
107
+ elseif s: IsInRegex ()
108
+ call s: CheckPair (' reg' , ' #\zs"' , ' "' , function (' <SID>NotARegexpDelimiter' ))
109
+ endif
98
110
99
111
" Find closest matching higher form.
100
- let [formtype, coord] = reduce (matches, function ( ' <SID>ClosestMatch ' ), [ ' top ' , [ 0 , 0 ]])
101
- echom ' Match' formtype coord
112
+ let [formtype, coord] = s: best_match
113
+ " echom 'Match' formtype coord
102
114
103
115
if formtype == ' top'
104
116
" At the top level, no indent.
105
- echom ' At the top level!'
117
+ " echom 'At the top level!'
106
118
return 0
107
119
elseif formtype == ' lst'
108
- echom ' Special format rules!'
120
+ " echom 'Special format rules!'
109
121
" TODO
110
122
" Grab text!
111
- echom getline (coord[0 ], lnum - 1 )
123
+ " echom getline(coord[0], lnum - 1)
112
124
" Begin lexing!
113
125
return coord[1 ] + 1
114
126
elseif formtype == ' vec' || formtype == ' map'
115
127
" Inside a vector, map or set.
116
128
return coord[1 ]
117
129
elseif formtype == ' reg'
118
130
" Inside a regex.
119
- echom ' Inside a regex!'
131
+ " echom 'Inside a regex!'
120
132
return coord[1 ] - (s: ShouldAlignMultiLineStrings () ? 0 : 2 )
121
133
elseif formtype == ' str'
122
134
" Inside a string.
123
- echom ' Inside a string!'
135
+ " echom 'Inside a string!'
124
136
return coord[1 ] - (s: ShouldAlignMultiLineStrings () ? 0 : 1 )
125
137
endif
126
138
0 commit comments