commit f9b94021b062d68a7c3f7a6a5c9ebbb19d6ff2d5
parent af403165ac40091099fe717d58780df3be181942
Author: Alex Balgavy <alex@balgavy.eu>
Date: Wed, 6 Oct 2021 19:39:09 +0200
vim: fix statusline mixed indent
Diffstat:
1 file changed, 85 insertions(+), 58 deletions(-)
diff --git a/vim/autoload/statusline.vim b/vim/autoload/statusline.vim
@@ -1,99 +1,126 @@
" return '[&et]' if &et is set wrong
" return '[mixed-indenting]' if spaces and tabs are used to indent
" return an empty string if everything is fine
-function! statusline#StatuslineTabWarning()
- if &readonly || &bt == "nofile"
- return ""
- endif
-
- if !exists("b:statusline_tab_warning")
- let tabs = search('^\t', 'nw') != 0
- let spaces = search('^ \{' . &ts . ',}[^\t]', 'nw') != 0
+"
+" Indentation functions borrowed from airline, they do this pretty well.
+" Mixed indentation within a line. Returns the line number, or 0.
+function! s:check_mixed_line_indent()
+ " [<tab>]<space><tab>
+ " spaces before or between tabs are not allowed
+ let t_s_t = '(^\t* +\t\s*\S)'
+ " <tab>(<space> x count)
+ " count of spaces at the end of tabs should be less than tabstop value
+ let t_l_s = '(^\t+ {' . &ts . ',}' . '\S)'
+ return search('\v' . t_s_t . '|' . t_l_s, 'nw')
+endfunction
- if tabs && spaces
- let b:statusline_tab_warning = '[mixed-indenting]'
- elseif (spaces && !&et) || (tabs && &et)
- let b:statusline_tab_warning = '[&et]'
+" Mixed indentation across the file. Returns line numbers
+" with_tabs:with_spaces, or empty string
+function! s:check_mixed_indent_file()
+ let c_like_langs = ['arduino', 'c', 'cpp', 'cuda', 'go', 'javascript', 'ld', 'php' ]
+ if index(c_like_langs, &ft) > -1
+ " for C-like languages: allow /** */ comment style with one space before the '*'
+ let head_spc = '\v(^ +\*@!)'
+ else
+ let head_spc = '\v(^ +)'
+ endif
+ let indent_tabs = search('\v(^\t+)', 'nw')
+ let indent_spc = search(head_spc, 'nw')
+ if indent_tabs > 0 && indent_spc > 0
+ return printf("%d:%d", indent_tabs, indent_spc)
else
- let b:statusline_tab_warning = ''
+ return ''
+ endif
+endfunction
+
+function! statusline#StatuslineTabWarning()
+ if &readonly || &bt == "nofile"
+ return ""
+ endif
+
+ if !exists("b:statusline_tab_warning")
+ let mixed_on_line = s:check_mixed_line_indent()
+ let mixed_on_line_str = mixed_on_line ==# 0 ? '' : '[mixed-line '..mixed_on_line..']'
+ let mixed_in_file = s:check_mixed_indent_file()
+ let mixed_in_file_str = empty(mixed_in_file) ? '' : '[mixed-indenting '..mixed_in_file..']'
+ let b:statusline_tab_warning = mixed_on_line_str .. mixed_in_file_str
endif
- endif
- return b:statusline_tab_warning
+ return b:statusline_tab_warning
endfunction
" return '[\s]' if trailing white space is detected
" return '' otherwise
function! statusline#StatuslineTrailingSpaceWarning()
- if &readonly || &bt == "nofile"
- return ""
- endif
+ if &readonly || &bt == "nofile"
+ return ""
+ endif
- if !exists("b:statusline_trailing_space_warning")
- if search('\s\+$', 'nw') != 0
- let b:statusline_trailing_space_warning = '[\s]'
- else
- let b:statusline_trailing_space_warning = ''
+ if !exists("b:statusline_trailing_space_warning")
+ if search('\s\+$', 'nw') != 0
+ let b:statusline_trailing_space_warning = '[\s]'
+ else
+ let b:statusline_trailing_space_warning = ''
+ endif
endif
- endif
- return b:statusline_trailing_space_warning
+ return b:statusline_trailing_space_warning
endfunction
" build the current working directory string
function! statusline#StatuslineBuildCwd()
- let cwd = substitute(getcwd(),$HOME,'~','g')
- return "(".cwd.")"
+ let cwd = substitute(getcwd(),$HOME,'~','g')
+ return "(".cwd.")"
endfunction
" get the current fold info
function! statusline#StatuslineFoldmethod()
- if &foldmethod == "indent"
- return "z".&foldlevel.",c".foldlevel(line('.'))
- elseif &foldmethod == "expr"
- return "f:exp,l".&foldlevel
- else
- return "f:".strpart(&foldmethod, 0, 4)
- endif
+ if &foldmethod == "indent"
+ return "z".&foldlevel.",c".foldlevel(line('.'))
+ elseif &foldmethod == "expr"
+ return "f:exp,l".&foldlevel
+ else
+ return "f:".strpart(&foldmethod, 0, 4)
+ endif
endfunction
" print the textwrap information (textwidth or wrapmargin)
function! statusline#StatuslineWrapCol()
- if &textwidth == 0 && &wrapmargin == 0 && &wrap
- return "softwrap"
- endif
- if &textwidth == 0
- return "⟺ ".(winwidth(0)-&wrapmargin)."(M".&wrapmargin.")"
- else
- return "⟺ ".&textwidth
- endif
+ if &textwidth == 0 && &wrapmargin == 0 && &wrap
+ return "softwrap"
+ endif
+ if &textwidth == 0
+ return "⟺ ".(winwidth(0)-&wrapmargin)."(M".&wrapmargin.")"
+ else
+ return "⟺ ".&textwidth
+ endif
endfunction
function! statusline#StatuslineSpacesUsed()
- if &expandtab
- return (&shiftwidth ># 0 ? &shiftwidth : &tabstop)
- else
- if &shiftwidth ==# &tabstop
- return &shiftwidth
+ if &expandtab
+ return (&shiftwidth ># 0 ? &shiftwidth : &tabstop)
else
- return &tabstop."s".&shiftwidth
+ if &shiftwidth ==# &tabstop
+ return &shiftwidth
+ else
+ return &tabstop."s".&shiftwidth
+ endif
endif
- endif
endfunction
function! statusline#StatuslineWordCount()
- return wordcount().words . " words"
+ return wordcount().words . " words"
endfunction
function! statusline#StatuslineVimtexCompiler()
- if exists('b:vimtex.compiler') && b:vimtex.compiler.is_running()
- return '⚙︎ {'.(fnamemodify(b:vimtex.compiler.target_path, ":p:.")).'}'
- endif
- return ''
+ if exists('b:vimtex.compiler') && b:vimtex.compiler.is_running()
+ return '⚙︎ {'.(fnamemodify(b:vimtex.compiler.target_path, ":p:.")).'}'
+ endif
+ return ''
endfunction
function! statusline#StatuslineRemoteFile()
- if exists('b:netrw_lastfile')
- return ' ('.b:netrw_lastfile.')'
- endif
- return ''
+ if exists('b:netrw_lastfile')
+ return ' ('.b:netrw_lastfile.')'
+ endif
+ return ''
endfunction