From 97e204f3b64ebc19e74dc9a86941e39f9c52db73 Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Mon, 25 Jan 2016 21:00:05 +0100 Subject: [PATCH] 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. --- autoload/airline/extensions/wordcount.vim | 35 ++++---------- .../wordcount/formatters/default.vim | 48 +++++++++++++++++++ doc/airline.txt | 18 ++++++- 3 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 autoload/airline/extensions/wordcount/formatters/default.vim diff --git a/autoload/airline/extensions/wordcount.vim b/autoload/airline/extensions/wordcount.vim index 757ac03..ad0a72e 100644 --- a/autoload/airline/extensions/wordcount.vim +++ b/autoload/airline/extensions/wordcount.vim @@ -3,33 +3,17 @@ 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:formatter = get(g:, 'airline#extensions#wordcount#formatter', 'default') -" adapted from http://stackoverflow.com/questions/114431/fast-word-count-function-in-vim function! s:update() - if &ft !~ s:filetypes - unlet! b:airline_wordcount - return - elseif exists("*wordcount") - let b:airline_wordcount = printf(s:format, wordcount()['words']). - \ g:airline_symbols.space . g:airline_right_alt_sep . g:airline_symbols.space - elseif mode() =~? 's' - " Bail on select mode - return - else - let old_status = v:statusmsg - let position = getpos(".") - exe "silent normal! 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 + if match(&ft, s:filetypes) > -1 + if get(b:, 'airline_wordcount_cache', '') is# '' || + \ b:airline_wordcount_cache isnot# get(b:, 'airline_wordcount', '') || + \ get(b:, 'airline_change_tick', 0) != b:changedtick + " cache data + let b:airline_wordcount = airline#extensions#wordcount#formatters#{s:formatter}#format() + let b:airline_wordcount_cache = b:airline_wordcount + let b:airline_change_tick = b:changedtick endif endif endfunction @@ -44,4 +28,3 @@ function! airline#extensions#wordcount#init(ext) call a:ext.add_statusline_func('airline#extensions#wordcount#apply') autocmd BufReadPost,CursorMoved,CursorMovedI * call s:update() endfunction - diff --git a/autoload/airline/extensions/wordcount/formatters/default.vim b/autoload/airline/extensions/wordcount/formatters/default.vim new file mode 100644 index 0000000..52e3950 --- /dev/null +++ b/autoload/airline/extensions/wordcount/formatters/default.vim @@ -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\" + 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 diff --git a/doc/airline.txt b/doc/airline.txt index 5005d3b..6059947 100644 --- a/doc/airline.txt +++ b/doc/airline.txt @@ -415,6 +415,20 @@ eclim let g:airline#extensions#wordcount#filetypes = ... (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* * enable/disable detection of whitespace errors. > @@ -507,9 +521,9 @@ exposed. let g:airline#extensions#tabline#formatter = 'default' " 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 - function! airline#extensions#tabline#formatter#foo#format(bufnr, buffers) + function! airline#extensions#tabline#formatters#foo#format(bufnr, buffers) return fnamemodify(bufname(a:bufnr), ':t') endfunction let g:airline#extensions#tabline#formatter = 'foo'