2016-01-15 10:38:38 +08:00
|
|
|
" MIT License. Copyright (c) 2013-2016 Bailey Ling.
|
2013-08-21 23:14:12 +08:00
|
|
|
" vim: et ts=2 sts=2 sw=2
|
2013-08-07 08:17:33 +08:00
|
|
|
|
2013-08-07 09:48:00 +08:00
|
|
|
" http://got-ravings.blogspot.com/2008/10/vim-pr0n-statusline-whitespace-flags.html
|
2013-08-07 08:48:53 +08:00
|
|
|
|
2016-01-28 22:54:14 +08:00
|
|
|
let s:show_message = get(g:, 'airline#extensions#whitespace#show_message', 1)
|
2013-08-27 22:12:03 +08:00
|
|
|
let s:symbol = get(g:, 'airline#extensions#whitespace#symbol', g:airline_symbols.whitespace)
|
2016-02-07 00:44:59 +08:00
|
|
|
let s:default_checks = ['indent', 'trailing', 'mixed-indent-file']
|
2013-08-20 02:19:26 +08:00
|
|
|
|
2013-08-26 10:08:04 +08:00
|
|
|
let s:trailing_format = get(g:, 'airline#extensions#whitespace#trailing_format', 'trailing[%s]')
|
|
|
|
let s:mixed_indent_format = get(g:, 'airline#extensions#whitespace#mixed_indent_format', 'mixed-indent[%s]')
|
2015-09-23 23:45:46 +08:00
|
|
|
let s:long_format = get(g:, 'airline#extensions#whitespace#long_format', 'long[%s]')
|
2016-02-07 00:44:59 +08:00
|
|
|
let s:mixed_indent_file_format = get(g:, 'airline#extensions#whitespace#mixed_indent_file_format', 'mix-indent-file[%s]')
|
2014-04-20 02:27:14 +08:00
|
|
|
let s:indent_algo = get(g:, 'airline#extensions#whitespace#mixed_indent_algo', 0)
|
2016-02-10 03:16:12 +08:00
|
|
|
let s:skip_check_ft = {'make': ['indent', 'mixed-indent-file'] }
|
2013-12-14 05:38:32 +08:00
|
|
|
let s:max_lines = get(g:, 'airline#extensions#whitespace#max_lines', 20000)
|
2014-04-20 06:39:43 +08:00
|
|
|
let s:enabled = get(g:, 'airline#extensions#whitespace#enabled', 1)
|
2016-03-29 21:24:52 +08:00
|
|
|
let s:c_like_langs = get(g:, 'airline#extensions#c_like_langs', [ 'c', 'cpp', 'cuda', 'javascript', 'ld', 'php' ])
|
2016-03-17 07:10:55 +08:00
|
|
|
|
2014-04-20 02:27:14 +08:00
|
|
|
function! s:check_mixed_indent()
|
2014-04-20 22:52:06 +08:00
|
|
|
if s:indent_algo == 1
|
2014-04-20 02:27:14 +08:00
|
|
|
" [<tab>]<space><tab>
|
|
|
|
" spaces before or between tabs are not allowed
|
|
|
|
let t_s_t = '(^\t* +\t\s*\S)'
|
|
|
|
" <tab>(<space> x count)
|
2015-04-29 01:25:26 +08:00
|
|
|
" count of spaces at the end of tabs should be less than tabstop value
|
2014-04-20 02:27:14 +08:00
|
|
|
let t_l_s = '(^\t+ {' . &ts . ',}' . '\S)'
|
|
|
|
return search('\v' . t_s_t . '|' . t_l_s, 'nw')
|
2015-04-15 01:01:08 +08:00
|
|
|
elseif s:indent_algo == 2
|
|
|
|
return search('\v(^\t* +\t\s*\S)', 'nw')
|
2014-04-20 22:52:06 +08:00
|
|
|
else
|
|
|
|
return search('\v(^\t+ +)|(^ +\t+)', 'nw')
|
2014-04-20 02:27:14 +08:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2016-02-07 00:44:59 +08:00
|
|
|
function! s:check_mixed_indent_file()
|
2016-03-17 07:10:55 +08:00
|
|
|
if index(s:c_like_langs, &ft) > -1
|
|
|
|
" for C-like languages: allow /** */ comment style with one space before the '*'
|
2016-02-26 21:29:51 +08:00
|
|
|
let head_spc = '\v(^ +\*@!)'
|
|
|
|
else
|
|
|
|
let head_spc = '\v(^ +)'
|
|
|
|
endif
|
2016-02-07 00:44:59 +08:00
|
|
|
let indent_tabs = search('\v(^\t+)', 'nw')
|
2016-02-26 21:29:51 +08:00
|
|
|
let indent_spc = search(head_spc, 'nw')
|
2016-02-07 00:44:59 +08:00
|
|
|
if indent_tabs > 0 && indent_spc > 0
|
|
|
|
return printf("%d:%d", indent_tabs, indent_spc)
|
|
|
|
else
|
|
|
|
return ''
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2013-08-07 09:48:00 +08:00
|
|
|
function! airline#extensions#whitespace#check()
|
2013-12-14 05:38:32 +08:00
|
|
|
if &readonly || !&modifiable || !s:enabled || line('$') > s:max_lines
|
2016-05-15 03:56:48 +08:00
|
|
|
\ || get(b:, 'airline_whitespace_disabled', 0)
|
2013-08-07 10:29:03 +08:00
|
|
|
return ''
|
|
|
|
endif
|
|
|
|
|
2013-08-07 09:48:00 +08:00
|
|
|
if !exists('b:airline_whitespace_check')
|
|
|
|
let b:airline_whitespace_check = ''
|
2013-11-04 03:03:36 +08:00
|
|
|
let checks = get(g:, 'airline#extensions#whitespace#checks', s:default_checks)
|
2013-08-20 02:19:26 +08:00
|
|
|
|
|
|
|
let trailing = 0
|
2013-11-04 03:03:36 +08:00
|
|
|
if index(checks, 'trailing') > -1
|
2016-01-27 21:18:28 +08:00
|
|
|
try
|
|
|
|
let regexp = get(g:, 'airline#extensions#whitespace#trailing_regexp', '\s$')
|
|
|
|
let trailing = search(regexp, 'nw')
|
|
|
|
catch
|
|
|
|
echomsg 'airline#whitespace: error occured evaluating '. regexp
|
|
|
|
echomsg v:exception
|
|
|
|
return ''
|
|
|
|
endtry
|
2013-08-20 02:19:26 +08:00
|
|
|
endif
|
|
|
|
|
|
|
|
let mixed = 0
|
2016-02-10 03:16:12 +08:00
|
|
|
let check = 'indent'
|
|
|
|
if index(checks, check) > -1 && index(get(s:skip_check_ft, &ft, []), check) < 0
|
2014-04-20 02:27:14 +08:00
|
|
|
let mixed = s:check_mixed_indent()
|
2013-08-20 02:19:26 +08:00
|
|
|
endif
|
2013-08-07 08:48:53 +08:00
|
|
|
|
2016-02-07 00:44:59 +08:00
|
|
|
let mixed_file = ''
|
2016-02-10 03:16:12 +08:00
|
|
|
let check = 'mixed-indent-file'
|
|
|
|
if index(checks, check) > -1 && index(get(s:skip_check_ft, &ft, []), check) < 0
|
2016-02-07 00:44:59 +08:00
|
|
|
let mixed_file = s:check_mixed_indent_file()
|
|
|
|
endif
|
|
|
|
|
2015-09-23 23:45:46 +08:00
|
|
|
let long = 0
|
|
|
|
if index(checks, 'long') > -1 && &tw > 0
|
|
|
|
let long = search('\%>'.&tw.'v.\+', 'nw')
|
|
|
|
endif
|
|
|
|
|
2016-02-07 00:44:59 +08:00
|
|
|
if trailing != 0 || mixed != 0 || long != 0 || !empty(mixed_file)
|
2013-09-12 05:01:25 +08:00
|
|
|
let b:airline_whitespace_check = s:symbol
|
2013-08-20 08:35:48 +08:00
|
|
|
if s:show_message
|
2013-08-07 10:02:53 +08:00
|
|
|
if trailing != 0
|
2013-09-22 23:29:27 +08:00
|
|
|
let b:airline_whitespace_check .= (g:airline_symbols.space).printf(s:trailing_format, trailing)
|
2013-08-07 09:48:00 +08:00
|
|
|
endif
|
2014-03-10 09:56:36 +08:00
|
|
|
if mixed != 0
|
|
|
|
let b:airline_whitespace_check .= (g:airline_symbols.space).printf(s:mixed_indent_format, mixed)
|
2013-08-07 09:48:00 +08:00
|
|
|
endif
|
2015-09-23 23:45:46 +08:00
|
|
|
if long != 0
|
|
|
|
let b:airline_whitespace_check .= (g:airline_symbols.space).printf(s:long_format, long)
|
|
|
|
endif
|
2016-02-07 00:44:59 +08:00
|
|
|
if !empty(mixed_file)
|
|
|
|
let b:airline_whitespace_check .= (g:airline_symbols.space).printf(s:mixed_indent_file_format, mixed_file)
|
|
|
|
endif
|
2013-08-07 08:48:53 +08:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
endif
|
2013-08-07 09:48:00 +08:00
|
|
|
return b:airline_whitespace_check
|
2015-01-04 08:38:17 +08:00
|
|
|
endfunction
|
2013-08-07 08:48:53 +08:00
|
|
|
|
2013-08-08 22:42:27 +08:00
|
|
|
function! airline#extensions#whitespace#toggle()
|
2013-08-20 08:35:48 +08:00
|
|
|
if s:enabled
|
2014-04-20 02:16:36 +08:00
|
|
|
augroup airline_whitespace
|
|
|
|
autocmd!
|
|
|
|
augroup END
|
2013-08-31 08:57:34 +08:00
|
|
|
augroup! airline_whitespace
|
2013-08-20 08:35:48 +08:00
|
|
|
let s:enabled = 0
|
2013-08-10 21:09:52 +08:00
|
|
|
else
|
|
|
|
call airline#extensions#whitespace#init()
|
2013-08-20 08:35:48 +08:00
|
|
|
let s:enabled = 1
|
2013-08-08 22:42:27 +08:00
|
|
|
endif
|
2014-04-20 22:52:06 +08:00
|
|
|
|
2014-04-20 06:39:43 +08:00
|
|
|
if exists("g:airline#extensions#whitespace#enabled")
|
|
|
|
let g:airline#extensions#whitespace#enabled = s:enabled
|
2014-04-20 22:52:06 +08:00
|
|
|
if s:enabled && match(g:airline_section_warning, '#whitespace#check') < 0
|
|
|
|
let g:airline_section_warning .= airline#section#create(['whitespace'])
|
2014-04-20 06:39:43 +08:00
|
|
|
call airline#update_statusline()
|
|
|
|
endif
|
|
|
|
endif
|
2013-08-28 10:36:12 +08:00
|
|
|
echo 'Whitespace checking: '.(s:enabled ? 'Enabled' : 'Disabled')
|
2013-08-08 22:42:27 +08:00
|
|
|
endfunction
|
|
|
|
|
2013-08-24 00:42:55 +08:00
|
|
|
function! airline#extensions#whitespace#init(...)
|
2013-08-31 06:07:45 +08:00
|
|
|
call airline#parts#define_function('whitespace', 'airline#extensions#whitespace#check')
|
2013-08-07 09:48:00 +08:00
|
|
|
|
2013-08-20 08:35:48 +08:00
|
|
|
unlet! b:airline_whitespace_check
|
2013-08-07 09:48:00 +08:00
|
|
|
augroup airline_whitespace
|
|
|
|
autocmd!
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
autocmd CursorHold,BufWritePost * call <sid>ws_refresh()
|
2013-08-07 09:48:00 +08:00
|
|
|
augroup END
|
2013-08-07 08:17:33 +08:00
|
|
|
endfunction
|
Do not draw separators for empty sections
This is a little bit a hack, because by the time the separators are
added, it is not clear, if the following section is empty, therefore
we need to parse the content of the following section and eval the
expressions to find out, if this is empty
Remarks:
- catch all exceptions when eval'ing statusline
- make sure, that the seperators are highlighted
even when skipping empty regions (highlight group
names need to be adjusted)
- if a section is defined as empty, it will be removed completly from
the statusline. This means, it won't be called on the next update
and may not refresh properly (e.g. when the whitespace check
triggers, therefore, the whitesapce extension has to call an
explicit redraw whenever it is supposed to be refreshed)
2016-04-18 21:33:47 +08:00
|
|
|
|
|
|
|
function! s:ws_refresh()
|
|
|
|
unlet! b:airline_whitespace_check
|
|
|
|
if get(g:, 'airline_skip_empty_sections', 0)
|
|
|
|
exe ':AirlineRefresh'
|
|
|
|
endif
|
|
|
|
endfunction
|