Some improvements to the wordcount plugin

1) allow for custom formatting of the output of the wordcount formatter
   This allows for formatting numbers correctly e.g. 1,042 in English
   locale and 1.042 in German locale.

2) cache values, so that no on every cursor move the wordcount needs to
   be recalculated.
This commit is contained in:
Christian Brabandt 2016-01-25 21:00:05 +01:00
parent fb76dfbca1
commit 97e204f3b6
3 changed files with 73 additions and 28 deletions

View File

@ -3,33 +3,17 @@
let s:filetypes = get(g:, 'airline#extensions#wordcount#filetypes', '\vhelp|markdown|rst|org|text') let s:filetypes = get(g:, 'airline#extensions#wordcount#filetypes', '\vhelp|markdown|rst|org|text')
let s:format = get(g:, 'airline#extensions#wordcount#format', '%d words') let s:format = get(g:, 'airline#extensions#wordcount#format', '%d words')
let s:formatter = get(g:, 'airline#extensions#wordcount#formatter', 'default')
" adapted from http://stackoverflow.com/questions/114431/fast-word-count-function-in-vim
function! s:update() function! s:update()
if &ft !~ s:filetypes if match(&ft, s:filetypes) > -1
unlet! b:airline_wordcount if get(b:, 'airline_wordcount_cache', '') is# '' ||
return \ b:airline_wordcount_cache isnot# get(b:, 'airline_wordcount', '') ||
elseif exists("*wordcount") \ get(b:, 'airline_change_tick', 0) != b:changedtick
let b:airline_wordcount = printf(s:format, wordcount()['words']). " cache data
\ g:airline_symbols.space . g:airline_right_alt_sep . g:airline_symbols.space let b:airline_wordcount = airline#extensions#wordcount#formatters#{s:formatter}#format()
elseif mode() =~? 's' let b:airline_wordcount_cache = b:airline_wordcount
" Bail on select mode let b:airline_change_tick = b:changedtick
return
else
let old_status = v:statusmsg
let position = getpos(".")
exe "silent normal! g\<c-g>"
let stat = v:statusmsg
call setpos('.', position)
let v:statusmsg = old_status
let parts = split(stat)
if len(parts) > 11
let cnt = str2nr(split(stat)[11])
let spc = g:airline_symbols.space
let b:airline_wordcount = printf(s:format, cnt) . spc . g:airline_right_alt_sep . spc
else
unlet! b:airline_wordcount
endif endif
endif endif
endfunction endfunction
@ -44,4 +28,3 @@ function! airline#extensions#wordcount#init(ext)
call a:ext.add_statusline_func('airline#extensions#wordcount#apply') call a:ext.add_statusline_func('airline#extensions#wordcount#apply')
autocmd BufReadPost,CursorMoved,CursorMovedI * call s:update() autocmd BufReadPost,CursorMoved,CursorMovedI * call s:update()
endfunction endfunction

View File

@ -0,0 +1,48 @@
" MIT License. Copyright (c) 2013-2016 Bailey Ling.
" vim: et ts=2 sts=2 sw=2
function! airline#extensions#wordcount#formatters#default#format()
let words = string(s:wordcount())
if empty(words)
return
endif
let separator = s:get_decimal_group()
if words > 999 && !empty(separator)
" Format number according to locale, e.g. German: 1.245 or English: 1,245
let a = join(reverse(split(words, '.\zs')),'')
let a = substitute(a, '...', '&'.separator, 'g')
let words = join(reverse(split(a, '.\zs')),'')
endif
return words . " words" . g:airline_symbols.space . g:airline_right_alt_sep . g:airline_symbols.space
endfunction
function! s:wordcount()
if exists("*wordcount")
return wordcount()['words']
else if mode() =~? 's'
return
else
let old_status = v:statusmsg
let position = getpos(".")
exe "silent normal! g\<c-g>"
let stat = v:statusmsg
call setpos('.', position)
let v:statusmsg = old_status
let parts = split(stat)
if len(parts) > 11
return str2nr(parts[11])
else
return
endif
endif
endfunction
function s:get_decimal_group()
if match(v:lang, '\v\cC|en') > -1
return ','
elseif match(v:lang, '\v\cde|dk|fr') > -1
return '.'
endif
return ''
endfunction

View File

@ -415,6 +415,20 @@ eclim <https://eclim.org>
let g:airline#extensions#wordcount#filetypes = ... let g:airline#extensions#wordcount#filetypes = ...
(default: markdown,rst,org,help,text) (default: markdown,rst,org,help,text)
* defines the name of a formatter for word count will be displayed: >
" The default will try to guess LC_NUMERIC and format number accordingly
" e.g. 1,042 in English and 1.042 in German locale
let g:airline#extensions#wordcount#formatter = 'default'
" here is how you can define a 'foo' formatter:
" create a file in the dir autoload/airline/extensions/wordcount/formatters/
" called foo.vim
" this example needs at least Vim > 7.4.1042
function! airline#extensions#wordcount#formatters#foo#format()
return (wordcount()['words'] == 0 ? 'NONE' :
\ wordcount()['words'] > 100 ? 'okay' : 'not enough')
endfunction
let g:airline#extensions#wordline#formatter = 'foo'
< <
------------------------------------- *airline-whitespace* ------------------------------------- *airline-whitespace*
* enable/disable detection of whitespace errors. > * enable/disable detection of whitespace errors. >
@ -507,9 +521,9 @@ exposed.
let g:airline#extensions#tabline#formatter = 'default' let g:airline#extensions#tabline#formatter = 'default'
" here is how you can define a 'foo' formatter: " here is how you can define a 'foo' formatter:
" create a file in the dir autoload/airline/extensions/tabline/formatter/ " create a file in the dir autoload/airline/extensions/tabline/formatters/
" called foo.vim " called foo.vim
function! airline#extensions#tabline#formatter#foo#format(bufnr, buffers) function! airline#extensions#tabline#formatters#foo#format(bufnr, buffers)
return fnamemodify(bufname(a:bufnr), ':t') return fnamemodify(bufname(a:bufnr), ':t')
endfunction endfunction
let g:airline#extensions#tabline#formatter = 'foo' let g:airline#extensions#tabline#formatter = 'foo'