| 
									
										
										
										
											2023-02-20 20:44:55 +00:00
										 |  |  | " Vim indent file | 
					
						
							|  |  |  | " Language:     fish | 
					
						
							|  |  |  | " Maintainer:   Nicholas Boyle (github.com/nickeb96) | 
					
						
							|  |  |  | " Repository:   https://github.com/nickeb96/fish.vim | 
					
						
							|  |  |  | " Last Change:  February 4, 2023 | 
					
						
							| 
									
										
										
										
											2023-08-29 05:32:59 +10:00
										 |  |  | "               2023 Aug 28 by Vim Project (undo_indent) | 
					
						
							| 
									
										
										
										
											2023-02-20 20:44:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | if exists("b:did_indent") | 
					
						
							|  |  |  |     finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | let b:did_indent = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | setlocal indentexpr=GetFishIndent(v:lnum) | 
					
						
							|  |  |  | setlocal indentkeys+==end,=else,=case | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 05:32:59 +10:00
										 |  |  | let b:undo_indent = "setlocal indentexpr< indentkeys<" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-20 20:44:55 +00:00
										 |  |  | function s:PrevCmdStart(linenum) | 
					
						
							|  |  |  |     let l:linenum = a:linenum | 
					
						
							|  |  |  |     " look for the first line that isn't a line continuation | 
					
						
							|  |  |  |     while l:linenum > 1 && getline(l:linenum - 1) =~# '\\$' | 
					
						
							|  |  |  |         let l:linenum = l:linenum - 1 | 
					
						
							|  |  |  |     endwhile | 
					
						
							|  |  |  |     return l:linenum | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function GetFishIndent(lnum) | 
					
						
							|  |  |  |     let l:shiftwidth = shiftwidth() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let l:prevlnum = prevnonblank(a:lnum - 1) | 
					
						
							|  |  |  |     if l:prevlnum ==# 0 | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     " if the previous line ended with a line continuation | 
					
						
							|  |  |  |     if getline(a:lnum - 1) =~# '\\$' | 
					
						
							|  |  |  |         if a:lnum ==# 0 || getline(a:lnum - 2) !~# '\\$' | 
					
						
							|  |  |  |             " this is the first line continuation in a chain, so indent it | 
					
						
							|  |  |  |             return indent(a:lnum - 1) + l:shiftwidth | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             " use the same indentation as the previous continued line | 
					
						
							|  |  |  |             return indent(a:lnum - 1) | 
					
						
							|  |  |  |         endif | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let l:prevlnum = s:PrevCmdStart(l:prevlnum) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let l:prevline = getline(l:prevlnum) | 
					
						
							|  |  |  |     if l:prevline =~# '^\s*\(begin\|if\|else\|while\|for\|function\|case\|switch\)\>' | 
					
						
							|  |  |  |         let l:indent = l:shiftwidth | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         let l:indent = 0 | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let l:line = getline(a:lnum) | 
					
						
							|  |  |  |     if l:line =~# '^\s*end\>' | 
					
						
							|  |  |  |         " find end's matching start | 
					
						
							|  |  |  |         let l:depth = 1 | 
					
						
							|  |  |  |         let l:currentlnum = a:lnum | 
					
						
							|  |  |  |         while l:depth > 0 && l:currentlnum > 0 | 
					
						
							|  |  |  |             let l:currentlnum = s:PrevCmdStart(prevnonblank(l:currentlnum - 1)) | 
					
						
							|  |  |  |             let l:currentline = getline(l:currentlnum) | 
					
						
							|  |  |  |             if l:currentline =~# '^\s*end\>' | 
					
						
							|  |  |  |                 let l:depth = l:depth + 1 | 
					
						
							|  |  |  |             elseif l:currentline =~# '^\s*\(begin\|if\|while\|for\|function\|switch\)\>' | 
					
						
							|  |  |  |                 let l:depth = l:depth - 1 | 
					
						
							|  |  |  |             endif | 
					
						
							|  |  |  |         endwhile | 
					
						
							|  |  |  |         if l:currentline =~# '^\s*switch\>' | 
					
						
							|  |  |  |             return indent(l:currentlnum) | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             return indent(l:prevlnum) + l:indent - l:shiftwidth | 
					
						
							|  |  |  |         endif | 
					
						
							|  |  |  |     elseif l:line =~# '^\s*else\>' | 
					
						
							|  |  |  |         return indent(l:prevlnum) + l:indent - l:shiftwidth | 
					
						
							|  |  |  |     elseif l:line =~# '^\s*case\>' | 
					
						
							|  |  |  |         if getline(l:prevlnum) =~# '^\s*switch\>' | 
					
						
							|  |  |  |             return indent(l:prevlnum) + l:indent | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             return indent(l:prevlnum) + l:indent - l:shiftwidth | 
					
						
							|  |  |  |         endif | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return indent(l:prevlnum) + l:indent | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | endfunction |