# HG changeset patch # User Bram Moolenaar # Date 1279460749 -7200 # Node ID 01e4b4d37842ba943947058dd8da29cc46c6b490 # Parent da6ec32d8d8ff0fb5f9d6a770fbce1387fe8bbd6 Added strdisplaywidth() function. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1910,6 +1910,7 @@ 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} +strdisplaywidth( {expr} [, {col}]) Number display length of the String {expr} strftime( {format}[, {time}]) String time in specified format stridx( {haystack}, {needle}[, {start}]) Number index of {needle} in {haystack} @@ -5368,7 +5369,17 @@ 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()|. + Also see |strlen()|, |strdisplaywidth()| and |strwidth()|. + +strdisplaywidth({expr}[, {col}]) *strdisplaywidth()* + The result is a Number, which is the number of display cells + String {expr} occupies on the screen. + When {col} is omitted zero is used. Otherwise it is the + screen column where to start. This matters for Tab + characters. + When {expr} contains characters with East Asian Width Class + Ambiguous, this function's return value depends on 'ambiwidth'. + Also see |strlen()|, |strwidth()| and |strchars()|. strftime({format} [, {time}]) *strftime()* The result is a String, which is a formatted date and time, as @@ -5432,7 +5443,8 @@ strlen({expr}) The result is a Number, w < If the argument is a Number it is first converted to a String. For other types an error is given. - Also see |len()|, |strchars()| and |strwidth()|. + Also see |len()|, |strchars()|, |strdisplaywidth()| and + |strwidth()|. strpart({src}, {start}[, {len}]) *strpart()* The result is a String, which is part of {src}, starting from @@ -5478,10 +5490,10 @@ strtrans({expr}) *strtrans()* 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). + cell, alternatively use |strdisplaywidth()|. When {expr} contains characters with East Asian Width Class Ambiguous, this function's return value depends on 'ambiwidth'. - Also see |strlen()| and |strchars()|. + Also see |strlen()|, |strdisplaywidth()| and |strchars()|. submatch({nr}) *submatch()* Only for an expression in a |:substitute| command. Returns diff --git a/src/charset.c b/src/charset.c --- a/src/charset.c +++ b/src/charset.c @@ -839,14 +839,25 @@ win_chartabsize(wp, p, col) #endif /* - * return the number of characters the string 's' will take on the screen, - * taking into account the size of a tab + * Return the number of characters the string 's' will take on the screen, + * taking into account the size of a tab. */ int linetabsize(s) char_u *s; { - colnr_T col = 0; + return linetabsize_col(0, s); +} + +/* + * Like linetabsize(), but starting at column "startcol". + */ + int +linetabsize_col(startcol, s) + int startcol; + char_u *s; +{ + colnr_T col = startcol; while (*s != NUL) col += lbr_chartabsize_adv(&s, col); diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -710,6 +710,7 @@ static void f_strlen __ARGS((typval_T *a 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_strdisplaywidth __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)); @@ -7859,6 +7860,7 @@ static struct fst #endif {"str2nr", 1, 2, f_str2nr}, {"strchars", 1, 1, f_strchars}, + {"strdisplaywidth", 1, 2, f_strdisplaywidth}, #ifdef HAVE_STRFTIME {"strftime", 1, 2, f_strftime}, #endif @@ -16805,6 +16807,23 @@ f_strchars(argvars, rettv) } /* + * "strdisplaywidth()" function + */ + static void +f_strdisplaywidth(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + char_u *s = get_tv_string(&argvars[0]); + int col = 0; + + if (argvars[1].v_type != VAR_UNKNOWN) + col = get_tv_number(&argvars[1]); + + rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s)); +} + +/* * "strwidth()" function */ static void diff --git a/src/proto/charset.pro b/src/proto/charset.pro --- a/src/proto/charset.pro +++ b/src/proto/charset.pro @@ -15,6 +15,7 @@ int vim_strsize __ARGS((char_u *s)); int vim_strnsize __ARGS((char_u *s, int len)); int chartabsize __ARGS((char_u *p, colnr_T col)); int linetabsize __ARGS((char_u *s)); +int linetabsize_col __ARGS((int startcol, char_u *s)); int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len)); int vim_isIDc __ARGS((int c)); int vim_iswordc __ARGS((int c));