summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2010-07-18 15:31:08 +0200
committerBram Moolenaar <Bram@vim.org>2010-07-18 15:31:08 +0200
commit72597a57b526a8df333e77ef8a837b595baa18c7 (patch)
tree8b635e3dbb23f92a0a73b730cc79bc538c0b61b9 /src
parent9855d6b3610b3ae46a5522b9f8e1e4b521759e83 (diff)
Added strwidth() and strchars() functions.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c46
-rw-r--r--src/gui.c7
-rw-r--r--src/gui_mac.c14
-rw-r--r--src/gui_w16.c6
-rw-r--r--src/gui_w32.c6
-rw-r--r--src/mbyte.c35
-rw-r--r--src/proto/mbyte.pro1
-rw-r--r--src/screen.c4
8 files changed, 80 insertions, 39 deletions
diff --git a/src/eval.c b/src/eval.c
index 295512e34a..a344cd2a52 100644
--- a/src/eval.c
+++ b/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},
@@ -16778,6 +16782,48 @@ f_strlen(argvars, rettv)
}
/*
+ * "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
*/
static void
diff --git a/src/gui.c b/src/gui.c
index 4075997f01..68999926f6 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -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
}
diff --git a/src/gui_mac.c b/src/gui_mac.c
index f6aa22b574..2f0f7f8657 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -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);
diff --git a/src/gui_w16.c b/src/gui_w16.c
index f7e6d597f8..68667846b9 100644
--- a/src/gui_w16.c
+++ b/src/gui_w16.c
@@ -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
diff --git a/src/gui_w32.c b/src/gui_w32.c
index cfd4b78571..1fdc99396e 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -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
diff --git a/src/mbyte.c b/src/mbyte.c
index 3a83eb4820..3719b85b67 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -1579,6 +1579,23 @@ dbcs_char2cells(c)
}
/*
+ * 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].
* We make sure that the offset used is less than "max_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;
diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro
index e805cb442e..9519a19371 100644
--- a/src/proto/mbyte.pro
+++ b/src/proto/mbyte.pro
@@ -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));
diff --git a/src/screen.c b/src/screen.c
index 5b9a0737f8..74898f82dd 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -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;