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:
parent
022b896592
commit
ed767a2073
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
15
src/eval.c
15
src/eval.c
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
141
src/ops.c
141
src/ops.c
@ -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;
|
||||
@ -6989,7 +6992,11 @@ cursor_pos_info()
|
||||
*/
|
||||
if (curbuf->b_ml.ml_flags & ML_EMPTY)
|
||||
{
|
||||
MSG(_(no_lines_msg));
|
||||
if (dict == NULL)
|
||||
{
|
||||
MSG(_(no_lines_msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7122,74 +7129,98 @@ cursor_pos_info()
|
||||
if (!curbuf->b_p_eol && (curbuf->b_p_bin || !curbuf->b_p_fixeol))
|
||||
byte_count -= eol_size;
|
||||
|
||||
if (VIsual_active)
|
||||
if (dict == NULL)
|
||||
{
|
||||
if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
|
||||
if (VIsual_active)
|
||||
{
|
||||
getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
|
||||
&max_pos.col);
|
||||
vim_snprintf((char *)buf1, sizeof(buf1), _("%ld Cols; "),
|
||||
(long)(oparg.end_vcol - oparg.start_vcol + 1));
|
||||
if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
|
||||
{
|
||||
getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
|
||||
&max_pos.col);
|
||||
vim_snprintf((char *)buf1, sizeof(buf1), _("%ld Cols; "),
|
||||
(long)(oparg.end_vcol - oparg.start_vcol + 1));
|
||||
}
|
||||
else
|
||||
buf1[0] = NUL;
|
||||
|
||||
if (char_count_cursor == byte_count_cursor
|
||||
&& char_count == byte_count)
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"),
|
||||
buf1, line_count_selected,
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
word_count_cursor, word_count,
|
||||
byte_count_cursor, byte_count);
|
||||
else
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"),
|
||||
buf1, line_count_selected,
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
word_count_cursor, word_count,
|
||||
char_count_cursor, char_count,
|
||||
byte_count_cursor, byte_count);
|
||||
}
|
||||
else
|
||||
buf1[0] = NUL;
|
||||
{
|
||||
p = ml_get_curline();
|
||||
validate_virtcol();
|
||||
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
|
||||
(int)curwin->w_virtcol + 1);
|
||||
col_print(buf2, sizeof(buf2), (int)STRLEN(p),
|
||||
linetabsize(p));
|
||||
|
||||
if (char_count_cursor == byte_count_cursor
|
||||
&& char_count == byte_count)
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"),
|
||||
buf1, line_count_selected,
|
||||
if (char_count_cursor == byte_count_cursor
|
||||
&& char_count == byte_count)
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
|
||||
(char *)buf1, (char *)buf2,
|
||||
(long)curwin->w_cursor.lnum,
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
word_count_cursor, word_count,
|
||||
byte_count_cursor, byte_count);
|
||||
else
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"),
|
||||
buf1, line_count_selected,
|
||||
else
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"),
|
||||
(char *)buf1, (char *)buf2,
|
||||
(long)curwin->w_cursor.lnum,
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
word_count_cursor, word_count,
|
||||
char_count_cursor, char_count,
|
||||
byte_count_cursor, byte_count);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
{
|
||||
p = ml_get_curline();
|
||||
validate_virtcol();
|
||||
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
|
||||
(int)curwin->w_virtcol + 1);
|
||||
col_print(buf2, sizeof(buf2), (int)STRLEN(p),
|
||||
linetabsize(p));
|
||||
|
||||
if (char_count_cursor == byte_count_cursor
|
||||
&& char_count == byte_count)
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
|
||||
(char *)buf1, (char *)buf2,
|
||||
(long)curwin->w_cursor.lnum,
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
word_count_cursor, word_count,
|
||||
byte_count_cursor, byte_count);
|
||||
else
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"),
|
||||
(char *)buf1, (char *)buf2,
|
||||
(long)curwin->w_cursor.lnum,
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
word_count_cursor, word_count,
|
||||
char_count_cursor, char_count,
|
||||
byte_count_cursor, byte_count);
|
||||
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);
|
||||
}
|
||||
|
||||
#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. */
|
||||
p = p_shm;
|
||||
p_shm = (char_u *)"";
|
||||
msg(IObuff);
|
||||
p_shm = p;
|
||||
}
|
||||
}
|
||||
|
@ -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 : */
|
||||
|
@ -120,6 +120,7 @@ SCRIPTS_ALL = \
|
||||
test_tagcase.out \
|
||||
test_textobjects.out \
|
||||
test_utf8.out \
|
||||
test_wordcount.out \
|
||||
test_writefile.out
|
||||
|
||||
|
||||
|
125
src/testdir/test_wordcount.in
Normal file
125
src/testdir/test_wordcount.in
Normal 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:
|
34
src/testdir/test_wordcount.ok
Normal file
34
src/testdir/test_wordcount.ok
Normal 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}]
|
@ -741,6 +741,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1042,
|
||||
/**/
|
||||
1041,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user