1
0
forked from aniani/vim

Added strwidth() and strchars() functions.

This commit is contained in:
Bram Moolenaar 2010-07-18 15:31:08 +02:00
parent 9855d6b361
commit 72597a57b5
10 changed files with 99 additions and 42 deletions

View File

@ -1909,6 +1909,7 @@ split( {expr} [, {pat} [, {keepempty}]])
sqrt( {expr} Float squar root of {expr}
str2float( {expr}) Float convert String to Float
str2nr( {expr} [, {base}]) Number convert String to Number
strchars( {expr}) Number character length of the String {expr}
strftime( {format}[, {time}]) String time in specified format
stridx( {haystack}, {needle}[, {start}])
Number index of {needle} in {haystack}
@ -1919,6 +1920,7 @@ strpart( {src}, {start}[, {len}])
strridx( {haystack}, {needle} [, {start}])
Number last index of {needle} in {haystack}
strtrans( {expr}) String translate string to make it printable
strwidth( {expr}) Number display cell length of the String {expr}
submatch( {nr}) String specific match in ":substitute"
substitute( {expr}, {pat}, {sub}, {flags})
String all {pat} in {expr} replaced with {sub}
@ -5362,6 +5364,12 @@ str2nr( {expr} [, {base}]) *str2nr()*
Text after the number is silently ignored.
strchars({expr}) *strchars()*
The result is a Number, which is the number of characters
String {expr} occupies. Composing characters are counted
separately.
Also see |strlen()| and |strwidth()|.
strftime({format} [, {time}]) *strftime()*
The result is a String, which is a formatted date and time, as
specified by the {format} string. The given {time} is used,
@ -5424,7 +5432,7 @@ strlen({expr}) The result is a Number, which is the length of the String
<
If the argument is a Number it is first converted to a String.
For other types an error is given.
Also see |len()|.
Also see |len()|, |strchars()| and |strwidth()|.
strpart({src}, {start}[, {len}]) *strpart()*
The result is a String, which is part of {src}, starting from
@ -5467,6 +5475,14 @@ strtrans({expr}) *strtrans()*
< This displays a newline in register a as "^@" instead of
starting a new line.
strwidth({expr}) *strwidth()*
The result is a Number, which is the number of display cells
String {expr} occupies. A Tab character is counted as one
cell (on the screen it depends on the position).
When {expr} contains characters with East Asian Width Class
Ambiguous, this function's return value depends on 'ambiwidth'.
Also see |strlen()| and |strchars()|.
submatch({nr}) *submatch()*
Only for an expression in a |:substitute| command. Returns
the {nr}'th submatch of the matched text. When {nr} is 0

View File

@ -1193,8 +1193,8 @@ Awaiting updated patches:
Search in 'runtimepath'?
More docs needed about how to use this.
How to get the messages into the .po files?
charlen() Like strlen() but counting characters instead of
bytes.
strchars() Like strlen() and strwidth() but counting characters
instead of bytes.
confirm() add "flags" argument, with 'v' for vertical
layout and 'c' for console dialog. (Haegg)
Flemming Madsen has a patch for the 'c' flag

View File

@ -700,6 +700,7 @@ static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv));
static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv));
#endif
static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv));
static void f_strchars __ARGS((typval_T *argvars, typval_T *rettv));
#ifdef HAVE_STRFTIME
static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv));
#endif
@ -709,6 +710,7 @@ static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv));
static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv));
static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv));
static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv));
static void f_strwidth __ARGS((typval_T *argvars, typval_T *rettv));
static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv));
static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv));
static void f_synID __ARGS((typval_T *argvars, typval_T *rettv));
@ -7856,6 +7858,7 @@ static struct fst
{"str2float", 1, 1, f_str2float},
#endif
{"str2nr", 1, 2, f_str2nr},
{"strchars", 1, 1, f_strchars},
#ifdef HAVE_STRFTIME
{"strftime", 1, 2, f_strftime},
#endif
@ -7865,6 +7868,7 @@ static struct fst
{"strpart", 2, 3, f_strpart},
{"strridx", 2, 3, f_strridx},
{"strtrans", 1, 1, f_strtrans},
{"strwidth", 1, 1, f_strwidth},
{"submatch", 1, 1, f_submatch},
{"substitute", 4, 4, f_substitute},
{"synID", 3, 3, f_synID},
@ -16777,6 +16781,48 @@ f_strlen(argvars, rettv)
get_tv_string(&argvars[0])));
}
/*
* "strchars()" function
*/
static void
f_strchars(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
char_u *s = get_tv_string(&argvars[0]);
#ifdef FEAT_MBYTE
varnumber_T len = 0;
while (*s != NUL)
{
mb_cptr2char_adv(&s);
++len;
}
rettv->vval.v_number = len;
#else
rettv->vval.v_number = (varnumber_T)(STRLEN(s));
#endif
}
/*
* "strwidth()" function
*/
static void
f_strwidth(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
char_u *s = get_tv_string(&argvars[0]);
rettv->vval.v_number = (varnumber_T)(
#ifdef FEAT_MBYTE
mb_string2cells(s, -1)
#else
STRLEN(s)
#endif
);
}
/*
* "strpart()" function
*/

View File

@ -2329,14 +2329,9 @@ gui_outstr_nowrap(s, len, flags, fg, bg, back)
# ifdef FEAT_MBYTE
if (enc_dbcs == DBCS_JPNU)
{
int clen = 0;
int i;
/* Get the length in display cells, this can be different from the
* number of bytes for "euc-jp". */
for (i = 0; i < len; i += (*mb_ptr2len)(s + i))
clen += (*mb_ptr2cells)(s + i);
len = clen;
len = mb_string2cells(s, len);
}
# endif
}

View File

@ -3983,13 +3983,8 @@ draw_string_QD(int row, int col, char_u *s, int len, int flags)
/* Multibyte computation taken from gui_w32.c */
if (has_mbyte)
{
int cell_len = 0;
int n;
/* Compute the length in display cells. */
for (n = 0; n < len; n += MB_BYTE2LEN(s[n]))
cell_len += (*mb_ptr2cells)(s + n);
rc.right = FILL_X(col + cell_len);
rc.right = FILL_X(col + mb_string2cells(s, len));
}
else
#endif
@ -4087,13 +4082,8 @@ draw_string_ATSUI(int row, int col, char_u *s, int len, int flags)
/* Multibyte computation taken from gui_w32.c */
if (has_mbyte)
{
int cell_len = 0;
int n;
/* Compute the length in display cells. */
for (n = 0; n < len; n += MB_BYTE2LEN(s[n]))
cell_len += (*mb_ptr2cells)(s + n);
rc.right = FILL_X(col + cell_len);
rc.right = FILL_X(col + mb_string2cells(s, len));
}
else
rc.right = FILL_X(col + len) + (col + len == Columns);

View File

@ -664,12 +664,8 @@ gui_mch_draw_string(
#ifdef FEAT_MBYTE
if (has_mbyte)
{
int cell_len = 0;
/* Compute the length in display cells. */
for (n = 0; n < len; n += MB_BYTE2LEN(text[n]))
cell_len += (*mb_ptr2cells)(text + n);
rc.right = FILL_X(col + cell_len);
rc.right = FILL_X(col + mb_string2cells(text, len));
}
else
#endif

View File

@ -2261,12 +2261,8 @@ gui_mch_draw_string(
#ifdef FEAT_MBYTE
if (has_mbyte)
{
int cell_len = 0;
/* Compute the length in display cells. */
for (n = 0; n < len; n += MB_BYTE2LEN(text[n]))
cell_len += (*mb_ptr2cells)(text + n);
rc.right = FILL_X(col + cell_len);
rc.right = FILL_X(col + mb_string2cells(text, len));
}
else
#endif

View File

@ -1578,6 +1578,23 @@ dbcs_char2cells(c)
return MB_BYTE2LEN((unsigned)c >> 8);
}
/*
* Return the number of cells occupied by string "p".
* Stop at a NUL character. When "len" >= 0 stop at character "p[len]".
*/
int
mb_string2cells(p, len)
char_u *p;
int len;
{
int i;
int clen = 0;
for (i = 0; (len < 0 || i < len) && p[i] != NUL; i += (*mb_ptr2len)(p + i))
clen += (*mb_ptr2cells)(p + i);
return clen;
}
/*
* mb_off2cells() function pointer.
* Return number of display cells for char at ScreenLines[off].
@ -4364,12 +4381,12 @@ im_commit_cb(GtkIMContext *context UNUSED,
const gchar *str,
gpointer data UNUSED)
{
int slen = (int)STRLEN(str);
int add_to_input = TRUE;
int clen;
int len = slen;
int commit_with_preedit = TRUE;
char_u *im_str, *p;
int slen = (int)STRLEN(str);
int add_to_input = TRUE;
int clen;
int len = slen;
int commit_with_preedit = TRUE;
char_u *im_str;
#ifdef XIM_DEBUG
xim_log("im_commit_cb(): %s\n", str);
@ -4402,9 +4419,9 @@ im_commit_cb(GtkIMContext *context UNUSED,
}
else
im_str = (char_u *)str;
clen = 0;
for (p = im_str; p < im_str + len; p += (*mb_ptr2len)(p))
clen += (*mb_ptr2cells)(p);
clen = mb_string2cells(im_str, len);
if (input_conv.vc_type != CONV_NONE)
vim_free(im_str);
preedit_start_col += clen;

View File

@ -14,6 +14,7 @@ int utf_ptr2cells __ARGS((char_u *p));
int dbcs_ptr2cells __ARGS((char_u *p));
int latin_ptr2cells_len __ARGS((char_u *p, int size));
int latin_char2cells __ARGS((int c));
int mb_string2cells __ARGS((char_u *p, int len));
int latin_off2cells __ARGS((unsigned off, unsigned max_off));
int dbcs_off2cells __ARGS((unsigned off, unsigned max_off));
int utf_off2cells __ARGS((unsigned off, unsigned max_off));

View File

@ -6168,8 +6168,8 @@ win_redr_status(wp)
int clen = 0, i;
/* Count total number of display cells. */
for (i = 0; p[i] != NUL; i += (*mb_ptr2len)(p + i))
clen += (*mb_ptr2cells)(p + i);
clen = mb_string2cells(p, -1);
/* Find first character that will fit.
* Going from start to end is much faster for DBCS. */
for (i = 0; p[i] != NUL && clen >= this_ru_col - 1;