fish.vim (2719B)
1 " Vim indent file 2 " Language: fish 3 " Maintainer: Nicholas Boyle (github.com/nickeb96) 4 " Repository: https://github.com/nickeb96/fish.vim 5 " Last Change: February 4, 2023 6 " 2023 Aug 28 by Vim Project (undo_indent) 7 8 if exists("b:did_indent") 9 finish 10 endif 11 let b:did_indent = 1 12 13 setlocal indentexpr=GetFishIndent(v:lnum) 14 setlocal indentkeys+==end,=else,=case 15 16 let b:undo_indent = "setlocal indentexpr< indentkeys<" 17 18 function s:PrevCmdStart(linenum) 19 let l:linenum = a:linenum 20 " look for the first line that isn't a line continuation 21 while l:linenum > 1 && getline(l:linenum - 1) =~# '\\$' 22 let l:linenum = l:linenum - 1 23 endwhile 24 return l:linenum 25 endfunction 26 27 function GetFishIndent(lnum) 28 let l:shiftwidth = shiftwidth() 29 30 let l:prevlnum = prevnonblank(a:lnum - 1) 31 if l:prevlnum ==# 0 32 return 0 33 endif 34 35 " if the previous line ended with a line continuation 36 if getline(a:lnum - 1) =~# '\\$' 37 if a:lnum ==# 0 || getline(a:lnum - 2) !~# '\\$' 38 " this is the first line continuation in a chain, so indent it 39 return indent(a:lnum - 1) + l:shiftwidth 40 else 41 " use the same indentation as the previous continued line 42 return indent(a:lnum - 1) 43 endif 44 endif 45 46 let l:prevlnum = s:PrevCmdStart(l:prevlnum) 47 48 let l:prevline = getline(l:prevlnum) 49 if l:prevline =~# '^\s*\(begin\|if\|else\|while\|for\|function\|case\|switch\)\>' 50 let l:indent = l:shiftwidth 51 else 52 let l:indent = 0 53 endif 54 55 let l:line = getline(a:lnum) 56 if l:line =~# '^\s*end\>' 57 " find end's matching start 58 let l:depth = 1 59 let l:currentlnum = a:lnum 60 while l:depth > 0 && l:currentlnum > 0 61 let l:currentlnum = s:PrevCmdStart(prevnonblank(l:currentlnum - 1)) 62 let l:currentline = getline(l:currentlnum) 63 if l:currentline =~# '^\s*end\>' 64 let l:depth = l:depth + 1 65 elseif l:currentline =~# '^\s*\(begin\|if\|while\|for\|function\|switch\)\>' 66 let l:depth = l:depth - 1 67 endif 68 endwhile 69 if l:currentline =~# '^\s*switch\>' 70 return indent(l:currentlnum) 71 else 72 return indent(l:prevlnum) + l:indent - l:shiftwidth 73 endif 74 elseif l:line =~# '^\s*else\>' 75 return indent(l:prevlnum) + l:indent - l:shiftwidth 76 elseif l:line =~# '^\s*case\>' 77 if getline(l:prevlnum) =~# '^\s*switch\>' 78 return indent(l:prevlnum) + l:indent 79 else 80 return indent(l:prevlnum) + l:indent - l:shiftwidth 81 endif 82 else 83 return indent(l:prevlnum) + l:indent 84 endif 85 endfunction