Skip to content

Commit b771d51

Browse files
committed
Improve fish#Indent().
1 parent 825853f commit b771d51

File tree

2 files changed

+82
-12
lines changed

2 files changed

+82
-12
lines changed

autoload/fish.vim

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,91 @@
1+
function! s:IsString(lnum, col)
2+
let l:stack = map(synstack(a:lnum, a:col), 'synIDattr(v:val, "name")')
3+
return len(filter(l:stack, 'v:val ==# "fishString"'))
4+
endfunction
5+
6+
function! s:IsContinuedLine(lnum)
7+
return getline(a:lnum - 1) =~ '\v\\$'
8+
endfunction
9+
10+
function! s:FindPrevLnum(lnum)
11+
if a:lnum < 1
12+
return 0
13+
endif
14+
let l:lnum = prevnonblank(a:lnum)
15+
while l:lnum > 0 && ( s:IsContinuedLine(l:lnum) || s:IsString(l:lnum, 1) )
16+
let l:lnum = prevnonblank(l:lnum - 1)
17+
endwhile
18+
return l:lnum
19+
endfunction
20+
21+
function! s:IsEndOfSwitch(lnum)
22+
let l:lnum = a:lnum
23+
let l:line = getline(l:lnum)
24+
let l:in_block = 0
25+
let l:stop_pat = '\v^\s*%(if|else|while|for|begin)>'
26+
let l:block_start_pat = '\v^\s*%(if|while|for|switch|begin)>'
27+
while l:lnum > 0
28+
let l:lnum = prevnonblank(l:lnum - 1)
29+
let l:line = getline(l:lnum)
30+
if l:line =~# '\v^\s*end>'
31+
let l:in_block += 1
32+
elseif l:in_block && l:line =~# l:block_start_pat
33+
let l:in_block -= 1
34+
elseif !l:in_block && l:line =~# l:stop_pat
35+
return 0
36+
elseif !l:in_block && l:line =~# '\v^\s*switch>'
37+
return 1
38+
endif
39+
endwhile
40+
return 0
41+
endfunction
42+
143
function! fish#Indent()
2-
let l:prevlnum = prevnonblank(v:lnum - 1)
44+
let l:line = getline(v:lnum)
45+
if s:IsString(v:lnum, 1)
46+
return indent(v:lnum)
47+
endif
48+
if exists('*shiftwidth')
49+
let l:shiftwidth = shiftwidth()
50+
else
51+
let l:shiftwidth = &shiftwidth
52+
endif
53+
let l:prevlnum = s:FindPrevLnum(v:lnum - 1)
354
if l:prevlnum ==# 0
455
return 0
556
endif
6-
let l:indent = 0
57+
let l:shift = 0
758
let l:prevline = getline(l:prevlnum)
8-
if l:prevline =~# '\v^\s*switch>'
9-
let l:indent = &shiftwidth * 2
10-
elseif l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case)>'
11-
let l:indent = &shiftwidth
59+
let l:previndent = indent(l:prevlnum)
60+
if s:IsContinuedLine(v:lnum)
61+
let l:previndent = indent(v:lnum - 1)
62+
if s:IsContinuedLine(v:lnum - 1)
63+
return l:previndent
64+
elseif exists('g:fish_indent_cont')
65+
return l:previndent + (g:fish_indent_cont * &sw)
66+
elseif exists('g:indent_cont')
67+
return l:previndent + (g:indent_cont * &sw)
68+
else
69+
return l:previndent + (3 * &sw)
70+
endif
1271
endif
13-
let l:line = getline(v:lnum)
14-
if l:line =~# '\v^\s*end>'
15-
return indent(v:lnum) - (l:indent ==# 0 ? &shiftwidth : l:indent)
16-
elseif l:line =~# '\v^\s*%(case|else)>'
17-
return indent(v:lnum) - &shiftwidth
72+
if l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case|switch)>'
73+
let l:shift += 1
74+
endif
75+
if l:line =~# '\v^\s*%(end|case|else)>'
76+
let l:shift -= 1
77+
endif
78+
if l:line =~# '\v^\s*<case>' && l:prevline =~# '\v<switch>'
79+
let l:shift += 1
80+
endif
81+
if l:line =~# '\v\s*end>' && s:IsEndOfSwitch(v:lnum)
82+
let l:shift -= 1
83+
endif
84+
if l:prevline =~# '\v^\s*%(if|while|for|else|switch|end)>.*<begin>'
85+
let l:shift += 1
1886
endif
19-
return indent(l:prevlnum) + l:indent
87+
let l:indent = l:previndent + l:shift * l:shiftwidth
88+
return l:indent < 0 ? 0 : l:indent
2089
endfunction
2190

2291
function! fish#Format()

indent/fish.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
setlocal indentexpr=fish#Indent()
2+
setlocal indentkeys=!^F,o,O
23
setlocal indentkeys+==end,=else,=case

0 commit comments

Comments
 (0)