forked from aniani/vim
Added strwidth() and strchars() functions.
This commit is contained in:
parent
9855d6b361
commit
72597a57b5
@ -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
|
||||
|
@ -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
|
||||
|
46
src/eval.c
46
src/eval.c
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
35
src/mbyte.c
35
src/mbyte.c
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user