changeset 474:a5fcf36ef512 v7.0127

updated for version 7.0127
author vimboss
date Wed, 10 Aug 2005 21:07:57 +0000
parents 4a7320e53f32
children e6dfeb0a0f53
files runtime/doc/todo.txt runtime/spell/main.aap runtime/spell/yi/main.aap src/buffer.c src/charset.c src/diff.c src/edit.c src/eval.c src/ex_cmds.c src/ex_docmd.c src/ex_getln.c src/fileio.c src/fold.c src/getchar.c src/globals.h src/gui.c src/gui_beval.c src/gui_gtk_x11.c src/gui_kde_wid.cc src/gui_w32.c src/gui_x11.c src/hardcopy.c src/macros.h src/mbyte.c src/message.c src/misc1.c src/misc2.c src/normal.c src/ops.c src/option.c src/os_mac.c src/os_mac_conv.c src/os_mswin.c src/os_unix.c src/os_win32.c src/proto/mbyte.pro src/proto/screen.pro src/regexp.c src/screen.c src/search.c src/spell.c src/syntax.c src/term.c src/ui.c src/version.c src/version.h src/window.c
diffstat 47 files changed, 645 insertions(+), 472 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Aug 09
+*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Aug 10
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,18 +30,8 @@ be worked on, but only if you sponsor Vi
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-Spell checking: code for pre-compressing tree. (Olaf Seibert)
-Any problems with the reference counting?
-
-spell checking for Yiddish: (Raphael Finkel)
-- use ~/tmp/yiddish.uspell.dat
-- suggestions are not displayed with 'rightleft'
-- suggestions don't have composing characters
-- out-of-mem error when using suggestion?
-
-Spell suggestion for "WOrd" should be "Word" instead of "word".
-
 Spell checking: default value for 'spellcapcheck' in spell file?
+For Hebrew and Yiddish it should be empty.
 
 When 'insertmode' is set, CTRL-L no longer moves the cursor left.  What
 compatibility problems does this cause?
--- a/runtime/spell/main.aap
+++ b/runtime/spell/main.aap
@@ -1,7 +1,7 @@
 # "aap": generate all the .spl files
 # "aap diff" create all the diff files
 
-LANG = de en fr he it nl pl
+LANG = de en fr he it nl pl yi
 
 diff: $*LANG/diff
         :print done
new file mode 100644
--- /dev/null
+++ b/runtime/spell/yi/main.aap
@@ -0,0 +1,33 @@
+# Aap recipe for Hebrew Vim spell files.
+
+# Use a freshly compiled Vim if it exists.
+@if os.path.exists('../../../src/vim'):
+    VIM = ../../../src/vim
+@else:
+    :progsearch VIM vim
+
+SPELLDIR = ..
+FILE    = wordlist.utf8.txt
+
+all: $SPELLDIR/yi.utf-8.spl ../README_yi.txt
+
+$SPELLDIR/yi.utf-8.spl : $VIM $FILE
+    :sys $VIM -u NONE -e -c "set enc=utf-8"
+            -c "mkspell! $(SPELLDIR)/yi $FILE" -c q
+
+../README_yi.txt : README.txt
+    :copy $source $target
+
+#
+# Fetch the word list when needed.
+#
+URLDIR = http://www.cs.uky.edu/~raphael/yiddish
+:attr {fetch = $URLDIR/%file%} $FILE
+
+
+# There is no diff file, the word list is used as-is
+diff:
+    :print No diff file.
+
+
+# vim: set sts=4 sw=4 :
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3346,7 +3346,7 @@ build_stl_str_hl(wp, out, outlen, fmt, f
 		    while (l >= item[groupitem[groupdepth]].maxwid)
 		    {
 			l -= ptr2cells(t + n);
-			n += (*mb_ptr2len_check)(t + n);
+			n += (*mb_ptr2len)(t + n);
 		    }
 		}
 		else
@@ -3708,7 +3708,7 @@ build_stl_str_hl(wp, out, outlen, fmt, f
 		    if (has_mbyte)
 		    {
 			l -= ptr2cells(t);
-			t += (*mb_ptr2len_check)(t);
+			t += (*mb_ptr2len)(t);
 		    }
 		    else
 #endif
@@ -3836,7 +3836,7 @@ build_stl_str_hl(wp, out, outlen, fmt, f
 		    width += ptr2cells(s);
 		    if (width >= maxwidth)
 			break;
-		    s += (*mb_ptr2len_check)(s);
+		    s += (*mb_ptr2len)(s);
 		}
 		/* Fill up for half a double-wide character. */
 		while (++width < maxwidth)
@@ -3861,7 +3861,7 @@ build_stl_str_hl(wp, out, outlen, fmt, f
 		while (width >= maxwidth)
 		{
 		    width -= ptr2cells(s + n);
-		    n += (*mb_ptr2len_check)(s + n);
+		    n += (*mb_ptr2len)(s + n);
 		}
 	    }
 	    else
--- a/src/charset.c
+++ b/src/charset.c
@@ -296,7 +296,7 @@ trans_characters(buf, bufsize)
     {
 # ifdef FEAT_MBYTE
 	/* Assume a multi-byte character doesn't need translation. */
-	if (has_mbyte && (trs_len = (*mb_ptr2len_check)(buf)) > 1)
+	if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
 	    len -= trs_len;
 	else
 # endif
@@ -342,7 +342,7 @@ transstr(s)
 	p = s;
 	while (*p != NUL)
 	{
-	    if ((l = (*mb_ptr2len_check)(p)) > 1)
+	    if ((l = (*mb_ptr2len)(p)) > 1)
 	    {
 		c = (*mb_ptr2char)(p);
 		p += l;
@@ -375,7 +375,7 @@ transstr(s)
 	while (*p != NUL)
 	{
 #ifdef FEAT_MBYTE
-	    if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 	    {
 		c = (*mb_ptr2char)(p);
 		if (vim_isprintc(c))
@@ -488,7 +488,7 @@ str_foldcase(str, orglen, buf, buflen)
 		}
 	    }
 	    /* skip to next multi-byte char */
-	    i += (*mb_ptr2len_check)(STR_PTR(i));
+	    i += (*mb_ptr2len)(STR_PTR(i));
 	}
 	else
 #endif
@@ -772,7 +772,7 @@ vim_strnsize(s, len)
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    int	    l = (*mb_ptr2len_check)(s);
+	    int	    l = (*mb_ptr2len)(s);
 
 	    size += ptr2cells(s);
 	    s += l;
--- a/src/diff.c
+++ b/src/diff.c
@@ -1513,8 +1513,8 @@ diff_cmp(s1, s2)
 	else
 	{
 #ifdef FEAT_MBYTE
-	    l  = (*mb_ptr2len_check)(p1);
-	    if (l != (*mb_ptr2len_check)(p2))
+	    l  = (*mb_ptr2len)(p1);
+	    if (l != (*mb_ptr2len)(p2))
 		break;
 	    if (l > 1)
 	    {
--- a/src/edit.c
+++ b/src/edit.c
@@ -444,7 +444,7 @@ edit(cmdchar, startln, count)
 #ifdef FEAT_MBYTE
 	    else if (has_mbyte)
 	    {
-		i = (*mb_ptr2len_check)(ptr);
+		i = (*mb_ptr2len)(ptr);
 		if (ptr[i] == NUL)
 		    curwin->w_cursor.col += i;
 	    }
@@ -1561,7 +1561,7 @@ change_indent(type, amount, round, repla
 	    last_vcol = vcol;
 #ifdef FEAT_MBYTE
 	    if (has_mbyte && new_cursor_col >= 0)
-		new_cursor_col += (*mb_ptr2len_check)(ptr + new_cursor_col);
+		new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col);
 	    else
 #endif
 		++new_cursor_col;
@@ -2153,7 +2153,7 @@ ins_compl_dictionaries(dict, pat, dir, f
 				     * with single-byte non-word characters. */
 				    while (*ptr != NUL)
 				    {
-					int l = (*mb_ptr2len_check)(ptr);
+					int l = (*mb_ptr2len)(ptr);
 
 					if (l < 2 && !vim_iswordc(*ptr))
 					    break;
@@ -2203,7 +2203,7 @@ find_word_start(ptr)
 #ifdef FEAT_MBYTE
     if (has_mbyte)
 	while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1)
-	    ptr += (*mb_ptr2len_check)(ptr);
+	    ptr += (*mb_ptr2len)(ptr);
     else
 #endif
 	while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr))
@@ -2228,7 +2228,7 @@ find_word_end(ptr)
 	if (start_class > 1)
 	    while (*ptr != NUL)
 	    {
-		ptr += (*mb_ptr2len_check)(ptr);
+		ptr += (*mb_ptr2len)(ptr);
 		if (mb_get_class(ptr) != start_class)
 		    break;
 	    }
@@ -3756,7 +3756,7 @@ quote_meta(dest, src, len)
 	{
 	    int i, mb_len;
 
-	    mb_len = (*mb_ptr2len_check)(src) - 1;
+	    mb_len = (*mb_ptr2len)(src) - 1;
 	    if (mb_len > 0 && len >= mb_len)
 		for (i = 0; i < mb_len; ++i)
 		{
@@ -4166,7 +4166,7 @@ insertchar(c, flags, second_indent)
 #ifdef FEAT_MBYTE
 		    if (has_mbyte)
 			foundcol = curwin->w_cursor.col
-				       + (*mb_ptr2len_check)(ml_get_cursor());
+					     + (*mb_ptr2len)(ml_get_cursor());
 		    else
 #endif
 			foundcol = curwin->w_cursor.col + 1;
@@ -5053,7 +5053,7 @@ oneright()
 
     ptr = ml_get_cursor();
 #ifdef FEAT_MBYTE
-    if (has_mbyte && (l = (*mb_ptr2len_check)(ptr)) > 1)
+    if (has_mbyte && (l = (*mb_ptr2len)(ptr)) > 1)
     {
 	/* The character under the cursor is a multi-byte character, move
 	 * several bytes right, but don't end up on the NUL. */
@@ -5633,7 +5633,7 @@ replace_do_bs()
 	    {
 		vcol += chartabsize(p + i, vcol);
 #ifdef FEAT_MBYTE
-		i += (*mb_ptr2len_check)(p) - 1;
+		i += (*mb_ptr2len)(p) - 1;
 #endif
 	    }
 	    vcol -= start_vcol;
@@ -7288,7 +7288,7 @@ ins_right()
 	{
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		curwin->w_cursor.col += (*mb_ptr2len_check)(ml_get_cursor());
+		curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
 	    else
 #endif
 		++curwin->w_cursor.col;
--- a/src/eval.c
+++ b/src/eval.c
@@ -7712,7 +7712,7 @@ f_byteidx(argvars, rettv)
     {
 	if (*t == NUL)		/* EOL reached */
 	    return;
-	t += mb_ptr2len_check(t);
+	t += (*mb_ptr2len)(t);
     }
     rettv->vval.v_number = t - str;
 #else
@@ -7865,7 +7865,7 @@ f_col(argvars, rettv)
 # ifdef FEAT_MBYTE
 		    int		l;
 
-		    if (*p != NUL && p[(l = (*mb_ptr2len_check)(p))] == NUL)
+		    if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
 			col += l;
 # else
 		    if (*p != NUL && p[1] == NUL)
@@ -11582,7 +11582,7 @@ find_some_match(argvars, rettv, type)
 	    else
 	    {
 #ifdef FEAT_MBYTE
-		str = regmatch.startp[0] + mb_ptr2len_check(regmatch.startp[0]);
+		str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]);
 #else
 		str = regmatch.startp[0] + 1;
 #endif
@@ -13892,7 +13892,7 @@ f_split(argvars, rettv)
 	    {
 		/* Don't get stuck at the same match. */
 #ifdef FEAT_MBYTE
-		col = mb_ptr2len_check(regmatch.endp[0]);
+		col = (*mb_ptr2len)(regmatch.endp[0]);
 #else
 		col = 1;
 #endif
@@ -14509,13 +14509,13 @@ f_tolower(argvars, rettv)
 
 		c = utf_ptr2char(p);
 		lc = utf_tolower(c);
-		l = utf_ptr2len_check(p);
+		l = utf_ptr2len(p);
 		/* TODO: reallocate string when byte count changes. */
 		if (utf_char2len(lc) == l)
 		    utf_char2bytes(lc, p);
 		p += l;
 	    }
-	    else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 		p += l;		/* skip multi-byte character */
 	    else
 #endif
@@ -14594,18 +14594,18 @@ error:
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    inlen = mb_ptr2len_check(instr);
+	    inlen = (*mb_ptr2len)(instr);
 	    cpstr = instr;
 	    cplen = inlen;
 	    idx = 0;
 	    for (p = fromstr; *p != NUL; p += fromlen)
 	    {
-		fromlen = mb_ptr2len_check(p);
+		fromlen = (*mb_ptr2len)(p);
 		if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0)
 		{
 		    for (p = tostr; *p != NUL; p += tolen)
 		    {
-			tolen = mb_ptr2len_check(p);
+			tolen = (*mb_ptr2len)(p);
 			if (idx-- == 0)
 			{
 			    cplen = tolen;
@@ -14628,7 +14628,7 @@ error:
 		first = FALSE;
 		for (p = tostr; *p != NUL; p += tolen)
 		{
-		    tolen = mb_ptr2len_check(p);
+		    tolen = (*mb_ptr2len)(p);
 		    --idx;
 		}
 		if (idx != 0)
@@ -16539,7 +16539,7 @@ ex_echo(eap)
 #ifdef FEAT_MBYTE
 			if (has_mbyte)
 			{
-			    int i = (*mb_ptr2len_check)(p);
+			    int i = (*mb_ptr2len)(p);
 
 			    (void)msg_outtrans_len_attr(p, i, echo_attr);
 			    p += i - 1;
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -596,7 +596,7 @@ ex_retab(eap)
 	    vcol += chartabsize(ptr + col, (colnr_T)vcol);
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		col += (*mb_ptr2len_check)(ptr + col);
+		col += (*mb_ptr2len)(ptr + col);
 	    else
 #endif
 		++col;
@@ -4643,7 +4643,7 @@ do_sub(eap)
 		    }
 #ifdef FEAT_MBYTE
 		    else if (has_mbyte)
-			p1 += (*mb_ptr2len_check)(p1) - 1;
+			p1 += (*mb_ptr2len)(p1) - 1;
 #endif
 		}
 
@@ -5715,7 +5715,7 @@ fix_help_buffer()
 						int	l;
 
 						this_utf = TRUE;
-						l = utf_ptr2len_check(s);
+						l = utf_ptr2len(s);
 						if (l == 1)
 						    this_utf = FALSE;
 						s += l - 1;
@@ -6010,7 +6010,7 @@ helptags_one(dir, ext, tagfname)
 			int l;
 
 			this_utf8 = TRUE;
-			l = utf_ptr2len_check(s);
+			l = utf_ptr2len(s);
 			if (l == 1)
 			{
 			    /* Illegal UTF-8 byte sequence. */
@@ -6333,7 +6333,7 @@ ex_sign(eap)
 			if (has_mbyte)
 			{
 			    cells = 0;
-			    for (s = arg; s < p; s += (*mb_ptr2len_check)(s))
+			    for (s = arg; s < p; s += (*mb_ptr2len)(s))
 			    {
 				if (!vim_isprintc((*mb_ptr2char)(s)))
 				    break;
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -8324,7 +8324,7 @@ ex_normal(eap)
 	    if (*p == CSI)  /* leadbyte CSI */
 		len += 2;
 # endif
-	    for (l = (*mb_ptr2len_check)(p) - 1; l > 0; --l)
+	    for (l = (*mb_ptr2len)(p) - 1; l > 0; --l)
 		if (*++p == K_SPECIAL	  /* trailbyte K_SPECIAL or CSI */
 # ifdef FEAT_GUI
 			|| *p == CSI
@@ -8348,7 +8348,7 @@ ex_normal(eap)
 			arg[len++] = (int)KE_CSI;
 		    }
 # endif
-		    for (l = (*mb_ptr2len_check)(p) - 1; l > 0; --l)
+		    for (l = (*mb_ptr2len)(p) - 1; l > 0; --l)
 		    {
 			arg[len++] = *++p;
 			if (*p == K_SPECIAL)
@@ -9772,7 +9772,7 @@ ses_put_fname(fd, name, flagp)
 	{
 	    int l;
 
-	    if (has_mbyte && (l = (*mb_ptr2len_check)(name)) > 1)
+	    if (has_mbyte && (l = (*mb_ptr2len)(name)) > 1)
 	    {
 		/* copy a multibyte char */
 		while (--l >= 0)
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -881,7 +881,7 @@ getcmdline(firstc, count, indent)
 			    while (p > ccline.cmdbuff && mb_get_class(p) == i)
 				p = mb_prevptr(ccline.cmdbuff, p);
 			    if (mb_get_class(p) != i)
-				p += (*mb_ptr2len_check)(p);
+				p += (*mb_ptr2len)(p);
 			}
 		    }
 		    else
@@ -1115,7 +1115,7 @@ getcmdline(firstc, count, indent)
 		    ccline.cmdspos += i;
 #ifdef FEAT_MBYTE
 		    if (has_mbyte)
-			ccline.cmdpos += (*mb_ptr2len_check)(ccline.cmdbuff
+			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
 							     + ccline.cmdpos);
 		    else
 #endif
@@ -1241,7 +1241,7 @@ getcmdline(firstc, count, indent)
 		    {
 			/* Count ">" for double-wide char that doesn't fit. */
 			correct_cmdspos(ccline.cmdpos, i);
-			ccline.cmdpos += (*mb_ptr2len_check)(ccline.cmdbuff
+			ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
 							 + ccline.cmdpos) - 1;
 		    }
 #endif
@@ -1861,7 +1861,7 @@ set_cmdspos_cursor()
 	}
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    i += (*mb_ptr2len_check)(ccline.cmdbuff + i) - 1;
+	    i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1;
 #endif
     }
 }
@@ -1876,7 +1876,7 @@ correct_cmdspos(idx, cells)
     int		idx;
     int		cells;
 {
-    if ((*mb_ptr2len_check)(ccline.cmdbuff + idx) > 1
+    if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
 		&& (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
 		&& ccline.cmdspos % Columns + cells > Columns)
 	ccline.cmdspos++;
@@ -2184,7 +2184,7 @@ cmdline_getvcol_cursor()
 	int	i = 0;
 
 	for (col = 0; i < ccline.cmdpos; ++col)
-	    i += (*mb_ptr2len_check)(ccline.cmdbuff + i);
+	    i += (*mb_ptr2len)(ccline.cmdbuff + i);
 
 	return col;
     }
@@ -2225,7 +2225,7 @@ redrawcmd_preedit()
 			  && cmdpos < ccline.cmdlen; ++col)
 	    {
 		cmdspos += (*mb_ptr2cells)(ccline.cmdbuff + cmdpos);
-		cmdpos  += (*mb_ptr2len_check)(ccline.cmdbuff + cmdpos);
+		cmdpos  += (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
 	    }
 	}
 	else
@@ -2251,7 +2251,7 @@ redrawcmd_preedit()
 
 # ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		char_len = (*mb_ptr2len_check)(ccline.cmdbuff + cmdpos);
+		char_len = (*mb_ptr2len)(ccline.cmdbuff + cmdpos);
 	    else
 # endif
 		char_len = 1;
@@ -2339,7 +2339,7 @@ draw_cmdline(start, len)
 	    msg_putchar('*');
 # ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		i += (*mb_ptr2len_check)(ccline.cmdbuff + start + i) - 1;
+		i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1;
 # endif
 	}
     else
@@ -2378,7 +2378,7 @@ draw_cmdline(start, len)
 	{
 	    p = ccline.cmdbuff + j;
 	    u8c = utfc_ptr2char_len(p, &u8c_c1, &u8c_c2, start + len - j);
-	    mb_l = utfc_ptr2len_check_len(p, start + len - j);
+	    mb_l = utfc_ptr2len_len(p, start + len - j);
 	    if (ARABIC_CHAR(u8c))
 	    {
 		/* Do Arabic shaping. */
@@ -2511,12 +2511,12 @@ put_on_cmdline(str, len, redraw)
 	    {
 		/* Count nr of characters in the new string. */
 		m = 0;
-		for (i = 0; i < len; i += (*mb_ptr2len_check)(str + i))
+		for (i = 0; i < len; i += (*mb_ptr2len)(str + i))
 		    ++m;
 		/* Count nr of bytes in cmdline that are overwritten by these
 		 * characters. */
 		for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0;
-				 i += (*mb_ptr2len_check)(ccline.cmdbuff + i))
+				 i += (*mb_ptr2len)(ccline.cmdbuff + i))
 		    --m;
 		if (i < ccline.cmdlen)
 		{
@@ -2619,7 +2619,7 @@ put_on_cmdline(str, len, redraw)
 #ifdef FEAT_MBYTE
 		if (has_mbyte)
 		{
-		    c = (*mb_ptr2len_check)(ccline.cmdbuff + ccline.cmdpos) - 1;
+		    c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1;
 		    if (c > len - i - 1)
 			c = len - i - 1;
 		    ccline.cmdpos += c;
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1402,7 +1402,7 @@ retry:
 		    p = ptr;
 		    for (flen = from_size; flen > 0; flen -= l)
 		    {
-			l = utf_ptr2len_check_len(p, flen);
+			l = utf_ptr2len_len(p, flen);
 			if (l > flen)			/* incomplete char */
 			{
 			    if (l > CONV_RESTLEN)
@@ -1467,7 +1467,7 @@ retry:
 		    p = ptr;
 		    for (flen = from_size; flen > 0; flen -= l)
 		    {
-			l = utf_ptr2len_check_len(p, flen);
+			l = utf_ptr2len_len(p, flen);
 			u8c = utf_ptr2char(p);
 			ucsp[needed * 2] = (u8c & 0xff);
 			ucsp[needed * 2 + 1] = (u8c >> 8);
@@ -1726,7 +1726,7 @@ retry:
 		{
 		    if (*p >= 0x80)
 		    {
-			len = utf_ptr2len_check(p);
+			len = utf_ptr2len(p);
 			/* A length of 1 means it's an illegal byte.  Accept
 			 * an incomplete character at the end though, the next
 			 * read() will get the next bytes, we'll check it
@@ -4614,7 +4614,7 @@ buf_write_bytes(ip)
 		    if (l > len)
 			l = len;
 		    mch_memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l);
-		    n = utf_ptr2len_check_len(ip->bw_rest, ip->bw_restlen + l);
+		    n = utf_ptr2len_len(ip->bw_rest, ip->bw_restlen + l);
 		    if (n > ip->bw_restlen + len)
 		    {
 			/* We have an incomplete byte sequence at the end to
@@ -4644,7 +4644,7 @@ buf_write_bytes(ip)
 		}
 		else
 		{
-		    n = utf_ptr2len_check_len(buf + wlen, len - wlen);
+		    n = utf_ptr2len_len(buf + wlen, len - wlen);
 		    if (n > len - wlen)
 		    {
 			/* We have an incomplete byte sequence at the end to
@@ -4711,7 +4711,7 @@ buf_write_bytes(ip)
 		 * The buffer has been allocated to be big enough. */
 		while (fromlen > 0)
 		{
-		    n = utf_ptr2len_check_len(from, fromlen);
+		    n = utf_ptr2len_len(from, fromlen);
 		    if (n > (int)fromlen)	/* incomplete byte sequence */
 			break;
 		    u8c = utf_ptr2char(from);
@@ -6599,7 +6599,7 @@ forward_slash(fname)
     for (p = fname; *p != NUL; ++p)
 # ifdef  FEAT_MBYTE
 	/* The Big5 encoding can have '\' in the trail byte. */
-	if (enc_dbcs != 0 && (*mb_ptr2len_check)(p) > 1)
+	if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
 	    ++p;
 	else
 # endif
@@ -8908,7 +8908,7 @@ file_pat_to_reg_pat(pat, pat_end, allow_
 	    default:
 		size++;
 # ifdef  FEAT_MBYTE
-		if (enc_dbcs != 0 && (*mb_ptr2len_check)(p) > 1)
+		if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
 		{
 		    ++p;
 		    ++size;
@@ -9045,7 +9045,7 @@ file_pat_to_reg_pat(pat, pat_end, allow_
 		break;
 	    default:
 # ifdef  FEAT_MBYTE
-		if (enc_dbcs != 0 && (*mb_ptr2len_check)(p) > 1)
+		if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
 		    reg_pat[i++] = *p++;
 		else
 # endif
--- a/src/fold.c
+++ b/src/fold.c
@@ -1954,7 +1954,7 @@ get_foldtext(wp, lnum, lnume, foldinfo, 
 # ifdef FEAT_MBYTE
 		int	len;
 
-		if (has_mbyte && (len = (*mb_ptr2len_check)(p)) > 1)
+		if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1)
 		{
 		    if (!vim_isprintc((*mb_ptr2char)(p)))
 			break;
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -562,14 +562,8 @@ AppendToRedobuffLit(s)
 	    /* Handle a special or multibyte character. */
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-	    {
-		c = (*mb_ptr2char)(s);
-		if (enc_utf8)
-		    /* Handle composing chars as well. */
-		    s += utf_ptr2len_check(s);
-		else
-		    s += (*mb_ptr2len_check)(s);
-	    }
+		/* Handle composing chars separately. */
+		c = mb_cptr2char_adv(&s);
 	    else
 #endif
 		c = *s++;
@@ -2025,7 +2019,7 @@ vgetorpeek(advance)
 				 * multi-byte char.  Happens when mapping
 				 * <M-a> and then changing 'encoding'. */
 				if (has_mbyte && MB_BYTE2LEN(c1)
-					    > (*mb_ptr2len_check)(mp->m_keys))
+						  > (*mb_ptr2len)(mp->m_keys))
 				    mlen = 0;
 #endif
 				/*
@@ -2413,7 +2407,7 @@ vgetorpeek(advance)
 							       (colnr_T)vcol);
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
-					col += (*mb_ptr2len_check)(ptr + col);
+					col += (*mb_ptr2len)(ptr + col);
 				    else
 #endif
 					++col;
@@ -3105,7 +3099,7 @@ do_map(maptype, arg, mode, abbrev)
 
 		first = vim_iswordp(keys);
 		last = first;
-		p = keys + mb_ptr2len_check(keys);
+		p = keys + (*mb_ptr2len)(keys);
 		n = 1;
 		while (p < keys + len)
 		{
@@ -3113,7 +3107,7 @@ do_map(maptype, arg, mode, abbrev)
 		    last = vim_iswordp(p);	/* type of last char */
 		    if (same == -1 && last != first)
 			same = n - 1;		/* count of same char type */
-		    p += mb_ptr2len_check(p);
+		    p += (*mb_ptr2len)(p);
 		}
 		if (last && n > 2 && same >= 0 && same < n - 1)
 		{
@@ -4045,7 +4039,7 @@ check_abbr(c, ptr, col, mincol)
 	    p = mb_prevptr(ptr, p);
 	    if (vim_isspace(*p) || (!vim_abbr && is_id != vim_iswordp(p)))
 	    {
-		p += (*mb_ptr2len_check)(p);
+		p += (*mb_ptr2len)(p);
 		break;
 	    }
 	    ++clen;
--- a/src/globals.h
+++ b/src/globals.h
@@ -717,8 +717,11 @@ EXTERN vimconv_T output_conv;			/* type 
  * (DBCS).
  * The value is set in mb_init();
  */
-EXTERN int (*mb_ptr2len_check) __ARGS((char_u *p)) INIT(= latin_ptr2len_check);
+/* length of char in bytes, including following composing chars */
+EXTERN int (*mb_ptr2len) __ARGS((char_u *p)) INIT(= latin_ptr2len);
+/* byte length of char */
 EXTERN int (*mb_char2len) __ARGS((int c)) INIT(= latin_char2len);
+/* convert char to bytes, return the length */
 EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
 EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
 EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
--- a/src/gui.c
+++ b/src/gui.c
@@ -1783,7 +1783,7 @@ gui_outstr(s, len)
 		cells += (*mb_ptr2cells)(s + this_len);
 		if (gui.col + cells > Columns)
 		    break;
-		this_len += (*mb_ptr2len_check)(s + this_len);
+		this_len += (*mb_ptr2len)(s + this_len);
 	    }
 	    if (this_len > len)
 		this_len = len;	    /* don't include following composing char */
@@ -1847,7 +1847,7 @@ gui_screenchar(off, flags, fg, bg, back)
 
     /* Draw non-multi-byte character or DBCS character. */
     return gui_outstr_nowrap(ScreenLines + off,
-	    enc_dbcs ? (*mb_ptr2len_check)(ScreenLines + off) : 1,
+	    enc_dbcs ? (*mb_ptr2len)(ScreenLines + off) : 1,
 							 flags, fg, bg, back);
 #else
     return gui_outstr_nowrap(ScreenLines + off, 1, flags, fg, bg, back);
@@ -2190,7 +2190,7 @@ gui_outstr_nowrap(s, len, flags, fg, bg,
 	    comping = utf_iscomposing(c);
 	    if (!comping)	/* count cells from non-composing chars */
 		cells += cn;
-	    cl = utf_ptr2len_check(s + i);
+	    cl = utf_ptr2len(s + i);
 	    if (cl == 0)	/* hit end of string */
 		len = i + cl;	/* len must be wrong "cannot happen" */
 
@@ -2274,7 +2274,7 @@ gui_outstr_nowrap(s, len, flags, fg, bg,
 
 	    /* 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_check)(s + i))
+	    for (i = 0; i < len; i += (*mb_ptr2len)(s + i))
 		clen += (*mb_ptr2cells)(s + i);
 	    len = clen;
 	}
@@ -2508,7 +2508,7 @@ gui_redraw_block(row1, col1, row2, col2,
 			/* Stop at a double-byte single-width char. */
 			if (ScreenLines[off + idx] == 0x8e)
 			    break;
-			if (len > 1 && (*mb_ptr2len_check)(ScreenLines
+			if (len > 1 && (*mb_ptr2len)(ScreenLines
 							    + off + idx) == 2)
 			    ++idx;  /* skip second byte of double-byte char */
 		    }
@@ -4559,7 +4559,7 @@ concat_esc(gap, text, what)
     while (*text != NUL)
     {
 #ifdef FEAT_MBYTE
-	int l = (*mb_ptr2len_check)(text);
+	int l = (*mb_ptr2len)(text);
 	if (l > 1)
 	{
 	    while (--l >= 0)
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -910,7 +910,7 @@ set_printable_label_text(GtkLabel *label
 	}
 	else
 	{
-	    charlen = utf_ptr2len_check(p);
+	    charlen = utf_ptr2len(p);
 	    uc = utf_ptr2char(p);
 
 	    if (charlen != utf_char2len(uc))
@@ -956,7 +956,7 @@ set_printable_label_text(GtkLabel *label
 	    }
 	    else
 	    {
-		charlen = utf_ptr2len_check(p);
+		charlen = utf_ptr2len(p);
 		uc = utf_ptr2char(p);
 
 		if (charlen != utf_char2len(uc))
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -5255,7 +5255,7 @@ gui_gtk2_draw_string(int row, int col, c
 	 * compensate for that. */
 	for (sp = s, bp = conv_buf; sp < s + len && bp < conv_buf + convlen; )
 	{
-	    plen = utf_ptr2len_check(bp);
+	    plen = utf_ptr2len(bp);
 	    if ((*mb_ptr2cells)(sp) == 2 && utf_ptr2cells(bp) == 1)
 	    {
 		new_conv_buf = alloc(convlen + 2);
@@ -5272,7 +5272,7 @@ gui_gtk2_draw_string(int row, int col, c
 		bp = conv_buf + plen;
 		plen = 1;
 	    }
-	    sp += (*mb_ptr2len_check)(sp);
+	    sp += (*mb_ptr2len)(sp);
 	    bp += plen;
 	}
 	s = conv_buf;
@@ -5541,7 +5541,7 @@ gui_mch_draw_string(int row, int col, ch
 		    c = 0xbf;
 		buf[textlen].byte1 = c >> 8;
 		buf[textlen].byte2 = c;
-		p += utf_ptr2len_check(p);
+		p += utf_ptr2len(p);
 		width += utf_char2cells(c);
 	    }
 	    else
@@ -5565,7 +5565,7 @@ gui_mch_draw_string(int row, int col, ch
 	if (has_mbyte)
 	{
 	    width = 0;
-	    for (p = s; p < s + len; p += (*mb_ptr2len_check)(p))
+	    for (p = s; p < s + len; p += (*mb_ptr2len)(p))
 		width += (*mb_ptr2cells)(p);
 	}
 	else
--- a/src/gui_kde_wid.cc
+++ b/src/gui_kde_wid.cc
@@ -944,7 +944,7 @@ VimWidget::imComposeEvent(QIMEvent *e)
 	else
 	    draw_feedback[n] = XIMReverse;
 	preedit_end_col += (*mb_ptr2cells)(p);
-	p += (*mb_ptr2len_check)(p);
+	p += (*mb_ptr2len)(p);
     }
     im_preedit_cursor = e->cursorPos();
     im_preedit_trailing = preedit_buf_len - im_preedit_cursor;
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2039,7 +2039,7 @@ gui_mch_draw_string(
 		unicodepdy[clen] = cw * gui.char_width;
 	    }
 	    cells += cw;
-	    i += utfc_ptr2len_check_len(text + i, len - i);
+	    i += utfc_ptr2len_len(text + i, len - i);
 	    ++clen;
 	}
 	ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
@@ -2818,7 +2818,7 @@ gui_mch_dialog(
 	for (pend = pstart; *pend != NUL && *pend != '\n'; )
 	{
 #ifdef FEAT_MBYTE
-	    l = mb_ptr2len_check(pend);
+	    l = (*mb_ptr2len)(pend);
 #else
 	    l = 1;
 #endif
--- a/src/gui_x11.c
+++ b/src/gui_x11.c
@@ -2530,7 +2530,7 @@ gui_mch_draw_string(row, col, s, len, fl
 	    buf[wlen].byte2 = c;
 	    ++wlen;
 	    cells += utf_char2cells(c);
-	    p += utf_ptr2len_check(p);
+	    p += utf_ptr2len(p);
 	}
     }
     else if (has_mbyte)
@@ -2539,7 +2539,7 @@ gui_mch_draw_string(row, col, s, len, fl
 	for (p = s; p < s + len; )
 	{
 	    cells += ptr2cells(p);
-	    p += (*mb_ptr2len_check)(p);
+	    p += (*mb_ptr2len)(p);
 	}
     }
 
--- a/src/hardcopy.c
+++ b/src/hardcopy.c
@@ -513,7 +513,7 @@ prt_header(psettings, pagenum, lnum)
     {
 	if (mch_print_text_out(p,
 #ifdef FEAT_MBYTE
-		(l = (*mb_ptr2len_check)(p))
+		(l = (*mb_ptr2len)(p))
 #else
 		1
 #endif
@@ -867,7 +867,7 @@ hardcopy_line(psettings, page_line, ppos
     {
 	outputlen = 1;
 #ifdef FEAT_MBYTE
-	if (has_mbyte && (outputlen = (*mb_ptr2len_check)(line + col)) < 1)
+	if (has_mbyte && (outputlen = (*mb_ptr2len)(line + col)) < 1)
 	    outputlen = 1;
 #endif
 #ifdef FEAT_SYN_HL
--- a/src/macros.h
+++ b/src/macros.h
@@ -254,15 +254,23 @@
  * PTR2CHAR(): get character from pointer.
  */
 #ifdef FEAT_MBYTE
-# define mb_ptr_adv(p)	    p += has_mbyte ? (*mb_ptr2len_check)(p) : 1
+/* Advance multi-byte pointer, skip over composing chars. */
+# define mb_ptr_adv(p)	    p += has_mbyte ? (*mb_ptr2len)(p) : 1
+/* Advance multi-byte pointer, do not skip over composing chars. */
+# define mb_cptr_adv(p)	    p += enc_utf8 ? utf_ptr2len(p) : has_mbyte ? (*mb_ptr2len)(p) : 1
+/* Backup multi-byte pointer. */
 # define mb_ptr_back(s, p)  p -= has_mbyte ? ((*mb_head_off)(s, p - 1) + 1) : 1
+/* get length of multi-byte char, not including composing chars */
+# define mb_cptr2len(p)	    (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
+
 # define MB_COPY_CHAR(f, t) if (has_mbyte) mb_copy_char(&f, &t); else *t++ = *f++
 # define MB_CHARLEN(p)	    (has_mbyte ? mb_charlen(p) : STRLEN(p))
-# define PTR2CHAR(p)	    (has_mbyte ? mb_ptr2char(p) : *(p))
+# define PTR2CHAR(p)	    (has_mbyte ? mb_ptr2char(p) : (int)*(p))
 #else
 # define mb_ptr_adv(p)		++p
+# define mb_cptr_adv(p)		++p
 # define mb_ptr_back(s, p)	--p
 # define MB_COPY_CHAR(f, t)	*t++ = *f++
 # define MB_CHARLEN(p)		STRLEN(p)
-# define PTR2CHAR(p)		(*(p))
+# define PTR2CHAR(p)		((int)*(p))
 #endif
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -126,7 +126,7 @@
 static int enc_canon_search __ARGS((char_u *name));
 static int dbcs_char2len __ARGS((int c));
 static int dbcs_char2bytes __ARGS((int c, char_u *buf));
-static int dbcs_ptr2len_check __ARGS((char_u *p));
+static int dbcs_ptr2len __ARGS((char_u *p));
 static int dbcs_char2cells __ARGS((int c));
 static int dbcs_ptr2char __ARGS((char_u *p));
 
@@ -589,7 +589,7 @@ codepage_invalid:
      */
     if (enc_utf8)
     {
-	mb_ptr2len_check = utfc_ptr2len_check;
+	mb_ptr2len = utfc_ptr2len;
 	mb_char2len = utf_char2len;
 	mb_char2bytes = utf_char2bytes;
 	mb_ptr2cells = utf_ptr2cells;
@@ -600,7 +600,7 @@ codepage_invalid:
     }
     else if (enc_dbcs != 0)
     {
-	mb_ptr2len_check = dbcs_ptr2len_check;
+	mb_ptr2len = dbcs_ptr2len;
 	mb_char2len = dbcs_char2len;
 	mb_char2bytes = dbcs_char2bytes;
 	mb_ptr2cells = dbcs_ptr2cells;
@@ -611,7 +611,7 @@ codepage_invalid:
     }
     else
     {
-	mb_ptr2len_check = latin_ptr2len_check;
+	mb_ptr2len = latin_ptr2len;
 	mb_char2len = latin_char2len;
 	mb_char2bytes = latin_char2bytes;
 	mb_ptr2cells = latin_ptr2cells;
@@ -1054,21 +1054,21 @@ dbcs_char2bytes(c, buf)
 }
 
 /*
- * mb_ptr2len_check() function pointer.
+ * mb_ptr2len() function pointer.
  * Get byte length of character at "*p" but stop at a NUL.
  * For UTF-8 this includes following composing characters.
  * Returns 0 when *p is NUL.
  *
  */
     int
-latin_ptr2len_check(p)
+latin_ptr2len(p)
     char_u	*p;
 {
     return MB_BYTE2LEN(*p);
 }
 
     static int
-dbcs_ptr2len_check(p)
+dbcs_ptr2len(p)
     char_u	*p;
 {
     int		len;
@@ -1255,7 +1255,7 @@ utf_ptr2cells(p)
     {
 	c = utf_ptr2char(p);
 	/* An illegal byte is displayed as <xx>. */
-	if (utf_ptr2len_check(p) == 1 || c == NUL)
+	if (utf_ptr2len(p) == 1 || c == NUL)
 	    return 4;
 	/* If the char is ASCII it must be an overlong sequence. */
 	if (c < 0x80)
@@ -1411,7 +1411,25 @@ mb_ptr2char_adv(pp)
     int		c;
 
     c = (*mb_ptr2char)(*pp);
-    *pp += (*mb_ptr2len_check)(*pp);
+    *pp += (*mb_ptr2len)(*pp);
+    return c;
+}
+
+/*
+ * Get character at **pp and advance *pp to the next character.
+ * Note: composing characters are returned as separate characters.
+ */
+    int
+mb_cptr2char_adv(pp)
+    char_u	**pp;
+{
+    int		c;
+
+    c = (*mb_ptr2char)(*pp);
+    if (enc_utf8)
+	*pp += utf_ptr2len(*pp);
+    else
+	*pp += (*mb_ptr2len)(*pp);
     return c;
 }
 
@@ -1482,14 +1500,14 @@ utfc_ptr2char(p, p1, p2)
     int		cc;
 
     c = utf_ptr2char(p);
-    len = utf_ptr2len_check(p);
+    len = utf_ptr2len(p);
     /* Only accept a composing char when the first char isn't illegal. */
     if ((len > 1 || *p < 0x80)
 	    && p[len] >= 0x80
 	    && UTF_COMPOSINGLIKE(p, p + len))
     {
 	*p1 = utf_ptr2char(p + len);
-	len += utf_ptr2len_check(p + len);
+	len += utf_ptr2len(p + len);
 	if (p[len] >= 0x80 && utf_iscomposing(cc = utf_ptr2char(p + len)))
 	    *p2 = cc;
 	else
@@ -1519,7 +1537,7 @@ utfc_ptr2char_len(p, p1, p2, maxlen)
     int		cc;
 
     c = utf_ptr2char(p);
-    len = utf_ptr2len_check_len(p, maxlen);
+    len = utf_ptr2len_len(p, maxlen);
     /* Only accept a composing char when the first char isn't illegal. */
     if ((len > 1 || *p < 0x80)
 	    && len < maxlen
@@ -1527,7 +1545,7 @@ utfc_ptr2char_len(p, p1, p2, maxlen)
 	    && UTF_COMPOSINGLIKE(p, p + len))
     {
 	*p1 = utf_ptr2char(p + len);
-	len += utf_ptr2len_check_len(p + len, maxlen - len);
+	len += utf_ptr2len_len(p + len, maxlen - len);
 	if (len < maxlen
 		&& p[len] >= 0x80
 		&& utf_iscomposing(cc = utf_ptr2char(p + len)))
@@ -1573,7 +1591,7 @@ utfc_char2bytes(off, buf)
  * Returns 1 for an illegal byte sequence.
  */
     int
-utf_ptr2len_check(p)
+utf_ptr2len(p)
     char_u	*p;
 {
     int		len;
@@ -1607,7 +1625,7 @@ utf_byte2len(b)
  * Returns number > "size" for an incomplete byte sequence.
  */
     int
-utf_ptr2len_check_len(p, size)
+utf_ptr2len_len(p, size)
     char_u	*p;
     int		size;
 {
@@ -1630,7 +1648,7 @@ utf_ptr2len_check_len(p, size)
  * This includes following composing characters.
  */
     int
-utfc_ptr2len_check(p)
+utfc_ptr2len(p)
     char_u	*p;
 {
     int		len;
@@ -1645,7 +1663,7 @@ utfc_ptr2len_check(p)
 	return 1;
 
     /* Skip over first UTF-8 char, stopping at a NUL byte. */
-    len = utf_ptr2len_check(p);
+    len = utf_ptr2len(p);
 
     /* Check for illegal byte. */
     if (len == 1 && b0 >= 0x80)
@@ -1667,7 +1685,7 @@ utfc_ptr2len_check(p)
 #ifdef FEAT_ARABIC
 	prevlen = len;
 #endif
-	len += utf_ptr2len_check(p + len);
+	len += utf_ptr2len(p + len);
     }
 }
 
@@ -1677,7 +1695,7 @@ utfc_ptr2len_check(p)
  * Returns 1 for an illegal char or an incomplete byte sequence.
  */
     int
-utfc_ptr2len_check_len(p, size)
+utfc_ptr2len_len(p, size)
     char_u	*p;
     int		size;
 {
@@ -1692,7 +1710,7 @@ utfc_ptr2len_check_len(p, size)
 	return 1;
 
     /* Skip over first UTF-8 char, stopping at a NUL byte. */
-    len = utf_ptr2len_check_len(p, size);
+    len = utf_ptr2len_len(p, size);
 
     /* Check for illegal byte and incomplete byte sequence. */
     if ((len == 1 && p[0] >= 0x80) || len > size)
@@ -1714,7 +1732,7 @@ utfc_ptr2len_check_len(p, size)
 #ifdef FEAT_ARABIC
 	prevlen = len;
 #endif
-	len += utf_ptr2len_check_len(p + len, size - len);
+	len += utf_ptr2len_len(p + len, size - len);
     }
     return len;
 }
@@ -2276,7 +2294,7 @@ mb_strnicmp(s1, s2, nn)
 	}
 	else
 	{
-	    l = (*mb_ptr2len_check)(s1 + i);
+	    l = (*mb_ptr2len)(s1 + i);
 	    if (l <= 1)
 	    {
 		/* Single byte: first check normally, then with ignore case. */
@@ -2317,7 +2335,7 @@ show_utf8()
     /* Get the byte length of the char under the cursor, including composing
      * characters. */
     line = ml_get_cursor();
-    len = utfc_ptr2len_check(line);
+    len = utfc_ptr2len(line);
     if (len == 0)
     {
 	MSG("NUL");
@@ -2335,7 +2353,7 @@ show_utf8()
 		STRCPY(IObuff + rlen, "+ ");
 		rlen += 2;
 	    }
-	    clen = utf_ptr2len_check(line + i);
+	    clen = utf_ptr2len(line + i);
 	}
 	sprintf((char *)IObuff + rlen, "%02x ", line[i]);
 	--clen;
@@ -2377,7 +2395,7 @@ dbcs_head_off(base, p)
      * byte we are looking for.  Return 1 when we went past it, 0 otherwise. */
     q = base;
     while (q < p)
-	q += dbcs_ptr2len_check(q);
+	q += dbcs_ptr2len(q);
     return (q == p) ? 0 : 1;
 }
 
@@ -2413,7 +2431,7 @@ dbcs_screen_head_off(base, p)
 	if (enc_dbcs == DBCS_JPNU && *q == 0x8e)
 	    ++q;
 	else
-	    q += dbcs_ptr2len_check(q);
+	    q += dbcs_ptr2len(q);
     }
     return (q == p) ? 0 : 1;
 }
@@ -2485,7 +2503,7 @@ mb_copy_char(fp, tp)
     char_u	**fp;
     char_u	**tp;
 {
-    int	    l = (*mb_ptr2len_check)(*fp);
+    int	    l = (*mb_ptr2len)(*fp);
 
     mch_memmove(*tp, *fp, (size_t)l);
     *tp += l;
@@ -2677,8 +2695,8 @@ mb_prevptr(line, p)
 }
 
 /*
- * Return the character length of "str".  Each multi-byte character counts as
- * one.
+ * Return the character length of "str".  Each multi-byte character (with
+ * following composing characters) counts as one.
  */
     int
 mb_charlen(str)
@@ -2690,7 +2708,7 @@ mb_charlen(str)
 	return 0;
 
     for (count = 0; *str != NUL; count++)
-	str += (*mb_ptr2len_check)(str);
+	str += (*mb_ptr2len)(str);
 
     return count;
 }
@@ -2742,7 +2760,7 @@ mb_unescape(pp)
 
 	/* Return a multi-byte character if it's found.  An illegal sequence
 	 * will result in a 1 here. */
-	if ((*mb_ptr2len_check)(buf) > 1)
+	if ((*mb_ptr2len)(buf) > 1)
 	{
 	    *pp = str + n + 1;
 	    return buf;
@@ -3158,10 +3176,10 @@ iconv_string(vcp, str, slen, unconvlenp)
 	    if ((*mb_ptr2cells)((char_u *)from) > 1)
 		*to++ = '?';
 	    if (enc_utf8)
-		l = utfc_ptr2len_check_len((char_u *)from, fromlen);
+		l = utfc_ptr2len_len((char_u *)from, fromlen);
 	    else
 	    {
-		l = (*mb_ptr2len_check)((char_u *)from);
+		l = (*mb_ptr2len)((char_u *)from);
 		if (l > (int)fromlen)
 		    l = fromlen;
 	    }
@@ -3465,7 +3483,7 @@ im_commit_cb(GtkIMContext *context, cons
     else
 	im_str = (char_u *)str;
     clen = 0;
-    for (p = im_str; p < im_str + len; p += (*mb_ptr2len_check)(p))
+    for (p = im_str; p < im_str + len; p += (*mb_ptr2len)(p))
 	clen += (*mb_ptr2cells)(p);
     if (input_conv.vc_type != CONV_NONE)
 	vim_free(im_str);
@@ -3731,7 +3749,7 @@ im_get_feedback_attr(int col)
 
 	/* Get the byte index as used by PangoAttrIterator */
 	for (index = 0; col > 0 && preedit_string[index] != '\0'; --col)
-	    index += utfc_ptr2len_check((char_u *)preedit_string + index);
+	    index += utfc_ptr2len((char_u *)preedit_string + index);
 
 	if (preedit_string[index] != '\0')
 	{
@@ -5233,7 +5251,7 @@ preedit_draw_cbproc(XIC xic, XPointer cl
 		    }
 		}
 		if (has_mbyte)
-		    ptr += mb_ptr2len_check(ptr);
+		    ptr += (*mb_ptr2len)(ptr);
 		else
 #endif
 		    ptr++;
@@ -5846,7 +5864,7 @@ string_convert_ext(vcp, ptr, lenp, uncon
 	    d = retval;
 	    for (i = 0; i < len; ++i)
 	    {
-		l = utf_ptr2len_check(ptr + i);
+		l = utf_ptr2len(ptr + i);
 		if (l == 0)
 		    *d++ = NUL;
 		else if (l == 1)
--- a/src/message.c
+++ b/src/message.c
@@ -263,7 +263,7 @@ trunc_string(s, buf, room)
 	buf[e] = s[e];
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    for (n = (*mb_ptr2len_check)(s + e); --n > 0; )
+	    for (n = (*mb_ptr2len)(s + e); --n > 0; )
 	    {
 		++e;
 		buf[e] = s[e];
@@ -283,7 +283,7 @@ trunc_string(s, buf, room)
 	while (len + n > room)
 	{
 	    n -= ptr2cells(s + i);
-	    i += (*mb_ptr2len_check)(s + i);
+	    i += (*mb_ptr2len)(s + i);
 	}
     }
     else if (enc_utf8)
@@ -718,7 +718,7 @@ msg_may_trunc(force, s)
 	    for (n = 0; size >= room; )
 	    {
 		size -= (*mb_ptr2cells)(s + n);
-		n += (*mb_ptr2len_check)(s + n);
+		n += (*mb_ptr2len)(s + n);
 	    }
 	    --n;
 	}
@@ -1243,7 +1243,7 @@ msg_outtrans_one(p, attr)
 #ifdef FEAT_MBYTE
     int		l;
 
-    if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
     {
 	msg_outtrans_len_attr(p, l, attr);
 	return p + l;
@@ -1291,9 +1291,9 @@ msg_outtrans_len_attr(msgstr, len, attr)
 #ifdef FEAT_MBYTE
 	if (enc_utf8)
 	    /* Don't include composing chars after the end. */
-	    mb_l = utfc_ptr2len_check_len(str, len + 1);
+	    mb_l = utfc_ptr2len_len(str, len + 1);
 	else if (has_mbyte)
-	    mb_l = (*mb_ptr2len_check)(str);
+	    mb_l = (*mb_ptr2len)(str);
 	else
 	    mb_l = 1;
 	if (has_mbyte && mb_l > 1)
@@ -1403,7 +1403,7 @@ msg_outtrans_special(strstart, from)
 	/* Highlight special keys */
 	msg_puts_attr(string, len > 1
 #ifdef FEAT_MBYTE
-		&& (*mb_ptr2len_check)(string) <= 1
+		&& (*mb_ptr2len)(string) <= 1
 #endif
 		? attr : 0);
 	retval += len;
@@ -1463,7 +1463,7 @@ str2special(sp, from)
 
 #ifdef FEAT_MBYTE
     /* For multi-byte characters check for an illegal byte. */
-    if (has_mbyte && MB_BYTE2LEN(*str) > (*mb_ptr2len_check)(str))
+    if (has_mbyte && MB_BYTE2LEN(*str) > (*mb_ptr2len)(str))
     {
 	transchar_nonprint(buf, c);
 	return buf;
@@ -1547,7 +1547,7 @@ msg_prt_line(s, list)
 		c = *p_extra++;
 	}
 #ifdef FEAT_MBYTE
-	else if (has_mbyte && (l = (*mb_ptr2len_check)(s)) > 1)
+	else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
 	{
 	    col += (*mb_ptr2cells)(s);
 	    mch_memmove(buf, s, (size_t)l);
@@ -1855,10 +1855,9 @@ msg_puts_display(str, maxlen, attr, recu
 		{
 		    if (enc_utf8 && maxlen >= 0)
 			/* avoid including composing chars after the end */
-			l = utfc_ptr2len_check_len(s,
-						   (int)((str + maxlen) - s));
+			l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
 		    else
-			l = (*mb_ptr2len_check)(s);
+			l = (*mb_ptr2len)(s);
 		    s = screen_puts_mbyte(s, l, attr);
 		}
 		else
@@ -1915,7 +1914,12 @@ msg_puts_display(str, maxlen, attr, recu
 	if (*s == '\n')		    /* go to next line */
 	{
 	    msg_didout = FALSE;	    /* remember that line is empty */
-	    msg_col = 0;
+#ifdef FEAT_RIGHTLEFT
+	    if (cmdmsg_rl)
+		msg_col = Columns - 1;
+	    else
+#endif
+		msg_col = 0;
 	    if (++msg_row >= Rows)  /* safety check */
 		msg_row = Rows - 1;
 	}
@@ -1944,9 +1948,9 @@ msg_puts_display(str, maxlen, attr, recu
 		cw = (*mb_ptr2cells)(s);
 		if (enc_utf8 && maxlen >= 0)
 		    /* avoid including composing chars after the end */
-		    l = utfc_ptr2len_check_len(s, (int)((str + maxlen) - s));
+		    l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
 		else
-		    l = (*mb_ptr2len_check)(s);
+		    l = (*mb_ptr2len)(s);
 	    }
 	    else
 	    {
@@ -3125,8 +3129,14 @@ msg_advance(col)
     }
     if (col >= Columns)		/* not enough room */
 	col = Columns - 1;
-    while (msg_col < col)
-	msg_putchar(' ');
+#ifdef FEAT_RIGHTLEFT
+    if (cmdmsg_rl)
+	while (msg_col > Columns - col)
+	    msg_putchar(' ');
+    else
+#endif
+	while (msg_col < col)
+	    msg_putchar(' ');
 }
 
 #if defined(FEAT_CON_DIALOG) || defined(PROTO)
@@ -3229,7 +3239,7 @@ do_dialog(type, title, message, buttons,
 		    {
 			if ((*mb_ptr2char)(hotkeys + i) == c)
 			    break;
-			i += (*mb_ptr2len_check)(hotkeys + i) - 1;
+			i += (*mb_ptr2len)(hotkeys + i) - 1;
 		    }
 		    else
 #endif
@@ -3283,7 +3293,7 @@ copy_char(from, to, lowercase)
 	}
 	else
 	{
-	    len = (*mb_ptr2len_check)(from);
+	    len = (*mb_ptr2len)(from);
 	    mch_memmove(to, from, (size_t)len);
 	    return len;
 	}
@@ -3353,7 +3363,7 @@ msg_show_console_dialog(message, buttons
 		    /* advance to next hotkey and set default hotkey */
 #ifdef FEAT_MBYTE
 		    if (has_mbyte)
-			hotkp += (*mb_ptr2len_check)(hotkp);
+			hotkp += (*mb_ptr2len)(hotkp);
 		    else
 #endif
 			++hotkp;
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -1072,7 +1072,7 @@ open_line(dir, flags, old_indent)
 
 			    for (i = 0; p[i] != NUL && i < lead_len; i += l)
 			    {
-				l = mb_ptr2len_check(p + i);
+				l = (*mb_ptr2len)(p + i);
 				if (vim_strnsize(p, i + l) > repl_size)
 				    break;
 			    }
@@ -1102,7 +1102,7 @@ open_line(dir, flags, old_indent)
 				else
 				{
 #ifdef FEAT_MBYTE
-				    int	    l = mb_ptr2len_check(p);
+				    int	    l = (*mb_ptr2len)(p);
 
 				    if (l > 1)
 				    {
@@ -1840,7 +1840,7 @@ ins_bytes_len(p, len)
 
     for (i = 0; i < len; i += n)
     {
-	n = (*mb_ptr2len_check)(p + i);
+	n = (*mb_ptr2len)(p + i);
 	ins_char_bytes(p + i, n);
     }
 # else
@@ -1952,7 +1952,7 @@ ins_char_bytes(buf, charlen)
 		if (vcol > new_vcol && oldp[col + oldlen] == TAB)
 		    break;
 #ifdef FEAT_MBYTE
-		oldlen += (*mb_ptr2len_check)(oldp + col + oldlen);
+		oldlen += (*mb_ptr2len)(oldp + col + oldlen);
 #else
 		++oldlen;
 #endif
@@ -1968,7 +1968,7 @@ ins_char_bytes(buf, charlen)
 	{
 	    /* normal replace */
 #ifdef FEAT_MBYTE
-	    oldlen = (*mb_ptr2len_check)(oldp + col);
+	    oldlen = (*mb_ptr2len)(oldp + col);
 #else
 	    oldlen = 1;
 #endif
@@ -1983,7 +1983,7 @@ ins_char_bytes(buf, charlen)
 	for (i = 0; i < oldlen; ++i)
 	{
 #ifdef FEAT_MBYTE
-	    l = (*mb_ptr2len_check)(oldp + col + i) - 1;
+	    l = (*mb_ptr2len)(oldp + col + i) - 1;
 	    for (j = l; j >= 0; --j)
 		replace_push(oldp[col + i + j]);
 	    i += l;
@@ -2130,7 +2130,7 @@ del_chars(count, fixpos)
     p = ml_get_cursor();
     for (i = 0; i < count && *p != NUL; ++i)
     {
-	l = (*mb_ptr2len_check)(p);
+	l = (*mb_ptr2len)(p);
 	bytes += l;
 	p += l;
     }
@@ -2169,7 +2169,7 @@ del_bytes(count, fixpos)
 #ifdef FEAT_MBYTE
     /* If 'delcombine' is set and deleting (less than) one character, only
      * delete the last combining character. */
-    if (p_deco && enc_utf8 && utfc_ptr2len_check(oldp + col) >= count)
+    if (p_deco && enc_utf8 && utfc_ptr2len(oldp + col) >= count)
     {
 	int	c1, c2;
 	int	n;
@@ -2182,7 +2182,7 @@ del_bytes(count, fixpos)
 	    do
 	    {
 		col = n;
-		count = utf_ptr2len_check(oldp + n);
+		count = utf_ptr2len(oldp + n);
 		n += count;
 	    } while (UTF_COMPOSINGLIKE(oldp + col, oldp + n));
 	    fixpos = 0;
@@ -8237,7 +8237,7 @@ dos_expandpath(
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    len = (*mb_ptr2len_check)(path_end);
+	    len = (*mb_ptr2len)(path_end);
 	    STRNCPY(p, path_end, len);
 	    p += len;
 	    path_end += len;
@@ -8538,7 +8538,7 @@ unix_expandpath(gap, path, wildoff, flag
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    len = (*mb_ptr2len_check)(path_end);
+	    len = (*mb_ptr2len)(path_end);
 	    STRNCPY(p, path_end, len);
 	    p += len;
 	    path_end += len;
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -364,7 +364,7 @@ inc(lp)
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    int l = (*mb_ptr2len_check)(p);
+	    int l = (*mb_ptr2len)(p);
 
 	    lp->col += l;
 	    return ((p[l] != NUL) ? 0 : 2);
@@ -1168,7 +1168,7 @@ vim_strsave_escaped_ext(string, esc_char
     for (p = string; *p; p++)
     {
 #ifdef FEAT_MBYTE
-	if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 	{
 	    length += l;		/* count a multibyte char */
 	    p += l - 1;
@@ -1186,7 +1186,7 @@ vim_strsave_escaped_ext(string, esc_char
 	for (p = string; *p; p++)
 	{
 #ifdef FEAT_MBYTE
-	    if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 	    {
 		mch_memmove(p2, p, (size_t)l);
 		p2 += l;
@@ -1288,7 +1288,7 @@ strup_save(orig)
 
 		/* Reallocate string when byte count changes.  This is rare,
 		 * thus it's OK to do another malloc()/free(). */
-		l = utf_ptr2len_check(p);
+		l = utf_ptr2len(p);
 		nl = utf_char2len(uc);
 		if (nl != l)
 		{
@@ -1305,7 +1305,7 @@ strup_save(orig)
 		utf_char2bytes(uc, p);
 		p += nl;
 	    }
-	    else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 		p += l;		/* skip multi-byte character */
 	    else
 # endif
@@ -1604,7 +1604,7 @@ vim_strchr(string, c)
 	{
 	    if (utf_ptr2char(p) == c)
 		return p;
-	    p += (*mb_ptr2len_check)(p);
+	    p += (*mb_ptr2len)(p);
 	}
 	return NULL;
     }
@@ -1617,7 +1617,7 @@ vim_strchr(string, c)
 	{
 	    if (b == c && p[1] == n2)
 		return p;
-	    p += (*mb_ptr2len_check)(p);
+	    p += (*mb_ptr2len)(p);
 	}
 	return NULL;
     }
@@ -1627,7 +1627,7 @@ vim_strchr(string, c)
 	{
 	    if (b == c)
 		return p;
-	    p += (*mb_ptr2len_check)(p);
+	    p += (*mb_ptr2len)(p);
 	}
 	return NULL;
     }
--- a/src/normal.c
+++ b/src/normal.c
@@ -1731,7 +1731,7 @@ do_pending_operator(cap, old_col, gui_ya
 	{
 	    int		l;
 
-	    l = (*mb_ptr2len_check)(ml_get_pos(&oap->end));
+	    l = (*mb_ptr2len)(ml_get_pos(&oap->end));
 	    if (l > 1)
 		oap->end.col += l - 1;
 	}
@@ -2866,7 +2866,7 @@ do_mouse(oap, c, dir, count, fixindent)
 		    if (*p_sel == 'e' && *ml_get_cursor() != NUL)
 #ifdef FEAT_MBYTE
 			curwin->w_cursor.col +=
-					 (*mb_ptr2len_check)(ml_get_cursor());
+					 (*mb_ptr2len)(ml_get_cursor());
 #else
 			++curwin->w_cursor.col;
 #endif
@@ -2940,7 +2940,7 @@ find_end_of_word(pos)
     while (line[pos->col] != NUL)
     {
 #ifdef FEAT_MBYTE
-	col = pos->col + (*mb_ptr2len_check)(line + pos->col);
+	col = pos->col + (*mb_ptr2len)(line + pos->col);
 #else
 	col = pos->col + 1;
 #endif
@@ -3210,7 +3210,7 @@ find_ident_at_pos(wp, lnum, startcol, st
 		this_class = mb_get_class(ptr + col);
 		if (this_class != 0 && (i == 1 || this_class != 1))
 		    break;
-		col += (*mb_ptr2len_check)(ptr + col);
+		col += (*mb_ptr2len)(ptr + col);
 	    }
 	}
 	else
@@ -3332,7 +3332,7 @@ find_ident_at_pos(wp, lnum, startcol, st
 			&& find_is_eval_item(ptr + col, &col, &bn, FORWARD))
 # endif
 		))
-	    col += (*mb_ptr2len_check)(ptr + col);
+	    col += (*mb_ptr2len)(ptr + col);
     }
     else
 #endif
@@ -5135,7 +5135,7 @@ nv_ident(cap)
 	if (has_mbyte)
 	{
 	    int i;
-	    int len = (*mb_ptr2len_check)(ptr) - 1;
+	    int len = (*mb_ptr2len)(ptr) - 1;
 
 	    for (i = 0; i < len && n >= 1; ++i, --n)
 		*p++ = *ptr++;
@@ -5207,7 +5207,7 @@ get_visual_text(cap, pp, lenp)
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	    /* Correct the length to include the whole last character. */
-	    *lenp += (*mb_ptr2len_check)(*pp + (*lenp - 1)) - 1;
+	    *lenp += (*mb_ptr2len)(*pp + (*lenp - 1)) - 1;
 #endif
     }
     reset_VIsual_and_resel();
@@ -5430,7 +5430,7 @@ nv_right(cap)
 # ifdef FEAT_MBYTE
 		if (has_mbyte)
 		    curwin->w_cursor.col +=
-					 (*mb_ptr2len_check)(ml_get_cursor());
+					 (*mb_ptr2len)(ml_get_cursor());
 		else
 # endif
 		    ++curwin->w_cursor.col;
--- a/src/ops.c
+++ b/src/ops.c
@@ -420,7 +420,7 @@ shift_block(oap, amount)
 	{
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		bd.textstart += (*mb_ptr2len_check)(bd.textstart);
+		bd.textstart += (*mb_ptr2len)(bd.textstart);
 #endif
 	    ++bd.textstart;
 	}
@@ -3324,7 +3324,7 @@ do_put(regname, dir, count, flags)
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
 		/* move to start of next multi-byte character */
-		curwin->w_cursor.col += (*mb_ptr2len_check)(ml_get_cursor());
+		curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
 	    else
 #endif
 #ifdef FEAT_VIRTUALEDIT
@@ -3490,7 +3490,7 @@ do_put(regname, dir, count, flags)
 #ifdef FEAT_MBYTE
 		if (has_mbyte)
 		{
-		    int bytelen = (*mb_ptr2len_check)(ml_get_cursor());
+		    int bytelen = (*mb_ptr2len)(ml_get_cursor());
 
 		    /* put it on the next of the multi-byte character. */
 		    col += bytelen;
@@ -3842,7 +3842,7 @@ ex_display(eap)
 		for (p = yb->y_array[j]; *p && (n -= ptr2cells(p)) >= 0; ++p)
 		{
 #ifdef FEAT_MBYTE
-		    clen = (*mb_ptr2len_check)(p);
+		    clen = (*mb_ptr2len)(p);
 #endif
 		    msg_outtrans_len(p, clen);
 #ifdef FEAT_MBYTE
@@ -3945,7 +3945,7 @@ dis_msg(p, skip_esc)
 	    && (n -= ptr2cells(p)) >= 0)
     {
 #ifdef FEAT_MBYTE
-	if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 	{
 	    msg_outtrans_len(p, l);
 	    p += l;
@@ -5974,7 +5974,7 @@ line_count_info(line, wc, cc, limit, eol
 	    is_word = 1;
 	++chars;
 #ifdef FEAT_MBYTE
-	i += mb_ptr2len_check(line + i);
+	i += (*mb_ptr2len)(line + i);
 #else
 	++i;
 #endif
--- a/src/option.c
+++ b/src/option.c
@@ -4121,7 +4121,7 @@ do_set(arg, opt_flags)
 				    ++arg;	/* remove backslash */
 #ifdef FEAT_MBYTE
 				if (has_mbyte
-					&& (i = (*mb_ptr2len_check)(arg)) > 1)
+					&& (i = (*mb_ptr2len)(arg)) > 1)
 				{
 				    /* copy multibyte char */
 				    mch_memmove(s, arg, (size_t)i);
--- a/src/os_mac.c
+++ b/src/os_mac.c
@@ -118,7 +118,7 @@ mac_expandpath(
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    int len = (*mb_ptr2len_check)(path);
+	    int len = (*mb_ptr2len)(path);
 
 	    STRNCPY(p, path, len);
 	    p += len;
--- a/src/os_mac_conv.c
+++ b/src/os_mac_conv.c
@@ -129,7 +129,7 @@ mac_string_convert(ptr, len, lenp, fail_
 	for (d = retval, in = 0, out = 0; in < len && out < buflen - 1;)
 	{
 	    if (from == kCFStringEncodingUTF8)
-		l = utf_ptr2len_check(ptr + in);
+		l = utf_ptr2len(ptr + in);
 	    else
 		l = 1;
 	    cfstr = CFStringCreateWithBytes(NULL, ptr + in, l, from, 0);
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -919,7 +919,7 @@ utf8_to_ucs2(char_u *instr, int inlen, s
     while (todo > 0)
     {
 	/* Only convert if we have a complete sequence. */
-	l = utf_ptr2len_check_len(p, todo);
+	l = utf_ptr2len_len(p, todo);
 	if (l > todo)
 	{
 	    /* Return length of incomplete sequence. */
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3980,7 +3980,7 @@ mch_call_shell(cmd, options)
 				ta_buf[i] = '\n';
 # ifdef FEAT_MBYTE
 			    if (has_mbyte)
-				i += (*mb_ptr2len_check)(ta_buf + i) - 1;
+				i += (*mb_ptr2len)(ta_buf + i) - 1;
 # endif
 			}
 
@@ -3997,7 +3997,7 @@ mch_call_shell(cmd, options)
 # ifdef FEAT_MBYTE
 				else if (has_mbyte)
 				{
-				    int l = (*mb_ptr2len_check)(ta_buf + i);
+				    int l = (*mb_ptr2len)(ta_buf + i);
 
 				    msg_outtrans_len(ta_buf + i, l);
 				    i += l - 1;
@@ -4097,10 +4097,7 @@ mch_call_shell(cmd, options)
 			     * round. */
 			    for (p = buffer; p < buffer + len; p += l)
 			    {
-				if (enc_utf8)	/* exclude composing chars */
-				    l = utf_ptr2len_check(p);
-				else
-				    l = (*mb_ptr2len_check)(p);
+				l = mb_cptr2len(p);
 				if (l == 0)
 				    l = 1;  /* NUL byte? */
 				else if (MB_BYTE2LEN(*p) != l)
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -2284,7 +2284,7 @@ fname_case(
 
 	    if (enc_dbcs)
 	    {
-		l = (*mb_ptr2len_check)(porig);
+		l = (*mb_ptr2len)(porig);
 		while (--l >= 0)
 		    *ptrue++ = *porig++;
 	    }
--- a/src/proto/mbyte.pro
+++ b/src/proto/mbyte.pro
@@ -6,7 +6,7 @@ int mb_get_class __ARGS((char_u *p));
 int dbcs_class __ARGS((unsigned lead, unsigned trail));
 int latin_char2len __ARGS((int c));
 int latin_char2bytes __ARGS((int c, char_u *buf));
-int latin_ptr2len_check __ARGS((char_u *p));
+int latin_ptr2len __ARGS((char_u *p));
 int utf_char2cells __ARGS((int c));
 int latin_ptr2cells __ARGS((char_u *p));
 int utf_ptr2cells __ARGS((char_u *p));
@@ -18,17 +18,18 @@ int utf_off2cells __ARGS((unsigned off))
 int latin_ptr2char __ARGS((char_u *p));
 int utf_ptr2char __ARGS((char_u *p));
 int mb_ptr2char_adv __ARGS((char_u **pp));
+int mb_cptr2char_adv __ARGS((char_u **pp));
 int arabic_combine __ARGS((int one, int two));
 int arabic_maycombine __ARGS((int two));
 int utf_composinglike __ARGS((char_u *p1, char_u *p2));
 int utfc_ptr2char __ARGS((char_u *p, int *p1, int *p2));
 int utfc_ptr2char_len __ARGS((char_u *p, int *p1, int *p2, int maxlen));
 int utfc_char2bytes __ARGS((int off, char_u *buf));
-int utf_ptr2len_check __ARGS((char_u *p));
+int utf_ptr2len __ARGS((char_u *p));
 int utf_byte2len __ARGS((int b));
-int utf_ptr2len_check_len __ARGS((char_u *p, int size));
-int utfc_ptr2len_check __ARGS((char_u *p));
-int utfc_ptr2len_check_len __ARGS((char_u *p, int size));
+int utf_ptr2len_len __ARGS((char_u *p, int size));
+int utfc_ptr2len __ARGS((char_u *p));
+int utfc_ptr2len_len __ARGS((char_u *p, int size));
 int utf_char2len __ARGS((int c));
 int utf_char2bytes __ARGS((int c, char_u *buf));
 int utf_iscomposing __ARGS((int c));
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -10,6 +10,7 @@ void update_curbuf __ARGS((int type));
 void update_screen __ARGS((int type));
 void update_debug_sign __ARGS((buf_T *buf, linenr_T lnum));
 void updateWindow __ARGS((win_T *wp));
+void rl_mirror __ARGS((char_u *str));
 void status_redraw_all __ARGS((void));
 void status_redraw_curbuf __ARGS((void));
 void redraw_statuslines __ARGS((void));
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -714,7 +714,7 @@ get_equi_class(pp)
     {
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    l = mb_ptr2len_check(p + 2);
+	    l = (*mb_ptr2len)(p + 2);
 #endif
 	if (p[l + 2] == '=' && p[l + 3] == ']')
 	{
@@ -833,7 +833,7 @@ get_coll_element(pp)
     {
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    l = mb_ptr2len_check(p + 2);
+	    l = (*mb_ptr2len)(p + 2);
 #endif
 	if (p[l + 2] == '.' && p[l + 3] == ']')
 	{
@@ -876,7 +876,7 @@ skip_anyof(p)
     while (*p != NUL && *p != ']')
     {
 #ifdef FEAT_MBYTE
-	if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 	    p += l;
 	else
 #endif
@@ -2231,7 +2231,7 @@ collection:
 			    /* produce a multibyte character, including any
 			     * following composing characters */
 			    startc = mb_ptr2char(regparse);
-			    len = (*mb_ptr2len_check)(regparse);
+			    len = (*mb_ptr2len)(regparse);
 			    if (enc_utf8 && utf_char2len(startc) != len)
 				startc = -1;	/* composing chars */
 			    while (--len >= 0)
@@ -2309,7 +2309,7 @@ collection:
 			    off = 0;
 			for (;;)
 			{
-			    l = utf_ptr2len_check(regparse + off);
+			    l = utf_ptr2len(regparse + off);
 			    if (!UTF_COMPOSINGLIKE(regparse + off,
 							  regparse + off + l))
 				break;
@@ -2721,7 +2721,7 @@ skipchr()
     {
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    prevchr_len += (*mb_ptr2len_check)(regparse + prevchr_len);
+	    prevchr_len += (*mb_ptr2len)(regparse + prevchr_len);
 	else
 #endif
 	    ++prevchr_len;
@@ -3462,7 +3462,7 @@ vim_regexec_both(line, col)
 		break;
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		col += (*mb_ptr2len_check)(regline + col);
+		col += (*mb_ptr2len)(regline + col);
 	    else
 #endif
 		++col;
@@ -4100,7 +4100,7 @@ regmatch(scan)
 		opnd = OPERAND(scan);
 		/* Safety check (just in case 'encoding' was changed since
 		 * compiling the program). */
-		if ((len = (*mb_ptr2len_check)(opnd)) < 2)
+		if ((len = (*mb_ptr2len)(opnd)) < 2)
 		{
 		    status = RA_NOMATCH;
 		    break;
@@ -5278,7 +5278,7 @@ do_class:
 		    break;
 	    }
 #ifdef FEAT_MBYTE
-	    else if (has_mbyte && (l = (*mb_ptr2len_check)(scan)) > 1)
+	    else if (has_mbyte && (l = (*mb_ptr2len)(scan)) > 1)
 	    {
 		if (testval != 0)
 		    break;
@@ -5399,7 +5399,7 @@ do_class:
 
 	    /* Safety check (just in case 'encoding' was changed since
 	     * compiling the program). */
-	    if ((len = (*mb_ptr2len_check)(opnd)) > 1)
+	    if ((len = (*mb_ptr2len)(opnd)) > 1)
 	    {
 		if (ireg_ic && enc_utf8)
 		    cf = utf_fold(utf_ptr2char(opnd));
@@ -5443,7 +5443,7 @@ do_class:
 	    else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
 		++scan;
 #ifdef FEAT_MBYTE
-	    else if (has_mbyte && (len = (*mb_ptr2len_check)(scan)) > 1)
+	    else if (has_mbyte && (len = (*mb_ptr2len)(scan)) > 1)
 	    {
 		if ((cstrchr(opnd, (*mb_ptr2char)(scan)) == NULL) == testval)
 		    break;
@@ -6306,7 +6306,7 @@ cstrchr(s, c)
 #ifdef FEAT_MBYTE
     if (has_mbyte)
     {
-	for (p = s; *p != NUL; p += (*mb_ptr2len_check)(p))
+	for (p = s; *p != NUL; p += (*mb_ptr2len)(p))
 	{
 	    if (enc_utf8 && c > 0x80)
 	    {
@@ -6453,7 +6453,7 @@ regtilde(source, magic)
 		++p;
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		p += (*mb_ptr2len_check)(p) - 1;
+		p += (*mb_ptr2len)(p) - 1;
 #endif
 	}
     }
@@ -6694,7 +6694,7 @@ vim_regsub_both(source, dest, copy, magi
 
 	    /* Write to buffer, if copy is set. */
 #ifdef FEAT_MBYTE
-	    if (has_mbyte && (l = (*mb_ptr2len_check)(src - 1)) > 1)
+	    if (has_mbyte && (l = (*mb_ptr2len)(src - 1)) > 1)
 	    {
 		/* TODO: should use "func" here. */
 		if (copy)
@@ -6789,7 +6789,7 @@ vim_regsub_both(source, dest, copy, magi
 			    dst += 2;
 			}
 #ifdef FEAT_MBYTE
-			else if (has_mbyte && (l = (*mb_ptr2len_check)(s)) > 1)
+			else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
 			{
 			    /* TODO: should use "func" here. */
 			    if (copy)
--- a/src/screen.c
+++ b/src/screen.c
@@ -143,9 +143,6 @@ static void screen_line __ARGS((int row,
 static void screen_line __ARGS((int row, int coloff, int endcol, int clear_width));
 # define SCREEN_LINE(r, o, e, c, rl)    screen_line((r), (o), (e), (c))
 #endif
-#ifdef FEAT_RIGHTLEFT
-static void rl_mirror __ARGS((char_u *str));
-#endif
 #ifdef FEAT_VERTSPLIT
 static void draw_vsep_win __ARGS((win_T *wp, int row));
 #endif
@@ -2178,7 +2175,7 @@ fold_line(wp, fold_count, foldinfo, lnum
 	for (p = text; *p != NUL; )
 	{
 	    cells = (*mb_ptr2cells)(p);
-	    c_len = (*mb_ptr2len_check)(p);
+	    c_len = (*mb_ptr2len)(p);
 	    if (col + cells > W_WIDTH(wp)
 # ifdef FEAT_RIGHTLEFT
 		    - (wp->w_p_rl ? col : 0)
@@ -2981,7 +2978,7 @@ win_line(wp, lnum, startrow, endrow)
 		{
 #ifdef FEAT_MBYTE
 		    if (has_mbyte && line[shl->endcol] != NUL)
-			shl->endcol += (*mb_ptr2len_check)(line + shl->endcol);
+			shl->endcol += (*mb_ptr2len)(line + shl->endcol);
 		    else
 #endif
 			++shl->endcol;
@@ -3287,7 +3284,7 @@ win_line(wp, lnum, startrow, endrow)
 				     * it */
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
-					shl->endcol += (*mb_ptr2len_check)(line
+					shl->endcol += (*mb_ptr2len)(line
 							       + shl->endcol);
 				    else
 #endif
@@ -3378,7 +3375,7 @@ win_line(wp, lnum, startrow, endrow)
 		    {
 			/* If the UTF-8 character is more than one byte:
 			 * Decode it into "mb_c". */
-			mb_l = (*mb_ptr2len_check)(p_extra);
+			mb_l = (*mb_ptr2len)(p_extra);
 			mb_utf8 = FALSE;
 			if (mb_l > n_extra)
 			    mb_l = 1;
@@ -3441,7 +3438,7 @@ win_line(wp, lnum, startrow, endrow)
 		{
 		    /* If the UTF-8 character is more than one byte: Decode it
 		     * into "mb_c". */
-		    mb_l = (*mb_ptr2len_check)(ptr);
+		    mb_l = (*mb_ptr2len)(ptr);
 		    mb_utf8 = FALSE;
 		    if (mb_l > 1)
 		    {
@@ -4822,11 +4819,12 @@ screen_line(row, coloff, endcol, clear_w
     }
 }
 
-#ifdef FEAT_RIGHTLEFT
+#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
 /*
- * Mirror text "str" for right-lieft displaying.
+ * Mirror text "str" for right-left displaying.
+ * Only works for single-byte characters (e.g., numbers).
  */
-    static void
+    void
 rl_mirror(str)
     char_u	*str;
 {
@@ -5128,7 +5126,7 @@ win_redr_status_matches(xp, num_matches,
 		++s;
 	    clen += ptr2cells(s);
 #ifdef FEAT_MBYTE
-	    if (has_mbyte && (l = (*mb_ptr2len_check)(s)) > 1)
+	    if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
 	    {
 		STRNCPY(buf + len, s, l);
 		s += l - 1;
@@ -5315,12 +5313,12 @@ win_redr_status(wp)
 		int	clen = 0, i;
 
 		/* Count total number of display cells. */
-		for (i = 0; p[i] != NUL; i += (*mb_ptr2len_check)(p + i))
+		for (i = 0; p[i] != NUL; i += (*mb_ptr2len)(p + i))
 		    clen += (*mb_ptr2cells)(p + i);
 		/* 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;
-					      i += (*mb_ptr2len_check)(p + i))
+					      i += (*mb_ptr2len)(p + i))
 		    clen -= (*mb_ptr2cells)(p + i);
 		len = clen;
 		if (i > 0)
@@ -5679,10 +5677,9 @@ screen_puts_len(text, len, row, col, att
 	if (has_mbyte)
 	{
 	    if (enc_utf8 && len > 0)
-		mbyte_blen = utfc_ptr2len_check_len(ptr,
-						   (int)((text + len) - ptr));
+		mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
 	    else
-		mbyte_blen = (*mb_ptr2len_check)(ptr);
+		mbyte_blen = (*mb_ptr2len)(ptr);
 	    if (enc_dbcs == DBCS_JPNU && c == 0x8e)
 		mbyte_cells = 1;
 	    else if (enc_dbcs != 0)
@@ -8583,7 +8580,7 @@ win_redr_ruler(wp, always)
 	if (has_mbyte)
 	{
 	    o = 0;
-	    for (i = 0; buffer[i] != NUL; i += (*mb_ptr2len_check)(buffer + i))
+	    for (i = 0; buffer[i] != NUL; i += (*mb_ptr2len)(buffer + i))
 	    {
 		o += (*mb_ptr2cells)(buffer + i);
 		if (this_ru_col + o > WITH_WIDTH(width))
--- a/src/search.c
+++ b/src/search.c
@@ -259,7 +259,7 @@ reverse_text(s)
 	    {
 		int	mb_len;
 
-		mb_len = (*mb_ptr2len_check)(s + s_i);
+		mb_len = (*mb_ptr2len)(s + s_i);
 		rev_i -= mb_len;
 		mch_memmove(rev + rev_i, s + s_i, mb_len);
 		s_i += mb_len - 1;
@@ -372,7 +372,7 @@ ignorecase(pat)
 #ifdef FEAT_MBYTE
 	    int		l;
 
-	    if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
 	    {
 		if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
 		{
@@ -544,7 +544,7 @@ searchit(win, buf, pos, dir, pat, count,
     /* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */
     else if (has_mbyte && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
 						     && pos->col < MAXCOL - 2)
-	extra_col = (*mb_ptr2len_check)(ml_get_buf(buf, pos->lnum, FALSE)
+	extra_col = (*mb_ptr2len)(ml_get_buf(buf, pos->lnum, FALSE)
 								  + pos->col);
 #endif
     else
@@ -647,7 +647,7 @@ searchit(win, buf, pos, dir, pat, count,
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
 					matchcol +=
-					  (*mb_ptr2len_check)(ptr + matchcol);
+					  (*mb_ptr2len)(ptr + matchcol);
 				    else
 #endif
 					++matchcol;
@@ -660,7 +660,7 @@ searchit(win, buf, pos, dir, pat, count,
 				{
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
-					matchcol += (*mb_ptr2len_check)(ptr
+					matchcol += (*mb_ptr2len)(ptr
 								  + matchcol);
 				    else
 #endif
@@ -750,7 +750,7 @@ searchit(win, buf, pos, dir, pat, count,
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
 					matchcol +=
-					  (*mb_ptr2len_check)(ptr + matchcol);
+					  (*mb_ptr2len)(ptr + matchcol);
 				    else
 #endif
 					++matchcol;
@@ -767,7 +767,7 @@ searchit(win, buf, pos, dir, pat, count,
 #ifdef FEAT_MBYTE
 				    if (has_mbyte)
 					matchcol +=
-					  (*mb_ptr2len_check)(ptr + matchcol);
+					  (*mb_ptr2len)(ptr + matchcol);
 				    else
 #endif
 					++matchcol;
@@ -1447,7 +1447,7 @@ searchc(cap, t_cmd)
 	    {
 		if (dir > 0)
 		{
-		    col += (*mb_ptr2len_check)(p + col);
+		    col += (*mb_ptr2len)(p + col);
 		    if (col >= len)
 			return FAIL;
 		}
@@ -1747,7 +1747,7 @@ findmatchlimit(oap, initc, flags, maxtra
 			break;
 #ifdef FEAT_MBYTE
 		    if (has_mbyte)
-			pos.col += (*mb_ptr2len_check)(linep + pos.col);
+			pos.col += (*mb_ptr2len)(linep + pos.col);
 		    else
 #endif
 			++pos.col;
@@ -1950,7 +1950,7 @@ findmatchlimit(oap, initc, flags, maxtra
 	    {
 #ifdef FEAT_MBYTE
 		if (has_mbyte)
-		    pos.col += (*mb_ptr2len_check)(linep + pos.col);
+		    pos.col += (*mb_ptr2len)(linep + pos.col);
 		else
 #endif
 		    ++pos.col;
@@ -4030,7 +4030,7 @@ find_next_quote(line, col, quotechar, es
 	    break;
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    col += (*mb_ptr2len_check)(line + col);
+	    col += (*mb_ptr2len)(line + col);
 	else
 #endif
 	    ++col;
--- a/src/spell.c
+++ b/src/spell.c
@@ -51,8 +51,9 @@
  */
 
 /* Use SPELL_PRINTTREE for debugging: dump the word tree after adding a word.
- * Only use for small word lists!
- * SPELL_COMPRESS_CNT is in how many words we compress the tree. */
+ * Only use it for small word lists!
+ * SPELL_COMPRESS_CNT is in how many words we compress the tree to limit the
+ * amount of memory used (esp. for Italian). */
 #if 0
 # define SPELL_PRINTTREE
 # define SPELL_COMPRESS_CNT 1
@@ -639,6 +640,7 @@ static void clear_midword __ARGS((buf_T 
 static void use_midword __ARGS((slang_T *lp, buf_T *buf));
 static int find_region __ARGS((char_u *rp, char_u *region));
 static int captype __ARGS((char_u *word, char_u *end));
+static int badword_captype __ARGS((char_u *word, char_u *end));
 static void spell_reload_one __ARGS((char_u *fname, int added_word));
 static int set_spell_charflags __ARGS((char_u *flags, int cnt, char_u *upp));
 static int set_spell_chartab __ARGS((char_u *fol, char_u *low, char_u *upp));
@@ -722,7 +724,7 @@ static linenr_T apply_prefixes __ARGS((s
 	    : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
 # else
 #  define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
-	    : (c) < 256 ? spelltab.st_isu[c] : (c))
+	    : (c) < 256 ? spelltab.st_isu[c] : (FALSE))
 # endif
 #endif
 
@@ -873,7 +875,7 @@ spell_check(wp, ptr, attrp, capcol)
 
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		return mb_ptr2len_check(ptr);
+		return (*mb_ptr2len)(ptr);
 #endif
 	    return 1;
 	}
@@ -1358,7 +1360,8 @@ spell_valid_case(wordflags, treeflags)
 {
     return ((wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0)
 	    || ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0
-		&& ((treeflags & WF_ONECAP) == 0 || wordflags == WF_ONECAP)));
+		&& ((treeflags & WF_ONECAP) == 0
+					   || (wordflags & WF_ONECAP) != 0)));
 }
 
 /*
@@ -2303,8 +2306,8 @@ set_sofo(lp, from, to)
 	 * sl_sal_first[] for this. */
 	for (p = from, s = to; *p != NUL && *s != NUL; )
 	{
-	    c = mb_ptr2char_adv(&p);
-	    mb_ptr_adv(s);
+	    c = mb_cptr2char_adv(&p);
+	    mb_cptr_adv(s);
 	    if (c >= 256)
 		++lp->sl_sal_first[c & 0xff];
 	}
@@ -2327,8 +2330,8 @@ set_sofo(lp, from, to)
 	vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
 	for (p = from, s = to; *p != NUL && *s != NUL; )
 	{
-	    c = mb_ptr2char_adv(&p);
-	    i = mb_ptr2char_adv(&s);
+	    c = mb_cptr2char_adv(&p);
+	    i = mb_cptr2char_adv(&s);
 	    if (c >= 256)
 	    {
 		/* Append the from-to chars at the end of the list with
@@ -2840,8 +2843,8 @@ use_midword(lp, buf)
 	    char_u  *bp;
 
 	    c = mb_ptr2char(p);
-	    l = mb_ptr2len_check(p);
-	    if (c < 256)
+	    l = (*mb_ptr2len)(p);
+	    if (c < 256 && l <= 2)
 		buf->b_spell_ismw[c] = TRUE;
 	    else if (buf->b_spell_ismw_mb == NULL)
 		/* First multi-byte char in "b_spell_ismw_mb". */
@@ -2945,6 +2948,50 @@ captype(word, end)
     return 0;
 }
 
+/*
+ * Like captype() but for a KEEPCAP word add ONECAP if the word starts with a
+ * capital.  So that make_case_word() can turn WOrd into Word.
+ * Add ALLCAP for "WOrD".
+ */
+    static int
+badword_captype(word, end)
+    char_u	*word;
+    char_u	*end;
+{
+    int		flags = captype(word, end);
+    int		l, u;
+    int		first;
+    char_u	*p;
+
+    if (flags & WF_KEEPCAP)
+    {
+	/* Count the number of UPPER and lower case letters. */
+	l = u = 0;
+	first = FALSE;
+	for (p = word; p < end; mb_ptr_adv(p))
+	{
+	    if (SPELL_ISUPPER(PTR2CHAR(p)))
+	    {
+		++u;
+		if (p == word)
+		    first = TRUE;
+	    }
+	    else
+		++l;
+	}
+
+	/* If there are more UPPER than lower case letters suggest an
+	 * ALLCAP word.  Otherwise, if the first letter is UPPER then
+	 * suggest ONECAP.  Exception: "ALl" most likely should be "All",
+	 * require three upper case letters. */
+	if (u > l && u > 2)
+	    flags |= WF_ALLCAP;
+	else if (first)
+	    flags |= WF_ONECAP;
+    }
+    return flags;
+}
+
 # if defined(FEAT_MBYTE) || defined(EXITFREE) || defined(PROTO)
 /*
  * Free all languages.
@@ -3097,8 +3144,8 @@ typedef struct affheader_S
 
 /*
  * Structure that is used to store the items in the word tree.  This avoids
- * the need to keep track of each allocated thing, it's freed all at once
- * after ":mkspell" is done.
+ * the need to keep track of each allocated thing, everything is freed all at
+ * once after ":mkspell" is done.
  */
 #define  SBLOCKSIZE 16000	/* size of sb_data */
 typedef struct sblock_S sblock_T;
@@ -3129,7 +3176,10 @@ struct wordnode_S
     wordnode_T	*wn_child;	/* child (next byte in word) */
     wordnode_T  *wn_sibling;	/* next sibling (alternate byte in word,
 				   always sorted) */
-    int		wn_refs;	/* nr of references to this node */
+    int		wn_refs;	/* Nr. of references to this node.  Only
+				   relevant for first node in a list of
+				   siblings, in following siblings it is
+				   always one. */
     char_u	wn_byte;	/* Byte for this node. NUL for word end */
     char_u	wn_prefixID;	/* when "wn_byte" is NUL: supported/required
 				   prefix ID or 0 */
@@ -3152,10 +3202,22 @@ typedef struct spellinfo_S
 {
     wordnode_T	*si_foldroot;	/* tree with case-folded words */
     long	si_foldwcount;	/* nr of words in si_foldroot */
+    int		si_fold_added;	/* nr of words added since compressing */
+
     wordnode_T	*si_keeproot;	/* tree with keep-case words */
     long	si_keepwcount;	/* nr of words in si_keeproot */
+    int		si_keep_added;	/* nr of words added since compressing */
+
     wordnode_T	*si_prefroot;	/* tree with postponed prefixes */
+
     sblock_T	*si_blocks;	/* memory blocks used */
+    wordnode_T	*si_first_free; /* List of nodes that have been freed during
+				   compression, linked by "wn_child" field. */
+#ifdef SPELL_PRINTTREE
+    int		si_wordnode_nr;	/* sequence nr for nodes */
+#endif
+
+
     int		si_ascii;	/* handling only ASCII words */
     int		si_add;		/* addition file */
     int		si_clear_chartab;   /* when TRUE clear char tables */
@@ -3163,6 +3225,7 @@ typedef struct spellinfo_S
     vimconv_T	si_conv;	/* for conversion to 'encoding' */
     int		si_memtot;	/* runtime memory used */
     int		si_verbose;	/* verbose messages */
+    int		si_msg_count;	/* number of words added since last message */
     int		si_region_count; /* number of regions supported (1 when there
 				    are no regions) */
     char_u	si_region_name[16]; /* region names (if count > 1) */
@@ -3181,28 +3244,29 @@ typedef struct spellinfo_S
     int		si_newID;	/* current value for ah_newID */
 } spellinfo_T;
 
-static afffile_T *spell_read_aff __ARGS((char_u *fname, spellinfo_T *spin));
+static afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname));
 static int str_equal __ARGS((char_u *s1, char_u	*s2));
 static void add_fromto __ARGS((spellinfo_T *spin, garray_T *gap, char_u	*from, char_u *to));
 static int sal_to_bool __ARGS((char_u *s));
 static int has_non_ascii __ARGS((char_u *s));
 static void spell_free_aff __ARGS((afffile_T *aff));
-static int spell_read_dic __ARGS((char_u *fname, spellinfo_T *spin, afffile_T *affile));
-static char_u *get_pfxlist __ARGS((afffile_T *affile, char_u *afflist, sblock_T	**blp));
-static int store_aff_word __ARGS((char_u *word, spellinfo_T *spin, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int comb, int flags, char_u *pfxlist));
-static int spell_read_wordfile __ARGS((char_u *fname, spellinfo_T *spin));
-static void *getroom __ARGS((sblock_T **blp, size_t len, int align));
-static char_u *getroom_save __ARGS((sblock_T **blp, char_u *s));
+static int spell_read_dic __ARGS((spellinfo_T *spin, char_u *fname, afffile_T *affile));
+static char_u *get_pfxlist __ARGS((spellinfo_T *spin, afffile_T *affile, char_u *afflist));
+static int store_aff_word __ARGS((spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int comb, int flags, char_u *pfxlist));
+static int spell_read_wordfile __ARGS((spellinfo_T *spin, char_u *fname));
+static void *getroom __ARGS((spellinfo_T *spin, size_t len, int align));
+static char_u *getroom_save __ARGS((spellinfo_T *spin, char_u *s));
 static void free_blocks __ARGS((sblock_T *bl));
-static wordnode_T *wordtree_alloc __ARGS((sblock_T **blp));
-static int store_word __ARGS((char_u *word, spellinfo_T *spin, int flags, int region, char_u *pfxlist));
-static int tree_add_word __ARGS((char_u *word, wordnode_T *tree, int flags, int region, int prefixID, spellinfo_T *spin));
-static wordnode_T *get_wordnode __ARGS((sblock_T **blp));
-static void free_wordnode __ARGS((wordnode_T *n));
-static void wordtree_compress __ARGS((wordnode_T *root, spellinfo_T *spin));
-static int node_compress __ARGS((wordnode_T *node, hashtab_T *ht, int *tot));
+static wordnode_T *wordtree_alloc __ARGS((spellinfo_T *spin));
+static int store_word __ARGS((spellinfo_T *spin, char_u *word, int flags, int region, char_u *pfxlist));
+static int tree_add_word __ARGS((spellinfo_T *spin, char_u *word, wordnode_T *tree, int flags, int region, int prefixID));
+static wordnode_T *get_wordnode __ARGS((spellinfo_T *spin));
+static void deref_wordnode __ARGS((spellinfo_T *spin, wordnode_T *node));
+static void free_wordnode __ARGS((spellinfo_T *spin, wordnode_T *n));
+static void wordtree_compress __ARGS((spellinfo_T *spin, wordnode_T *root));
+static int node_compress __ARGS((spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, int *tot));
 static int node_equal __ARGS((wordnode_T *n1, wordnode_T *n2));
-static void write_vim_spell __ARGS((char_u *fname, spellinfo_T *spin));
+static void write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname));
 static void clear_node __ARGS((wordnode_T *node));
 static int put_node __ARGS((FILE *fd, wordnode_T *node, int index, int regionmask, int prefixtree));
 static void mkspell __ARGS((int fcount, char_u **fnames, int ascii, int overwrite, int added_word));
@@ -3213,8 +3277,6 @@ static void init_spellfile __ARGS((void)
  * Use a negative number with the lower 8 bits zero. */
 #define PFX_FLAGS	-256
 
-static int  words_added = 0;	    /* number of words added to tree */
-
 #ifdef SPELL_PRINTTREE
 /*
  * For debugging the tree code: print the current tree in a (more or less)
@@ -3321,9 +3383,9 @@ spell_print_tree(wordnode_T *root)
  * Returns an afffile_T, NULL for complete failure.
  */
     static afffile_T *
-spell_read_aff(fname, spin)
+spell_read_aff(spin, fname)
+    spellinfo_T	*spin;
     char_u	*fname;
-    spellinfo_T	*spin;
 {
     FILE	*fd;
     afffile_T	*aff;
@@ -3389,7 +3451,7 @@ spell_read_aff(fname, spin)
     /*
      * Allocate and init the afffile_T structure.
      */
-    aff = (afffile_T *)getroom(&spin->si_blocks, sizeof(afffile_T), TRUE);
+    aff = (afffile_T *)getroom(spin, sizeof(afffile_T), TRUE);
     if (aff == NULL)
 	return NULL;
     hash_init(&aff->af_pref);
@@ -3516,14 +3578,14 @@ spell_read_aff(fname, spin)
 						       fname, lnum, items[4]);
 
 		/* New affix letter. */
-		cur_aff = (affheader_T *)getroom(&spin->si_blocks,
+		cur_aff = (affheader_T *)getroom(spin,
 						   sizeof(affheader_T), TRUE);
 		if (cur_aff == NULL)
 		    break;
 #ifdef FEAT_MBYTE
 		if (has_mbyte)
 		{
-		    l = mb_ptr2len_check(items[1]);
+		    l = (*mb_ptr2len)(items[1]);
 		    if (l >= AH_KEY_LEN)
 			l = 1;	/* too long, must be an overlong sequence */
 		    else
@@ -3591,18 +3653,16 @@ spell_read_aff(fname, spin)
 
 		/* New item for an affix letter. */
 		--aff_todo;
-		aff_entry = (affentry_T *)getroom(&spin->si_blocks,
+		aff_entry = (affentry_T *)getroom(spin,
 						    sizeof(affentry_T), TRUE);
 		if (aff_entry == NULL)
 		    break;
 		aff_entry->ae_rare = rare;
 
 		if (STRCMP(items[2], "0") != 0)
-		    aff_entry->ae_chop = getroom_save(&spin->si_blocks,
-								    items[2]);
+		    aff_entry->ae_chop = getroom_save(spin, items[2]);
 		if (STRCMP(items[3], "0") != 0)
-		    aff_entry->ae_add = getroom_save(&spin->si_blocks,
-								    items[3]);
+		    aff_entry->ae_add = getroom_save(spin, items[3]);
 
 		/* Don't use an affix entry with non-ASCII characters when
 		 * "spin->si_ascii" is TRUE. */
@@ -3616,8 +3676,7 @@ spell_read_aff(fname, spin)
 		    {
 			char_u	buf[MAXLINELEN];
 
-			aff_entry->ae_cond = getroom_save(&spin->si_blocks,
-								    items[4]);
+			aff_entry->ae_cond = getroom_save(spin, items[4]);
 			if (*items[0] == 'P')
 			    sprintf((char *)buf, "^%s", items[4]);
 			else
@@ -3638,7 +3697,7 @@ spell_read_aff(fname, spin)
 			if (aff_entry->ae_chop != NULL
 				&& aff_entry->ae_add != NULL
 #ifdef FEAT_MBYTE
-				&& aff_entry->ae_chop[mb_ptr2len_check(
+				&& aff_entry->ae_chop[(*mb_ptr2len)(
 						   aff_entry->ae_chop)] == NUL
 #else
 				&& aff_entry->ae_chop[1] == NUL
@@ -3673,7 +3732,7 @@ spell_read_aff(fname, spin)
 					{
 					    onecap_copy(items[4], buf, TRUE);
 					    aff_entry->ae_cond = getroom_save(
-						       &spin->si_blocks, buf);
+								   spin, buf);
 					}
 					else
 #endif
@@ -3713,7 +3772,7 @@ spell_read_aff(fname, spin)
 				if (aff_entry->ae_cond == NULL)
 				    *pp = NULL;
 				else
-				    *pp = getroom_save(&spin->si_blocks,
+				    *pp = getroom_save(spin,
 							  aff_entry->ae_cond);
 			    }
 
@@ -3731,8 +3790,8 @@ spell_read_aff(fname, spin)
 				n |= WFP_NC;
 			    if (upper)
 				n |= WFP_UP;
-			    tree_add_word(p, spin->si_prefroot, n,
-						idx, cur_aff->ah_newID, spin);
+			    tree_add_word(spin, p, spin->si_prefroot, n,
+						      idx, cur_aff->ah_newID);
 			}
 		    }
 		}
@@ -3924,9 +3983,9 @@ add_fromto(spin, gap, from, to)
     {
 	ftp = ((fromto_T *)gap->ga_data) + gap->ga_len;
 	(void)spell_casefold(from, STRLEN(from), word, MAXWLEN);
-	ftp->ft_from = getroom_save(&spin->si_blocks, word);
+	ftp->ft_from = getroom_save(spin, word);
 	(void)spell_casefold(to, STRLEN(to), word, MAXWLEN);
-	ftp->ft_to = getroom_save(&spin->si_blocks, word);
+	ftp->ft_to = getroom_save(spin, word);
 	++gap->ga_len;
     }
 }
@@ -4000,9 +4059,9 @@ spell_free_aff(aff)
  * Returns OK or FAIL;
  */
     static int
-spell_read_dic(fname, spin, affile)
+spell_read_dic(spin, fname, affile)
+    spellinfo_T	*spin;
     char_u	*fname;
-    spellinfo_T	*spin;
     afffile_T	*affile;
 {
     hashtab_T	ht;
@@ -4035,9 +4094,6 @@ spell_read_dic(fname, spin, affile)
     /* The hashtable is only used to detect duplicated words. */
     hash_init(&ht);
 
-    spin->si_foldwcount = 0;
-    spin->si_keepwcount = 0;
-
     if (spin->si_verbose || p_verbose > 2)
     {
 	if (!spin->si_verbose)
@@ -4048,6 +4104,9 @@ spell_read_dic(fname, spin, affile)
 	    verbose_leave();
     }
 
+    /* start with a message for the first line */
+    spin->si_msg_count = 999999;
+
     /* Read and ignore the first line: word count. */
     (void)vim_fgets(line, MAXLINELEN, fd);
     if (!vim_isdigit(*skipwhite(line)))
@@ -4106,9 +4165,10 @@ spell_read_dic(fname, spin, affile)
 	    w = line;
 	}
 
-	/* This takes time, print a message now and then. */
-	if (spin->si_verbose && (lnum & 0x3ff) == 0)
-	{
+	/* This takes time, print a message every 10000 words. */
+	if (spin->si_verbose && spin->si_msg_count > 10000)
+	{
+	    spin->si_msg_count = 0;
 	    vim_snprintf((char *)message, sizeof(message),
 		    _("line %6d, word %6d - %s"),
 		       lnum, spin->si_foldwcount + spin->si_keepwcount, w);
@@ -4121,7 +4181,7 @@ spell_read_dic(fname, spin, affile)
 	}
 
 	/* Store the word in the hashtable to be able to find duplicates. */
-	dw = (char_u *)getroom_save(&spin->si_blocks, w);
+	dw = (char_u *)getroom_save(spin, w);
 	if (dw == NULL)
 	    retval = FAIL;
 	vim_free(pc);
@@ -4154,24 +4214,24 @@ spell_read_dic(fname, spin, affile)
 
 	    if (affile->af_pfxpostpone)
 		/* Need to store the list of prefix IDs with the word. */
-		pfxlist = get_pfxlist(affile, afflist, &spin->si_blocks);
+		pfxlist = get_pfxlist(spin, affile, afflist);
 	}
 
 	/* Add the word to the word tree(s). */
-	if (store_word(dw, spin, flags, spin->si_region, pfxlist) == FAIL)
+	if (store_word(spin, dw, flags, spin->si_region, pfxlist) == FAIL)
 	    retval = FAIL;
 
 	if (afflist != NULL)
 	{
 	    /* Find all matching suffixes and add the resulting words.
 	     * Additionally do matching prefixes that combine. */
-	    if (store_aff_word(dw, spin, afflist, affile,
+	    if (store_aff_word(spin, dw, afflist, affile,
 			   &affile->af_suff, &affile->af_pref,
 					       FALSE, flags, pfxlist) == FAIL)
 		retval = FAIL;
 
 	    /* Find all matching prefixes and add the resulting words. */
-	    if (store_aff_word(dw, spin, afflist, affile,
+	    if (store_aff_word(spin, dw, afflist, affile,
 			  &affile->af_pref, NULL,
 					       FALSE, flags, pfxlist) == FAIL)
 		retval = FAIL;
@@ -4194,10 +4254,10 @@ spell_read_dic(fname, spin, affile)
  * or when out of memory.
  */
     static char_u *
-get_pfxlist(affile, afflist, blp)
+get_pfxlist(spin, affile, afflist)
+    spellinfo_T	*spin;
     afffile_T	*affile;
     char_u	*afflist;
-    sblock_T	**blp;
 {
     char_u	*p;
     int		cnt;
@@ -4226,7 +4286,7 @@ get_pfxlist(affile, afflist, blp)
 	    }
 	}
 	if (round == 1 && cnt > 0)
-	    res = getroom(blp, cnt + 1, FALSE);
+	    res = getroom(spin, cnt + 1, FALSE);
 	if (res == NULL)
 	    break;
     }
@@ -4246,9 +4306,9 @@ get_pfxlist(affile, afflist, blp)
  * Returns FAIL when out of memory.
  */
     static int
-store_aff_word(word, spin, afflist, affile, ht, xht, comb, flags, pfxlist)
+store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags, pfxlist)
+    spellinfo_T	*spin;		/* spell info */
     char_u	*word;		/* basic word start */
-    spellinfo_T	*spin;		/* spell info */
     char_u	*afflist;	/* list of names of supported affixes */
     afffile_T	*affile;
     hashtab_T	*ht;
@@ -4361,14 +4421,14 @@ store_aff_word(word, spin, afflist, affi
 			}
 
 			/* Store the modified word. */
-			if (store_word(newword, spin, use_flags,
+			if (store_word(spin, newword, use_flags,
 					spin->si_region, use_pfxlist) == FAIL)
 			    retval = FAIL;
 
 			/* When added a suffix and combining is allowed also
 			 * try adding prefixes additionally. */
 			if (xht != NULL && ah->ah_combine)
-			    if (store_aff_word(newword, spin, afflist, affile,
+			    if (store_aff_word(spin, newword, afflist, affile,
 					  xht, NULL, TRUE,
 					  use_flags, use_pfxlist) == FAIL)
 				retval = FAIL;
@@ -4385,9 +4445,9 @@ store_aff_word(word, spin, afflist, affi
  * Read a file with a list of words.
  */
     static int
-spell_read_wordfile(fname, spin)
+spell_read_wordfile(spin, fname)
+    spellinfo_T	*spin;
     char_u	*fname;
-    spellinfo_T	*spin;
 {
     FILE	*fd;
     long	lnum = 0;
@@ -4573,7 +4633,7 @@ spell_read_wordfile(fname, spin)
 	}
 
 	/* Normal word: store it. */
-	if (store_word(line, spin, flags, regionmask, NULL) == FAIL)
+	if (store_word(spin, line, flags, regionmask, NULL) == FAIL)
 	{
 	    retval = FAIL;
 	    break;
@@ -4598,18 +4658,19 @@ spell_read_wordfile(fname, spin)
 
 /*
  * Get part of an sblock_T, "len" bytes long.
- * This avoids calling free() for every little struct we use.
+ * This avoids calling free() for every little struct we use (and keeping
+ * track of them).
  * The memory is cleared to all zeros.
  * Returns NULL when out of memory.
  */
     static void *
-getroom(blp, len, align)
-    sblock_T	**blp;
+getroom(spin, len, align)
+    spellinfo_T *spin;
     size_t	len;		/* length needed */
     int		align;		/* align for pointer */
 {
     char_u	*p;
-    sblock_T	*bl = *blp;
+    sblock_T	*bl = spin->si_blocks;
 
     if (align && bl != NULL)
 	/* Round size up for alignment.  On some systems structures need to be
@@ -4623,8 +4684,8 @@ getroom(blp, len, align)
 	bl = (sblock_T *)alloc_clear((unsigned)(sizeof(sblock_T) + SBLOCKSIZE));
 	if (bl == NULL)
 	    return NULL;
-	bl->sb_next = *blp;
-	*blp = bl;
+	bl->sb_next = spin->si_blocks;
+	spin->si_blocks = bl;
 	bl->sb_used = 0;
     }
 
@@ -4638,13 +4699,13 @@ getroom(blp, len, align)
  * Make a copy of a string into memory allocated with getroom().
  */
     static char_u *
-getroom_save(blp, s)
-    sblock_T	**blp;
+getroom_save(spin, s)
+    spellinfo_T	*spin;
     char_u	*s;
 {
     char_u	*sc;
 
-    sc = (char_u *)getroom(blp, STRLEN(s) + 1, FALSE);
+    sc = (char_u *)getroom(spin, STRLEN(s) + 1, FALSE);
     if (sc != NULL)
 	STRCPY(sc, s);
     return sc;
@@ -4672,10 +4733,10 @@ free_blocks(bl)
  * Allocate the root of a word tree.
  */
     static wordnode_T *
-wordtree_alloc(blp)
-    sblock_T	**blp;
-{
-    return (wordnode_T *)getroom(blp, sizeof(wordnode_T), TRUE);
+wordtree_alloc(spin)
+    spellinfo_T *spin;
+{
+    return (wordnode_T *)getroom(spin, sizeof(wordnode_T), TRUE);
 }
 
 /*
@@ -4687,9 +4748,9 @@ wordtree_alloc(blp)
  * When "pfxlist" is not NULL store the word for each postponed prefix ID.
  */
     static int
-store_word(word, spin, flags, region, pfxlist)
+store_word(spin, word, flags, region, pfxlist)
+    spellinfo_T	*spin;
     char_u	*word;
-    spellinfo_T	*spin;
     int		flags;		/* extra flags, WF_BANNED */
     int		region;		/* supported region(s) */
     char_u	*pfxlist;	/* list of prefix IDs or NULL */
@@ -4703,19 +4764,19 @@ store_word(word, spin, flags, region, pf
     (void)spell_casefold(word, len, foldword, MAXWLEN);
     for (p = pfxlist; res == OK; ++p)
     {
-	res = tree_add_word(foldword, spin->si_foldroot, ct | flags,
-					    region, p == NULL ? 0 : *p, spin);
+	res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags,
+						  region, p == NULL ? 0 : *p);
 	if (p == NULL || *p == NUL)
 	    break;
     }
     ++spin->si_foldwcount;
 
-    if (res == OK && (ct == WF_KEEPCAP || flags & WF_KEEPCAP))
+    if (res == OK && (ct == WF_KEEPCAP || (flags & WF_KEEPCAP)))
     {
 	for (p = pfxlist; res == OK; ++p)
 	{
-	    res = tree_add_word(word, spin->si_keeproot, flags,
-					    region, p == NULL ? 0 : *p, spin);
+	    res = tree_add_word(spin, word, spin->si_keeproot, flags,
+						  region, p == NULL ? 0 : *p);
 	    if (p == NULL || *p == NUL)
 		break;
 	}
@@ -4731,20 +4792,19 @@ store_word(word, spin, flags, region, pf
  * Returns FAIL when out of memory.
  */
     static int
-tree_add_word(word, root, flags, region, prefixID, spin)
+tree_add_word(spin, word, root, flags, region, prefixID)
+    spellinfo_T	*spin;
     char_u	*word;
     wordnode_T	*root;
     int		flags;
     int		region;
     int		prefixID;
-    spellinfo_T	*spin;
 {
     wordnode_T	*node = root;
     wordnode_T	*np;
     wordnode_T	*copyp, **copyprev;
     wordnode_T	**prev = NULL;
     int		i;
-    sblock_T	**blp = &spin->si_blocks;
 
     /* Add each byte of the word to the tree, including the NUL at the end. */
     for (i = 0; ; ++i)
@@ -4759,7 +4819,7 @@ tree_add_word(word, root, flags, region,
 	    for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling)
 	    {
 		/* Allocate a new node and copy the info. */
-		np = get_wordnode(blp);
+		np = get_wordnode(spin);
 		if (np == NULL)
 		    return FAIL;
 		np->wn_child = copyp->wn_child;
@@ -4808,7 +4868,7 @@ tree_add_word(word, root, flags, region,
 			|| node->wn_prefixID != prefixID)))
 	{
 	    /* Allocate a new node. */
-	    np = get_wordnode(blp);
+	    np = get_wordnode(spin);
 	    if (np == NULL)
 		return FAIL;
 	    np->wn_byte = word[i];
@@ -4844,85 +4904,124 @@ tree_add_word(word, root, flags, region,
     spell_print_tree(root->wn_sibling);
 #endif
 
+    /* count nr of words added since last message */
+    ++spin->si_msg_count;
+
     /*
      * Every so many words compress the tree, so that we don't use too much
      * memory.
      */
-    if (++words_added >= SPELL_COMPRESS_CNT)
-    {
-	words_added = 0;
-
-	msg_start();
-	msg_puts((char_u *)_(msg_compressing));
-	msg_clr_eos();
-	msg_didout = FALSE;
-	msg_col = 0;
-	out_flush();
-	wordtree_compress(root->wn_sibling, spin);
+    i = FALSE;
+    if (root == spin->si_foldroot)
+    {
+	if (++spin->si_fold_added >= SPELL_COMPRESS_CNT)
+	{
+	    i = TRUE;
+	    spin->si_fold_added = 0;
+	}
+    }
+    else if (root == spin->si_keeproot)
+    {
+	if (++spin->si_keep_added >= SPELL_COMPRESS_CNT)
+	{
+	    i = TRUE;
+	    spin->si_keep_added = 0;
+	}
+    }
+    if (i)
+    {
+	if (spin->si_verbose)
+	{
+	    msg_start();
+	    msg_puts((char_u *)_(msg_compressing));
+	    msg_clr_eos();
+	    msg_didout = FALSE;
+	    msg_col = 0;
+	    out_flush();
+	}
+	wordtree_compress(spin, root);
     }
 
     return OK;
 }
 
-/* We keep a list of nodes that have been freed during compression.  They are
- * re-used when adding a new node.  The "wn_child" fields links them. */
-static wordnode_T *first_free_node = NULL;
-#ifdef SPELL_PRINTTREE
-static int wordnode_nr = 0;
-#endif
-
 /*
  * Get a wordnode_T, either from the list of previously freed nodes or
  * allocate a new one.
  */
     static wordnode_T *
-get_wordnode(blp)
-    sblock_T	**blp;
+get_wordnode(spin)
+    spellinfo_T	    *spin;
 {
     wordnode_T *n;
 
-    if (first_free_node == NULL)
-	n = (wordnode_T *)getroom(blp, sizeof(wordnode_T), TRUE);
+    if (spin->si_first_free == NULL)
+	n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), TRUE);
     else
     {
-	n = first_free_node;
-	first_free_node = n->wn_child;
+	n = spin->si_first_free;
+	spin->si_first_free = n->wn_child;
 	vim_memset(n, 0, sizeof(wordnode_T));
     }
 #ifdef SPELL_PRINTTREE
-    n->wn_nr = ++wordnode_nr;
+    n->wn_nr = ++spin->si_wordnode_nr;
 #endif
     return n;
 }
 
 /*
+ * Decrement the reference count on a node (which is the head of a list of
+ * siblings).  If the reference count becomes zero free the node and its
+ * siblings.
+ */
+    static void
+deref_wordnode(spin, node)
+    spellinfo_T *spin;
+    wordnode_T  *node;
+{
+    wordnode_T *np;
+
+    if (--node->wn_refs == 0)
+	for (np = node; np != NULL; np = np->wn_sibling)
+	{
+	    if (np->wn_child != NULL)
+		deref_wordnode(spin, np->wn_child);
+	    free_wordnode(spin, np);
+	}
+}
+
+/*
  * Free a wordnode_T for re-use later.
+ * Only the "wn_child" field becomes invalid.
  */
     static void
-free_wordnode(n)
-    wordnode_T *n;
-{
-    n->wn_child = first_free_node;
-    first_free_node = n;
+free_wordnode(spin, n)
+    spellinfo_T	*spin;
+    wordnode_T  *n;
+{
+    n->wn_child = spin->si_first_free;
+    spin->si_first_free = n;
 }
 
 /*
  * Compress a tree: find tails that are identical and can be shared.
  */
     static void
-wordtree_compress(root, spin)
+wordtree_compress(spin, root)
+    spellinfo_T	    *spin;
     wordnode_T	    *root;
-    spellinfo_T	    *spin;
 {
     hashtab_T	    ht;
     int		    n;
     int		    tot = 0;
     int		    perc;
 
-    if (root != NULL)
+    /* Skip the root itself, it's not actually used.  The first sibling is the
+     * start of the tree. */
+    if (root->wn_sibling != NULL)
     {
 	hash_init(&ht);
-	n = node_compress(root, &ht, &tot);
+	n = node_compress(spin, root->wn_sibling, &ht, &tot);
 
 #ifndef SPELL_PRINTTREE
 	if (spin->si_verbose || p_verbose > 2)
@@ -4940,7 +5039,7 @@ wordtree_compress(root, spin)
 		verbose_leave();
 	}
 #ifdef SPELL_PRINTTREE
-	spell_print_tree(root);
+	spell_print_tree(root->wn_sibling);
 #endif
 	hash_clear(&ht);
     }
@@ -4951,7 +5050,8 @@ wordtree_compress(root, spin)
  * Returns the number of compressed nodes.
  */
     static int
-node_compress(node, ht, tot)
+node_compress(spin, node, ht, tot)
+    spellinfo_T	*spin;
     wordnode_T	*node;
     hashtab_T	*ht;
     int		*tot;	    /* total count of nodes before compressing,
@@ -4978,7 +5078,7 @@ node_compress(node, ht, tot)
 	if ((child = np->wn_child) != NULL)
 	{
 	    /* Compress the child.  This fills hashkey. */
-	    compressed += node_compress(child, ht, tot);
+	    compressed += node_compress(spin, child, ht, tot);
 
 	    /* Try to find an identical child. */
 	    hash = hash_hash(child->wn_u1.hashkey);
@@ -4995,14 +5095,7 @@ node_compress(node, ht, tot)
 			 * current one.  This means the current child and all
 			 * its siblings is unlinked from the tree. */
 			++tp->wn_refs;
-			--child->wn_refs;
-			if (child->wn_refs == 0)
-			    for (; child != NULL; child = child->wn_sibling)
-			    {
-				if (child->wn_child != NULL)
-				    --child->wn_child->wn_refs;
-				free_wordnode(child);
-			    }
+			deref_wordnode(spin, child);
 			np->wn_child = tp;
 			++compressed;
 			break;
@@ -5123,9 +5216,9 @@ rep_compare(s1, s2)
  * Write the Vim spell file "fname".
  */
     static void
-write_vim_spell(fname, spin)
+write_vim_spell(spin, fname)
+    spellinfo_T	*spin;
     char_u	*fname;
-    spellinfo_T	*spin;
 {
     FILE	*fd;
     int		regionmask;
@@ -5523,11 +5616,6 @@ mkspell(fcount, fnames, ascii, overwrite
     ga_init2(&spin.si_sal, (int)sizeof(fromto_T), 20);
     ga_init2(&spin.si_map, (int)sizeof(char_u), 100);
     ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50);
-    first_free_node = NULL;
-#ifdef SPELL_PRINTTREE
-    wordnode_nr = 0;
-#endif
-    words_added = 0;
 
     /* default: fnames[0] is output file, following are input files */
     innames = &fnames[1];
@@ -5616,9 +5704,9 @@ mkspell(fcount, fnames, ascii, overwrite
 	}
 	spin.si_region_count = incount;
 
-	spin.si_foldroot = wordtree_alloc(&spin.si_blocks);
-	spin.si_keeproot = wordtree_alloc(&spin.si_blocks);
-	spin.si_prefroot = wordtree_alloc(&spin.si_blocks);
+	spin.si_foldroot = wordtree_alloc(&spin);
+	spin.si_keeproot = wordtree_alloc(&spin);
+	spin.si_prefroot = wordtree_alloc(&spin);
 	if (spin.si_foldroot == NULL
 		|| spin.si_keeproot == NULL
 		|| spin.si_prefroot == NULL)
@@ -5650,7 +5738,7 @@ mkspell(fcount, fnames, ascii, overwrite
 	    {
 		/* Read the .aff file.  Will init "spin->si_conv" based on the
 		 * "SET" line. */
-		afile[i] = spell_read_aff(fname, &spin);
+		afile[i] = spell_read_aff(&spin, fname);
 		if (afile[i] == NULL)
 		    error = TRUE;
 		else
@@ -5658,7 +5746,7 @@ mkspell(fcount, fnames, ascii, overwrite
 		    /* Read the .dic file and store the words in the trees. */
 		    vim_snprintf((char *)fname, sizeof(fname), "%s.dic",
 								  innames[i]);
-		    if (spell_read_dic(fname, &spin, afile[i]) == FAIL)
+		    if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
 			error = TRUE;
 		}
 	    }
@@ -5666,7 +5754,7 @@ mkspell(fcount, fnames, ascii, overwrite
 	    {
 		/* No .aff file, try reading the file as a word list.  Store
 		 * the words in the trees. */
-		if (spell_read_wordfile(innames[i], &spin) == FAIL)
+		if (spell_read_wordfile(&spin, innames[i]) == FAIL)
 		    error = TRUE;
 	    }
 
@@ -5681,18 +5769,18 @@ mkspell(fcount, fnames, ascii, overwrite
 	    /*
 	     * Combine tails in the tree.
 	     */
-	    if (!added_word || p_verbose > 2)
-	    {
-		if (added_word)
+	    if (spin.si_verbose || p_verbose > 2)
+	    {
+		if (!spin.si_verbose)
 		    verbose_enter();
 		MSG(_(msg_compressing));
 		out_flush();
-		if (added_word)
+		if (!spin.si_verbose)
 		    verbose_leave();
 	    }
-	    wordtree_compress(spin.si_foldroot->wn_sibling, &spin);
-	    wordtree_compress(spin.si_keeproot->wn_sibling, &spin);
-	    wordtree_compress(spin.si_prefroot->wn_sibling, &spin);
+	    wordtree_compress(&spin, spin.si_foldroot);
+	    wordtree_compress(&spin, spin.si_keeproot);
+	    wordtree_compress(&spin, spin.si_prefroot);
 	}
 
 	if (!error)
@@ -5700,27 +5788,27 @@ mkspell(fcount, fnames, ascii, overwrite
 	    /*
 	     * Write the info in the spell file.
 	     */
-	    if (!added_word || p_verbose > 2)
-	    {
-		if (added_word)
+	    if (spin.si_verbose || p_verbose > 2)
+	    {
+		if (!spin.si_verbose)
 		    verbose_enter();
 		smsg((char_u *)_("Writing spell file %s ..."), wfname);
 		out_flush();
-		if (added_word)
+		if (!spin.si_verbose)
 		    verbose_leave();
 	    }
 
-	    write_vim_spell(wfname, &spin);
-
-	    if (!added_word || p_verbose > 2)
-	    {
-		if (added_word)
+	    write_vim_spell(&spin, wfname);
+
+	    if (spin.si_verbose || p_verbose > 2)
+	    {
+		if (!spin.si_verbose)
 		    verbose_enter();
 		MSG(_("Done!"));
 		smsg((char_u *)_("Estimated runtime memory use: %d bytes"),
 							      spin.si_memtot);
 		out_flush();
-		if (added_word)
+		if (!spin.si_verbose)
 		    verbose_leave();
 	    }
 
@@ -6393,7 +6481,7 @@ spell_casefold(str, len, buf, buflen)
 		buf[outi] = NUL;
 		return FAIL;
 	    }
-	    c = mb_ptr2char_adv(&p);
+	    c = mb_cptr2char_adv(&p);
 	    outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
 	}
 	buf[outi] = NUL;
@@ -6580,11 +6668,27 @@ spell_suggest()
 	vim_free(repl_to);
 	repl_to = NULL;
 
+#ifdef FEAT_RIGHTLEFT
+	/* When 'rightleft' is set the list is drawn right-left. */
+	cmdmsg_rl = curwin->w_p_rl;
+	if (cmdmsg_rl)
+	    msg_col = Columns - 1;
+#endif
+
 	/* List the suggestions. */
 	msg_start();
 	lines_left = Rows;	/* avoid more prompt */
 	vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
 						sug.su_badlen, sug.su_badptr);
+#ifdef FEAT_RIGHTLEFT
+	if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0)
+	{
+	    /* And now the rabbit from the high hat: Avoid showing the
+	     * untranslated message rightleft. */
+	    vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
+						sug.su_badlen, sug.su_badptr);
+	}
+#endif
 	msg_puts(IObuff);
 	msg_clr_eos();
 	msg_putchar('\n');
@@ -6601,7 +6705,14 @@ spell_suggest()
 		vim_strncpy(wcopy + STRLEN(wcopy),
 					       sug.su_badptr + stp->st_orglen,
 					      sug.su_badlen - stp->st_orglen);
-	    vim_snprintf((char *)IObuff, IOSIZE, _("%2d \"%s\""), i + 1, wcopy);
+	    vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
+#ifdef FEAT_RIGHTLEFT
+	    if (cmdmsg_rl)
+		rl_mirror(IObuff);
+#endif
+	    msg_puts(IObuff);
+
+	    vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy);
 	    msg_puts(IObuff);
 
 	    /* The word may replace more than "su_badlen". */
@@ -6616,18 +6727,27 @@ spell_suggest()
 	    {
 		/* Add the score. */
 		if (sps_flags & (SPS_DOUBLE | SPS_BEST))
-		    vim_snprintf((char *)IObuff, IOSIZE, _(" (%s%d - %d)"),
+		    vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)",
 			stp->st_salscore ? "s " : "",
 			stp->st_score, stp->st_altscore);
 		else
-		    vim_snprintf((char *)IObuff, IOSIZE, _(" (%d)"),
+		    vim_snprintf((char *)IObuff, IOSIZE, " (%d)",
 			    stp->st_score);
+#ifdef FEAT_RIGHTLEFT
+		if (cmdmsg_rl)
+		    /* Mirror the numbers, but keep the leading space. */
+		    rl_mirror(IObuff + 1);
+#endif
 		msg_advance(30);
 		msg_puts(IObuff);
 	    }
 	    msg_putchar('\n');
 	}
 
+#ifdef FEAT_RIGHTLEFT
+	cmdmsg_rl = FALSE;
+	msg_col = 0;
+#endif
 	/* Ask for choice. */
 	i = prompt_for_number(&mouse_used);
 	if (mouse_used)
@@ -6815,7 +6935,8 @@ spell_find_suggest(badptr, su, maxcount,
     (void)spell_casefold(su->su_badptr, su->su_badlen,
 						    su->su_fbadword, MAXWLEN);
     /* get caps flags for bad word */
-    su->su_badflags = captype(su->su_badptr, su->su_badptr + su->su_badlen);
+    su->su_badflags = badword_captype(su->su_badptr,
+					       su->su_badptr + su->su_badlen);
     if (need_cap)
 	su->su_badflags |= WF_ONECAP;
 
@@ -6916,7 +7037,7 @@ spell_suggest_expr(su, expr)
 #endif
 
 /*
- * Find suggestions a file "fname".
+ * Find suggestions in file "fname".  Used for "file:" in 'spellsuggest'.
  */
     static void
 spell_suggest_file(su, fname)
@@ -7070,7 +7191,7 @@ onecap_copy(word, wcopy, upper)
     p = word;
 #ifdef FEAT_MBYTE
     if (has_mbyte)
-	c = mb_ptr2char_adv(&p);
+	c = mb_cptr2char_adv(&p);
     else
 #endif
 	c = *p++;
@@ -7108,7 +7229,7 @@ allcap_copy(word, wcopy)
     {
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    c = mb_ptr2char_adv(&s);
+	    c = mb_cptr2char_adv(&s);
 	else
 #endif
 	    c = *s++;
@@ -7298,10 +7419,10 @@ suggest_try_change(su)
 			else
 #endif
 			    n = sp->ts_fidx;
-			flags = captype(su->su_badptr, su->su_badptr + n);
-			su->su_badflags = captype(su->su_badptr + n,
+			flags = badword_captype(su->su_badptr,
+							   su->su_badptr + n);
+			su->su_badflags = badword_captype(su->su_badptr + n,
 					       su->su_badptr + su->su_badlen);
-
 			++depth;
 			stack[depth] = stack[depth - 1];
 			sp = &stack[depth];
@@ -7380,7 +7501,7 @@ suggest_try_change(su)
 		    c = su->su_badflags;
 		    if ((c & WF_ALLCAP)
 #ifdef FEAT_MBYTE
-			    && su->su_badlen == mb_ptr2len_check(su->su_badptr)
+			    && su->su_badlen == (*mb_ptr2len)(su->su_badptr)
 #else
 			    && su->su_badlen == 1
 #endif
@@ -7492,7 +7613,7 @@ suggest_try_change(su)
 			else
 #endif
 			    n = sp->ts_fidx;
-			su->su_badflags = captype(su->su_badptr + n,
+			su->su_badflags = badword_captype(su->su_badptr + n,
 					       su->su_badptr + su->su_badlen);
 
 			/* Restart at top of the tree. */
@@ -7751,7 +7872,7 @@ suggest_try_change(su)
 #ifdef FEAT_MBYTE
 		if (has_mbyte)
 		{
-		    n = mb_ptr2len_check(p);
+		    n = mb_cptr2len(p);
 		    c = mb_ptr2char(p);
 		    c2 = mb_ptr2char(p + n);
 		}
@@ -7816,9 +7937,9 @@ suggest_try_change(su)
 #ifdef FEAT_MBYTE
 		if (has_mbyte)
 		{
-		    n = mb_ptr2len_check(p);
+		    n = mb_cptr2len(p);
 		    c = mb_ptr2char(p);
-		    fl = mb_ptr2len_check(p + n);
+		    fl = mb_cptr2len(p + n);
 		    c2 = mb_ptr2char(p + n);
 		    c3 = mb_ptr2char(p + n + fl);
 		}
@@ -7897,10 +8018,10 @@ suggest_try_change(su)
 #ifdef FEAT_MBYTE
 		    if (has_mbyte)
 		    {
-			n = mb_ptr2len_check(p);
+			n = mb_cptr2len(p);
 			c = mb_ptr2char(p);
-			fl = mb_ptr2len_check(p + n);
-			fl += mb_ptr2len_check(p + n + fl);
+			fl = mb_cptr2len(p + n);
+			fl += mb_cptr2len(p + n + fl);
 			mch_memmove(p, p + n, fl);
 			mb_char2bytes(c, p + fl);
 			stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
@@ -7951,10 +8072,10 @@ suggest_try_change(su)
 #ifdef FEAT_MBYTE
 		    if (has_mbyte)
 		    {
-			n = mb_ptr2len_check(p);
-			n += mb_ptr2len_check(p + n);
+			n = mb_cptr2len(p);
+			n += mb_cptr2len(p + n);
 			c = mb_ptr2char(p + n);
-			tl = mb_ptr2len_check(p + n);
+			tl = mb_cptr2len(p + n);
 			mch_memmove(p + tl, p, n);
 			mb_char2bytes(c, p);
 			stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
@@ -8230,8 +8351,8 @@ find_keepcap_word(slang, fword, kword)
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
 	    {
-		flen = mb_ptr2len_check(fword + fwordidx[depth]);
-		ulen = mb_ptr2len_check(uword + uwordidx[depth]);
+		flen = mb_cptr2len(fword + fwordidx[depth]);
+		ulen = mb_cptr2len(uword + uwordidx[depth]);
 	    }
 	    else
 #endif
@@ -8703,7 +8824,7 @@ set_map_str(lp, map)
     for (p = map; *p != NUL; )
     {
 #ifdef FEAT_MBYTE
-	c = mb_ptr2char_adv(&p);
+	c = mb_cptr2char_adv(&p);
 #else
 	c = *p++;
 #endif
@@ -9138,7 +9259,7 @@ spell_soundfold_sofo(slang, inword, res)
 	 * 255, sl_sal the rest. */
 	for (s = inword; *s != NUL; )
 	{
-	    c = mb_ptr2char_adv(&s);
+	    c = mb_cptr2char_adv(&s);
 	    if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c))
 		c = ' ';
 	    else if (c < 256)
@@ -9510,7 +9631,7 @@ spell_soundfold_wsal(slang, inword, res)
     for (s = inword; *s != NUL; )
     {
 	t = s;
-	c = mb_ptr2char_adv(&s);
+	c = mb_cptr2char_adv(&s);
 	if (slang->sl_rem_accents)
 	{
 	    if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c))
@@ -10026,10 +10147,10 @@ spell_edit_score(badword, goodword)
 	/* Get the characters from the multi-byte strings and put them in an
 	 * int array for easy access. */
 	for (p = badword, badlen = 0; *p != NUL; )
-	    wbadword[badlen++] = mb_ptr2char_adv(&p);
+	    wbadword[badlen++] = mb_cptr2char_adv(&p);
 	wbadword[badlen++] = 0;
 	for (p = goodword, goodlen = 0; *p != NUL; )
-	    wgoodword[goodlen++] = mb_ptr2char_adv(&p);
+	    wgoodword[goodlen++] = mb_cptr2char_adv(&p);
 	wgoodword[goodlen++] = 0;
     }
     else
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -3064,7 +3064,7 @@ check_keyword_id(line, startcol, endcolp
     {
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    kwlen += (*mb_ptr2len_check)(kwp + kwlen);
+	    kwlen += (*mb_ptr2len)(kwp + kwlen);
 	else
 #endif
 	    ++kwlen;
@@ -4519,7 +4519,7 @@ syn_cmd_keyword(eap, syncing)
 #ifdef FEAT_MBYTE
 			if (has_mbyte)
 			{
-			    int l = (*mb_ptr2len_check)(p + 1);
+			    int l = (*mb_ptr2len)(p + 1);
 
 			    mch_memmove(p, p + 1, l);
 			    p += l;
--- a/src/term.c
+++ b/src/term.c
@@ -5066,7 +5066,7 @@ replace_termcodes(from, bufp, from_part,
 
 #ifdef FEAT_MBYTE
 	/* skip multibyte char correctly */
-	for (i = (*mb_ptr2len_check)(src); i > 0; --i)
+	for (i = (*mb_ptr2len)(src); i > 0; --i)
 #endif
 	{
 	    /*
--- a/src/ui.c
+++ b/src/ui.c
@@ -432,7 +432,7 @@ clip_update_selection()
 	    end = curwin->w_cursor;
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
-		end.col += (*mb_ptr2len_check)(ml_get_cursor()) - 1;
+		end.col += (*mb_ptr2len)(ml_get_cursor()) - 1;
 #endif
 	}
 	else
--- a/src/version.c
+++ b/src/version.c
@@ -1203,7 +1203,7 @@ do_intro_line(row, mesg, add_version, at
 	    if (has_mbyte)
 	    {
 		clen += ptr2cells(p + l);
-		l += (*mb_ptr2len_check)(p + l) - 1;
+		l += (*mb_ptr2len)(p + l) - 1;
 	    }
 	    else
 #endif
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 9)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 9, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 10)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 10, compiled "
--- a/src/window.c
+++ b/src/window.c
@@ -4611,7 +4611,7 @@ file_name_in_line(line, col, options, co
 			 || ((options & FNAME_HYP) && path_is_url(ptr + len)))
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
-	    len += (*mb_ptr2len_check)(ptr + len);
+	    len += (*mb_ptr2len)(ptr + len);
 	else
 #endif
 	    ++len;