From b771d5191d8d2b16014c90d5bbd53e3229c49de0 Mon Sep 17 00:00:00 2001 From: Israel Chauca Fuentes Date: Fri, 12 Jun 2015 13:28:58 -0400 Subject: [PATCH] Improve fish#Indent(). --- autoload/fish.vim | 93 +++++++++++++++++++++++++++++++++++++++++------ indent/fish.vim | 1 + 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/autoload/fish.vim b/autoload/fish.vim index 0a0a5a8..283dfaf 100644 --- a/autoload/fish.vim +++ b/autoload/fish.vim @@ -1,22 +1,91 @@ +function! s:IsString(lnum, col) + let l:stack = map(synstack(a:lnum, a:col), 'synIDattr(v:val, "name")') + return len(filter(l:stack, 'v:val ==# "fishString"')) +endfunction + +function! s:IsContinuedLine(lnum) + return getline(a:lnum - 1) =~ '\v\\$' +endfunction + +function! s:FindPrevLnum(lnum) + if a:lnum < 1 + return 0 + endif + let l:lnum = prevnonblank(a:lnum) + while l:lnum > 0 && ( s:IsContinuedLine(l:lnum) || s:IsString(l:lnum, 1) ) + let l:lnum = prevnonblank(l:lnum - 1) + endwhile + return l:lnum +endfunction + +function! s:IsEndOfSwitch(lnum) + let l:lnum = a:lnum + let l:line = getline(l:lnum) + let l:in_block = 0 + let l:stop_pat = '\v^\s*%(if|else|while|for|begin)>' + let l:block_start_pat = '\v^\s*%(if|while|for|switch|begin)>' + while l:lnum > 0 + let l:lnum = prevnonblank(l:lnum - 1) + let l:line = getline(l:lnum) + if l:line =~# '\v^\s*end>' + let l:in_block += 1 + elseif l:in_block && l:line =~# l:block_start_pat + let l:in_block -= 1 + elseif !l:in_block && l:line =~# l:stop_pat + return 0 + elseif !l:in_block && l:line =~# '\v^\s*switch>' + return 1 + endif + endwhile + return 0 +endfunction + function! fish#Indent() - let l:prevlnum = prevnonblank(v:lnum - 1) + let l:line = getline(v:lnum) + if s:IsString(v:lnum, 1) + return indent(v:lnum) + endif + if exists('*shiftwidth') + let l:shiftwidth = shiftwidth() + else + let l:shiftwidth = &shiftwidth + endif + let l:prevlnum = s:FindPrevLnum(v:lnum - 1) if l:prevlnum ==# 0 return 0 endif - let l:indent = 0 + let l:shift = 0 let l:prevline = getline(l:prevlnum) - if l:prevline =~# '\v^\s*switch>' - let l:indent = &shiftwidth * 2 - elseif l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case)>' - let l:indent = &shiftwidth + let l:previndent = indent(l:prevlnum) + if s:IsContinuedLine(v:lnum) + let l:previndent = indent(v:lnum - 1) + if s:IsContinuedLine(v:lnum - 1) + return l:previndent + elseif exists('g:fish_indent_cont') + return l:previndent + (g:fish_indent_cont * &sw) + elseif exists('g:indent_cont') + return l:previndent + (g:indent_cont * &sw) + else + return l:previndent + (3 * &sw) + endif endif - let l:line = getline(v:lnum) - if l:line =~# '\v^\s*end>' - return indent(v:lnum) - (l:indent ==# 0 ? &shiftwidth : l:indent) - elseif l:line =~# '\v^\s*%(case|else)>' - return indent(v:lnum) - &shiftwidth + if l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case|switch)>' + let l:shift += 1 + endif + if l:line =~# '\v^\s*%(end|case|else)>' + let l:shift -= 1 + endif + if l:line =~# '\v^\s*' && l:prevline =~# '\v' + let l:shift += 1 + endif + if l:line =~# '\v\s*end>' && s:IsEndOfSwitch(v:lnum) + let l:shift -= 1 + endif + if l:prevline =~# '\v^\s*%(if|while|for|else|switch|end)>.*' + let l:shift += 1 endif - return indent(l:prevlnum) + l:indent + let l:indent = l:previndent + l:shift * l:shiftwidth + return l:indent < 0 ? 0 : l:indent endfunction function! fish#Format() diff --git a/indent/fish.vim b/indent/fish.vim index d1ef6be..5e780b7 100644 --- a/indent/fish.vim +++ b/indent/fish.vim @@ -1,2 +1,3 @@ setlocal indentexpr=fish#Indent() +setlocal indentkeys=!^F,o,O setlocal indentkeys+==end,=else,=case