Skip to content

Commit 2627e1c

Browse files
committed
Add fallback for when Vim was not compiled with searchpairpos
1 parent f4e0689 commit 2627e1c

File tree

1 file changed

+28
-33
lines changed

1 file changed

+28
-33
lines changed

indent/clojure.vim

+28-33
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ let b:did_indent = 1
1515
let s:save_cpo = &cpoptions
1616
set cpoptions&vim
1717

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<'
1919

20-
setlocal noautoindent nosmartindent
20+
setlocal noautoindent nosmartindent nolisp
2121
setlocal softtabstop=2 shiftwidth=2 expandtab
2222
setlocal indentkeys=!,o,O
2323

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?
2725

2826
function! s:GetSynIdName(line, col)
2927
return synIDattr(synID(a:line, a:col, 0), 'name')
@@ -37,11 +35,11 @@ function! s:IgnoredRegion()
3735
return s:SyntaxMatch('\(string\|regex\|comment\|character\)', line('.'), col('.'))
3836
endfunction
3937

40-
function! s:NotAStringDelimiter()
38+
function! s:NotStringDelimiter()
4139
return ! s:SyntaxMatch('stringdelimiter', line('.'), col('.'))
4240
endfunction
4341

44-
function! s:NotARegexpDelimiter()
42+
function! s:NotRegexpDelimiter()
4543
return ! s:SyntaxMatch('regexpdelimiter', line('.'), col('.'))
4644
endfunction
4745

@@ -54,53 +52,53 @@ function! s:ShouldAlignMultiLineStrings()
5452
endfunction
5553

5654
" 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)
6159
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)
6361
if prevln < pos[0] || (prevln == pos[0] && s:best_match[1][1] < pos[1])
6462
let s:best_match = [a:name, pos]
6563
endif
6664
endfunction
6765

6866
function! s:GetClojureIndent()
69-
let lnum = v:lnum
70-
7167
" Move cursor to the first column of the line we want to indent.
72-
cursor(lnum, 0)
68+
call cursor(v:lnum, 0)
7369

7470
let s:best_match = ['top', [0, 0]]
7571

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)
7977

80-
let synname = s:GetSynIdName(lnum, col('.'))
78+
let synname = s:GetSynIdName(v:lnum, col('.'))
8179
if synname =~? 'string'
82-
call s:CheckPair('str', '"', '"', function('<SID>NotAStringDelimiter'))
80+
call s:CheckPair('str', '"', '"', function('<SID>NotStringDelimiter'))
8381
elseif synname =~? 'regex'
84-
call s:CheckPair('reg', '#\zs"', '"', function('<SID>NotARegexpDelimiter'))
82+
call s:CheckPair('reg', '#\zs"', '"', function('<SID>NotRegexpDelimiter'))
8583
endif
8684

8785
" Find closest matching higher form.
8886
let [formtype, coord] = s:best_match
89-
" echom 'Match' formtype coord
9087

9188
if formtype == 'top'
9289
" At the top level, no indent.
9390
return 0
9491
elseif formtype == 'lst'
9592
" Inside a list.
9693
" TODO Begin analysis and apply rules!
97-
" echom getline(coord[0], lnum - 1)
94+
" echom getline(coord[0], v:lnum - 1)
9895
return coord[1] + 1
9996
elseif formtype == 'vec' || formtype == 'map'
10097
" Inside a vector, map or set.
10198
return coord[1]
10299
elseif formtype == 'str'
103100
" Inside a string.
101+
" TODO: maintain string and regex indentation when `=` is pressed.
104102
return coord[1] - (s:ShouldAlignMultiLineStrings() ? 0 : 1)
105103
elseif formtype == 'reg'
106104
" Inside a regex.
@@ -110,16 +108,13 @@ function! s:GetClojureIndent()
110108
return 2
111109
endfunction
112110

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
123118

124119
let &cpoptions = s:save_cpo
125120
unlet! s:save_cpo

0 commit comments

Comments
 (0)