Bram Moolenaar | 938ae28 | 2023-02-20 20:44:55 +0000 | [diff] [blame] | 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 |
dkearns | 0382f05 | 2023-08-29 05:32:59 +1000 | [diff] [blame] | 6 | " 2023 Aug 28 by Vim Project (undo_indent) |
Bram Moolenaar | 938ae28 | 2023-02-20 20:44:55 +0000 | [diff] [blame] | 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 | |
dkearns | 0382f05 | 2023-08-29 05:32:59 +1000 | [diff] [blame] | 16 | let b:undo_indent = "setlocal indentexpr< indentkeys<" |
| 17 | |
Bram Moolenaar | 938ae28 | 2023-02-20 20:44:55 +0000 | [diff] [blame] | 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 |