|
| 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 | + |
1 | 43 | 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) |
3 | 54 | if l:prevlnum ==# 0 |
4 | 55 | return 0 |
5 | 56 | endif |
6 | | - let l:indent = 0 |
| 57 | + let l:shift = 0 |
7 | 58 | 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 |
12 | 71 | 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 |
18 | 86 | 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 |
20 | 89 | endfunction |
21 | 90 |
|
22 | 91 | function! fish#Format() |
|
0 commit comments