Skip to content

Commit ed767a2

Browse files
committed
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)
1 parent 022b896 commit ed767a2

11 files changed

Lines changed: 293 additions & 59 deletions

File tree

runtime/doc/editing.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ g CTRL-G Prints the current position of the cursor in five
7878
than one position on the screen (<Tab> or special
7979
character), both the "real" column and the screen
8080
column are shown, separated with a dash.
81-
See also 'ruler' option. {not in Vi}
81+
Also see the 'ruler' option and the |wordcount()|
82+
function.
83+
{not in Vi}
8284

8385
*v_g_CTRL-G*
8486
{Visual}g CTRL-G Similar to "g CTRL-G", but Word, Character, Line, and

runtime/doc/eval.txt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 02
1+
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 03
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2075,6 +2075,7 @@ winrestcmd() String returns command to restore window sizes
20752075
winrestview( {dict}) none restore view of current window
20762076
winsaveview() Dict save view of current window
20772077
winwidth( {nr}) Number width of window {nr}
2078+
wordcount() Dict get byte/char/word statistics
20782079
writefile( {list}, {fname} [, {flags}])
20792080
Number write list of lines to file {fname}
20802081
xor( {expr}, {expr}) Number bitwise XOR
@@ -6744,6 +6745,28 @@ winwidth({nr}) *winwidth()*
67446745
: exe "normal 50\<C-W>|"
67456746
:endif
67466747
<
6748+
wordcount() *wordcount()*
6749+
The result is a dictionary of byte/chars/word statistics for
6750+
the current buffer. This is the same info as provided by
6751+
|g_CTRL-G|
6752+
The return value includes:
6753+
bytes Number of bytes in the buffer
6754+
chars Number of chars in the buffer
6755+
words Number of words in the buffer
6756+
cursor_bytes Number of bytes before cursor position
6757+
(not in Visual mode)
6758+
cursor_chars Number of chars before cursor position
6759+
(not in Visual mode)
6760+
cursor_words Number of words before cursor position
6761+
(not in Visual mode)
6762+
visual_bytes Number of bytes visually selected
6763+
(only in Visual mode)
6764+
visual_chars Number of chars visually selected
6765+
(only in Visual mode)
6766+
visual_words Number of chars visually selected
6767+
(only in Visual mode)
6768+
6769+
67476770
*writefile()*
67486771
writefile({list}, {fname} [, {flags}])
67496772
Write |List| {list} to file {fname}. Each list item is

runtime/doc/usr_41.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,7 @@ Various: *various-functions*
923923
mzeval() evaluate |MzScheme| expression
924924
py3eval() evaluate Python expression (|+python3|)
925925
pyeval() evaluate Python expression (|+python|)
926+
wordcount() get byte/word/char count of buffer
926927

927928
==============================================================================
928929
*41.7* Defining a function

src/eval.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv));
780780
static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv));
781781
static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv));
782782
static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
783+
static void f_wordcount __ARGS((typval_T *argvars, typval_T *rettv));
783784
static void f_xor __ARGS((typval_T *argvars, typval_T *rettv));
784785

785786
static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp));
@@ -8387,6 +8388,7 @@ static struct fst
83878388
{"winrestview", 1, 1, f_winrestview},
83888389
{"winsaveview", 0, 0, f_winsaveview},
83898390
{"winwidth", 1, 1, f_winwidth},
8391+
{"wordcount", 0, 0, f_wordcount},
83908392
{"writefile", 2, 3, f_writefile},
83918393
{"xor", 2, 2, f_xor},
83928394
};
@@ -20219,6 +20221,19 @@ f_winwidth(argvars, rettv)
2021920221
#endif
2022020222
}
2022120223

20224+
/*
20225+
* "wordcount()" function
20226+
*/
20227+
static void
20228+
f_wordcount(argvars, rettv)
20229+
typval_T *argvars UNUSED;
20230+
typval_T *rettv;
20231+
{
20232+
if (rettv_dict_alloc(rettv) == FAIL)
20233+
return;
20234+
cursor_pos_info(rettv->vval.v_dict);
20235+
}
20236+
2022220237
/*
2022320238
* Write list of strings to file
2022420239
*/

src/normal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8270,7 +8270,7 @@ nv_g_cmd(cap)
82708270
* "g CTRL-G": display info about cursor position
82718271
*/
82728272
case Ctrl_G:
8273-
cursor_pos_info();
8273+
cursor_pos_info(NULL);
82748274
break;
82758275

82768276
/*

src/ops.c

Lines changed: 86 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6963,15 +6963,18 @@ line_count_info(line, wc, cc, limit, eol_size)
69636963
* Give some info about the position of the cursor (for "g CTRL-G").
69646964
* In Visual mode, give some info about the selected region. (In this case,
69656965
* the *_count_cursor variables store running totals for the selection.)
6966+
* When "dict" is not NULL store the info there instead of showing it.
69666967
*/
69676968
void
6968-
cursor_pos_info()
6969+
cursor_pos_info(dict)
6970+
dict_T *dict;
69696971
{
69706972
char_u *p;
69716973
char_u buf1[50];
69726974
char_u buf2[40];
69736975
linenr_T lnum;
69746976
long byte_count = 0;
6977+
long bom_count = 0;
69756978
long byte_count_cursor = 0;
69766979
long char_count = 0;
69776980
long char_count_cursor = 0;
@@ -6989,7 +6992,11 @@ cursor_pos_info()
69896992
*/
69906993
if (curbuf->b_ml.ml_flags & ML_EMPTY)
69916994
{
6992-
MSG(_(no_lines_msg));
6995+
if (dict == NULL)
6996+
{
6997+
MSG(_(no_lines_msg));
6998+
return;
6999+
}
69937000
}
69947001
else
69957002
{
@@ -7122,74 +7129,98 @@ cursor_pos_info()
71227129
if (!curbuf->b_p_eol && (curbuf->b_p_bin || !curbuf->b_p_fixeol))
71237130
byte_count -= eol_size;
71247131

7125-
if (VIsual_active)
7132+
if (dict == NULL)
71267133
{
7127-
if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
7134+
if (VIsual_active)
71287135
{
7129-
getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
7130-
&max_pos.col);
7131-
vim_snprintf((char *)buf1, sizeof(buf1), _("%ld Cols; "),
7132-
(long)(oparg.end_vcol - oparg.start_vcol + 1));
7136+
if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
7137+
{
7138+
getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
7139+
&max_pos.col);
7140+
vim_snprintf((char *)buf1, sizeof(buf1), _("%ld Cols; "),
7141+
(long)(oparg.end_vcol - oparg.start_vcol + 1));
7142+
}
7143+
else
7144+
buf1[0] = NUL;
7145+
7146+
if (char_count_cursor == byte_count_cursor
7147+
&& char_count == byte_count)
7148+
vim_snprintf((char *)IObuff, IOSIZE,
7149+
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"),
7150+
buf1, line_count_selected,
7151+
(long)curbuf->b_ml.ml_line_count,
7152+
word_count_cursor, word_count,
7153+
byte_count_cursor, byte_count);
7154+
else
7155+
vim_snprintf((char *)IObuff, IOSIZE,
7156+
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"),
7157+
buf1, line_count_selected,
7158+
(long)curbuf->b_ml.ml_line_count,
7159+
word_count_cursor, word_count,
7160+
char_count_cursor, char_count,
7161+
byte_count_cursor, byte_count);
71337162
}
71347163
else
7135-
buf1[0] = NUL;
7136-
7137-
if (char_count_cursor == byte_count_cursor
7138-
&& char_count == byte_count)
7139-
vim_snprintf((char *)IObuff, IOSIZE,
7140-
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"),
7141-
buf1, line_count_selected,
7164+
{
7165+
p = ml_get_curline();
7166+
validate_virtcol();
7167+
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
7168+
(int)curwin->w_virtcol + 1);
7169+
col_print(buf2, sizeof(buf2), (int)STRLEN(p),
7170+
linetabsize(p));
7171+
7172+
if (char_count_cursor == byte_count_cursor
7173+
&& char_count == byte_count)
7174+
vim_snprintf((char *)IObuff, IOSIZE,
7175+
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
7176+
(char *)buf1, (char *)buf2,
7177+
(long)curwin->w_cursor.lnum,
71427178
(long)curbuf->b_ml.ml_line_count,
71437179
word_count_cursor, word_count,
71447180
byte_count_cursor, byte_count);
7145-
else
7146-
vim_snprintf((char *)IObuff, IOSIZE,
7147-
_("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"),
7148-
buf1, line_count_selected,
7181+
else
7182+
vim_snprintf((char *)IObuff, IOSIZE,
7183+
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"),
7184+
(char *)buf1, (char *)buf2,
7185+
(long)curwin->w_cursor.lnum,
71497186
(long)curbuf->b_ml.ml_line_count,
71507187
word_count_cursor, word_count,
71517188
char_count_cursor, char_count,
71527189
byte_count_cursor, byte_count);
7153-
}
7154-
else
7155-
{
7156-
p = ml_get_curline();
7157-
validate_virtcol();
7158-
col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
7159-
(int)curwin->w_virtcol + 1);
7160-
col_print(buf2, sizeof(buf2), (int)STRLEN(p),
7161-
linetabsize(p));
7162-
7163-
if (char_count_cursor == byte_count_cursor
7164-
&& char_count == byte_count)
7165-
vim_snprintf((char *)IObuff, IOSIZE,
7166-
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
7167-
(char *)buf1, (char *)buf2,
7168-
(long)curwin->w_cursor.lnum,
7169-
(long)curbuf->b_ml.ml_line_count,
7170-
word_count_cursor, word_count,
7171-
byte_count_cursor, byte_count);
7172-
else
7173-
vim_snprintf((char *)IObuff, IOSIZE,
7174-
_("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"),
7175-
(char *)buf1, (char *)buf2,
7176-
(long)curwin->w_cursor.lnum,
7177-
(long)curbuf->b_ml.ml_line_count,
7178-
word_count_cursor, word_count,
7179-
char_count_cursor, char_count,
7180-
byte_count_cursor, byte_count);
7190+
}
71817191
}
71827192

7193+
/* Don't shorten this message, the user asked for it. */
71837194
#ifdef FEAT_MBYTE
7184-
byte_count = bomb_size();
7185-
if (byte_count > 0)
7195+
bom_count = bomb_size();
7196+
if (bom_count > 0)
71867197
sprintf((char *)IObuff + STRLEN(IObuff), _("(+%ld for BOM)"),
7187-
byte_count);
7198+
bom_count);
71887199
#endif
7189-
/* Don't shorten this message, the user asked for it. */
7190-
p = p_shm;
7191-
p_shm = (char_u *)"";
7192-
msg(IObuff);
7193-
p_shm = p;
7200+
if (dict == NULL)
7201+
{
7202+
p = p_shm;
7203+
p_shm = (char_u *)"";
7204+
msg(IObuff);
7205+
p_shm = p;
7206+
}
7207+
}
7208+
if (dict != NULL)
7209+
{
7210+
dict_add_nr_str(dict, "words", (long)word_count, NULL);
7211+
dict_add_nr_str(dict, "chars", (long)char_count, NULL);
7212+
dict_add_nr_str(dict, "bytes", (long)byte_count + bom_count, NULL);
7213+
if (VIsual_active)
7214+
{
7215+
dict_add_nr_str(dict, "visual_bytes", (long)byte_count_cursor, NULL);
7216+
dict_add_nr_str(dict, "visual_chars", (long)char_count_cursor, NULL);
7217+
dict_add_nr_str(dict, "visual_words", (long)word_count_cursor, NULL);
7218+
}
7219+
else
7220+
{
7221+
dict_add_nr_str(dict, "cursor_bytes", (long)byte_count_cursor, NULL);
7222+
dict_add_nr_str(dict, "cursor_chars", (long)char_count_cursor, NULL);
7223+
dict_add_nr_str(dict, "cursor_words", (long)word_count_cursor, NULL);
7224+
}
71947225
}
71957226
}

src/proto/ops.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@ void write_reg_contents __ARGS((int name, char_u *str, int maxlen, int must_appe
5858
void write_reg_contents_lst __ARGS((int name, char_u **strings, int maxlen, int must_append, int yank_type, long block_len));
5959
void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len));
6060
void clear_oparg __ARGS((oparg_T *oap));
61-
void cursor_pos_info __ARGS((void));
61+
void cursor_pos_info __ARGS((dict_T *eval));
6262
/* vim: set ft=c : */

src/testdir/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ SCRIPTS_ALL = \
120120
test_tagcase.out \
121121
test_textobjects.out \
122122
test_utf8.out \
123+
test_wordcount.out \
123124
test_writefile.out
124125

125126

0 commit comments

Comments
 (0)