0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 7.4.1042

Problem:    g-CTRL-G shows the word count, but there is no way to get the word
            count in a script.
Solution:   Add the wordcount() function. (Christian Brabandt)
This commit is contained in:
Bram Moolenaar 2016-01-03 22:49:16 +01:00
parent 022b896592
commit ed767a2073
11 changed files with 293 additions and 59 deletions

View File

@ -78,7 +78,9 @@ g CTRL-G Prints the current position of the cursor in five
than one position on the screen (<Tab> or special
character), both the "real" column and the screen
column are shown, separated with a dash.
See also 'ruler' option. {not in Vi}
Also see the 'ruler' option and the |wordcount()|
function.
{not in Vi}
*v_g_CTRL-G*
{Visual}g CTRL-G Similar to "g CTRL-G", but Word, Character, Line, and

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 02
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 03
VIM REFERENCE MANUAL by Bram Moolenaar
@ -2075,6 +2075,7 @@ winrestcmd() String returns command to restore window sizes
winrestview( {dict}) none restore view of current window
winsaveview() Dict save view of current window
winwidth( {nr}) Number width of window {nr}
wordcount() Dict get byte/char/word statistics
writefile( {list}, {fname} [, {flags}])
Number write list of lines to file {fname}
xor( {expr}, {expr}) Number bitwise XOR
@ -6744,6 +6745,28 @@ winwidth({nr}) *winwidth()*
: exe "normal 50\<C-W>|"
:endif
<
wordcount() *wordcount()*
The result is a dictionary of byte/chars/word statistics for
the current buffer. This is the same info as provided by
|g_CTRL-G|
The return value includes:
bytes Number of bytes in the buffer
chars Number of chars in the buffer
words Number of words in the buffer
cursor_bytes Number of bytes before cursor position
(not in Visual mode)
cursor_chars Number of chars before cursor position
(not in Visual mode)
cursor_words Number of words before cursor position
(not in Visual mode)
visual_bytes Number of bytes visually selected
(only in Visual mode)
visual_chars Number of chars visually selected
(only in Visual mode)
visual_words Number of chars visually selected
(only in Visual mode)
*writefile()*
writefile({list}, {fname} [, {flags}])
Write |List| {list} to file {fname}. Each list item is

View File

@ -923,6 +923,7 @@ Various: *various-functions*
mzeval() evaluate |MzScheme| expression
py3eval() evaluate Python expression (|+python3|)
pyeval() evaluate Python expression (|+python|)
wordcount() get byte/word/char count of buffer
==============================================================================
*41.7* Defining a function

View File

@ -780,6 +780,7 @@ static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv));
static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv));
static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv));
static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
static void f_wordcount __ARGS((typval_T *argvars, typval_T *rettv));
static void f_xor __ARGS((typval_T *argvars, typval_T *rettv));
static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp));
@ -8387,6 +8388,7 @@ static struct fst
{"winrestview", 1, 1, f_winrestview},
{"winsaveview", 0, 0, f_winsaveview},
{"winwidth", 1, 1, f_winwidth},
{"wordcount", 0, 0, f_wordcount},
{"writefile", 2, 3, f_writefile},
{"xor", 2, 2, f_xor},
};
@ -20219,6 +20221,19 @@ f_winwidth(argvars, rettv)
#endif
}
/*
* "wordcount()" function
*/
static void
f_wordcount(argvars, rettv)
typval_T *argvars UNUSED;
typval_T *rettv;
{
if (rettv_dict_alloc(rettv) == FAIL)
return;
cursor_pos_info(rettv->vval.v_dict);
}
/*
* Write list of strings to file
*/

View File

@ -8270,7 +8270,7 @@ nv_g_cmd(cap)
* "g CTRL-G": display info about cursor position
*/
case Ctrl_G:
cursor_pos_info();
cursor_pos_info(NULL);
break;
/*

View File

@ -6963,15 +6963,18 @@ line_count_info(line, wc, cc, limit, eol_size)
* Give some info about the position of the cursor (for "g CTRL-G").
* In Visual mode, give some info about the selected region. (In this case,
* the *_count_cursor variables store running totals for the selection.)
* When "dict" is not NULL store the info there instead of showing it.
*/
void
cursor_pos_info()
cursor_pos_info(dict)
dict_T *dict;
{
char_u *p;
char_u buf1[50];
char_u buf2[40];
linenr_T lnum;
long byte_count = 0;
long bom_count = 0;
long byte_count_cursor = 0;
long char_count = 0;
long char_count_cursor = 0;
@ -6988,8 +6991,12 @@ cursor_pos_info()
* Compute the length of the file in characters.
*/
if (curbuf->b_ml.ml_flags & ML_EMPTY)
{
if (dict == NULL)
{
MSG(_(no_lines_msg));
return;
}
}
else
{
@ -7122,6 +7129,8 @@ cursor_pos_info()
if (!curbuf->b_p_eol && (curbuf->b_p_bin || !curbuf->b_p_fixeol))
byte_count -= eol_size;
if (dict == NULL)
{
if (VIsual_active)
{
if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
@ -7179,17 +7188,39 @@ cursor_pos_info()
char_count_cursor, char_count,
byte_count_cursor, byte_count);
}
}
#ifdef FEAT_MBYTE
byte_count = bomb_size();
if (byte_count > 0)
sprintf((char *)IObuff + STRLEN(IObuff), _("(+%ld for BOM)"),
byte_count);
#endif
/* Don't shorten this message, the user asked for it. */
#ifdef FEAT_MBYTE
bom_count = bomb_size();
if (bom_count > 0)
sprintf((char *)IObuff + STRLEN(IObuff), _("(+%ld for BOM)"),
bom_count);
#endif
if (dict == NULL)
{
p = p_shm;
p_shm = (char_u *)"";
msg(IObuff);
p_shm = p;
}
}
if (dict != NULL)
{
dict_add_nr_str(dict, "words", (long)word_count, NULL);
dict_add_nr_str(dict, "chars", (long)char_count, NULL);
dict_add_nr_str(dict, "bytes", (long)byte_count + bom_count, NULL);
if (VIsual_active)
{
dict_add_nr_str(dict, "visual_bytes", (long)byte_count_cursor, NULL);
dict_add_nr_str(dict, "visual_chars", (long)char_count_cursor, NULL);
dict_add_nr_str(dict, "visual_words", (long)word_count_cursor, NULL);
}
else
{
dict_add_nr_str(dict, "cursor_bytes", (long)byte_count_cursor, NULL);
dict_add_nr_str(dict, "cursor_chars", (long)char_count_cursor, NULL);
dict_add_nr_str(dict, "cursor_words", (long)word_count_cursor, NULL);
}
}
}

View File

@ -58,5 +58,5 @@ void write_reg_contents __ARGS((int name, char_u *str, int maxlen, int must_appe
void write_reg_contents_lst __ARGS((int name, char_u **strings, int maxlen, int must_append, int yank_type, long block_len));
void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len));
void clear_oparg __ARGS((oparg_T *oap));
void cursor_pos_info __ARGS((void));
void cursor_pos_info __ARGS((dict_T *eval));
/* vim: set ft=c : */

View File

@ -120,6 +120,7 @@ SCRIPTS_ALL = \
test_tagcase.out \
test_textobjects.out \
test_utf8.out \
test_wordcount.out \
test_writefile.out

View File

@ -0,0 +1,125 @@
Test for wordcount() function
STARTTEST
:so small.vim
:so mbyte.vim
:set enc=utf8
:new
:fu DoRecordWin(...)
: wincmd k
: if exists("a:1")
: call cursor(a:1)
: endif
: let result=[]
: call add(result, g:test)
: call add(result, getline(1, '$'))
: call add(result, wordcount())
: wincmd j
: return result
:endfu
:fu PutInWindow(args)
: wincmd k
: %d _
: call append(1, a:args)
: wincmd j
:endfu
:fu Log()
: $put ='----'
: $put =remove(g:log,0)
: $put =string(g:log)
:endfu
:fu! STL()
: if mode() =~? 'V'
: let g:visual_stat=wordcount()
: endif
: return string(wordcount())
:endfu
:let g:test="Test 1: empty window"
:let log=DoRecordWin()
:call Log()
:"
:let g:test="Test 2: some words, cursor at start"
:call PutInWindow('one two three')
:let log=DoRecordWin([1,1,0])
:call Log()
:"
:let g:test="Test 3: some words, cursor at end"
:call PutInWindow('one two three')
:let log=DoRecordWin([2,99,0])
:call Log()
:"
:let g:test="Test 4: some words, cursor at end, ve=all"
:set ve=all
:call PutInWindow('one two three')
:let log=DoRecordWin([2,99,0])
:call Log()
:set ve=
:"
:let g:test="Test 5: several lines with words"
:call PutInWindow(['one two three', 'one two three', 'one two three'])
:let log=DoRecordWin([4,99,0])
:call Log()
:"
:let g:test="Test 6: one line with BOM set"
:call PutInWindow('one two three')
:wincmd k
:set bomb
:w! Xtest
:wincmd j
:let log=DoRecordWin([2,99,0])
:call Log()
:wincmd k
:set nobomb
:w!
:wincmd j
:"
:let g:test="Test 7: one line with multibyte words"
:call PutInWindow(['Äne M¤ne Müh'])
:let log=DoRecordWin([2,99,0])
:call Log()
:"
:let g:test="Test 8: several lines with multibyte words"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:let log=DoRecordWin([3,99,0])
:call Log()
:"
:let g:test="Test 9: visual mode, complete buffer"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:wincmd k
:set ls=2 stl=%{STL()}
:" start visual mode quickly and select complete buffer
:0
V2jy
:set stl= ls=1
:let log=DoRecordWin([3,99,0])
:let log[2]=g:visual_stat
:call Log()
:"
:let g:test="Test 10: visual mode (empty)"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:wincmd k
:set ls=2 stl=%{STL()}
:" start visual mode quickly and select complete buffer
:0
v$y
:set stl= ls=1
:let log=DoRecordWin([3,99,0])
:let log[2]=g:visual_stat
:call Log()
:"
:let g:test="Test 11: visual mode, single line"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:wincmd k
:set ls=2 stl=%{STL()}
:" start visual mode quickly and select complete buffer
:2
0v$y
:set stl= ls=1
:let log=DoRecordWin([3,99,0])
:let log[2]=g:visual_stat
:call Log()
:"
:/^RESULT test/,$w! test.out
:qa!
ENDTEST
RESULT test:

View File

@ -0,0 +1,34 @@
RESULT test:
----
Test 1: empty window
[[''], {'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0, 'bytes': 0, 'cursor_bytes': 0}]
----
Test 2: some words, cursor at start
[['', 'one two three'], {'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0, 'bytes': 15, 'cursor_bytes': 1}]
----
Test 3: some words, cursor at end
[['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 14}]
----
Test 4: some words, cursor at end, ve=all
[['', 'one two three'], {'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 15}]
----
Test 5: several lines with words
[['', 'one two three', 'one two three', 'one two three'], {'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9, 'bytes': 43, 'cursor_bytes': 42}]
----
Test 6: one line with BOM set
[['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 18, 'cursor_bytes': 14}]
----
Test 7: one line with multibyte words
[['', 'Äne M¤ne Müh'], {'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3, 'bytes': 17, 'cursor_bytes': 16}]
----
Test 8: several lines with multibyte words
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7, 'bytes': 36, 'cursor_bytes': 35}]
----
Test 9: visual mode, complete buffer
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32, 'visual_words': 7, 'visual_bytes': 36}]
----
Test 10: visual mode (empty)
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1, 'visual_words': 0, 'visual_bytes': 1}]
----
Test 11: visual mode, single line
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13, 'visual_words': 3, 'visual_bytes': 16}]

View File

@ -741,6 +741,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1042,
/**/
1041,
/**/