changeset 31782:a19ef442c77a v9.0.1223

patch 9.0.1223: cannot use setcellwidths() below 0x100 Commit: https://github.com/vim/vim/commit/7193323b7796c05573f3aa89d422e848feb3a8dc Author: K.Takata <kentkt@csc.jp> Date: Fri Jan 20 16:00:55 2023 +0000 patch 9.0.1223: cannot use setcellwidths() below 0x100 Problem: Cannot use setcellwidths() below 0x100. Solution: Also accept characters between 0x80 and 0x100. (Ken Takata, closes #11834)
author Bram Moolenaar <Bram@vim.org>
date Fri, 20 Jan 2023 21:01:44 +0100
parents 3237c4baee03
children cdee4ac5eea0
files runtime/doc/builtin.txt src/errors.h src/mbyte.c src/testdir/test_utf8.vim src/version.c
diffstat 5 files changed, 57 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -7966,7 +7966,7 @@ setcellwidths({list})					*setcellwidths
 		{low} and {high} can be the same, in which case this refers to
 		one character.  Otherwise it is the range of characters from
 		{low} to {high} (inclusive).		*E1111* *E1114*
-		Only characters with value 0x100 and higher can be used.
+		Only characters with value 0x80 and higher can be used.
 
 		{width} must be either 1 or 2, indicating the character width
 		in screen cells.			*E1112*
--- a/src/errors.h
+++ b/src/errors.h
@@ -2841,8 +2841,8 @@ EXTERN char e_list_item_nr_cell_width_in
 	INIT(= N_("E1112: List item %d cell width invalid"));
 EXTERN char e_overlapping_ranges_for_nr[]
 	INIT(= N_("E1113: Overlapping ranges for 0x%lx"));
-EXTERN char e_only_values_of_0x100_and_higher_supported[]
-	INIT(= N_("E1114: Only values of 0x100 and higher supported"));
+EXTERN char e_only_values_of_0x80_and_higher_supported[]
+	INIT(= N_("E1114: Only values of 0x80 and higher supported"));
 EXTERN char e_assert_fails_fourth_argument[]
 	INIT(= N_("E1115: \"assert_fails()\" fourth argument must be a number"));
 EXTERN char e_assert_fails_fifth_argument[]
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -1589,19 +1589,26 @@ utf_char2cells(int c)
 #endif
     };
 
+#ifdef FEAT_EVAL
+    // Use the value from setcellwidths() at 0x80 and higher, unless the
+    // character is not printable.
+    if (c >= 0x80 &&
+# ifdef USE_WCHAR_FUNCTIONS
+	    wcwidth(c) >= 1 &&
+# endif
+	    vim_isprintc(c))
+    {
+	int n = cw_value(c);
+	if (n != 0)
+	    return n;
+    }
+#endif
+
     if (c >= 0x100)
     {
-#if defined(FEAT_EVAL) || defined(USE_WCHAR_FUNCTIONS)
+#ifdef USE_WCHAR_FUNCTIONS
 	int	n;
-#endif
-
-#ifdef FEAT_EVAL
-	n = cw_value(c);
-	if (n != 0)
-	    return n;
-#endif
-
-#ifdef USE_WCHAR_FUNCTIONS
+
 	/*
 	 * Assume the library function wcwidth() works better than our own
 	 * stuff.  It should return 1 for ambiguous width chars!
@@ -5661,9 +5668,9 @@ f_setcellwidths(typval_T *argvars, typva
 	    if (i == 0)
 	    {
 		n1 = lili->li_tv.vval.v_number;
-		if (n1 < 0x100)
+		if (n1 < 0x80)
 		{
-		    emsg(_(e_only_values_of_0x100_and_higher_supported));
+		    emsg(_(e_only_values_of_0x80_and_higher_supported));
 		    vim_free(ptrs);
 		    return;
 		}
--- a/src/testdir/test_utf8.vim
+++ b/src/testdir/test_utf8.vim
@@ -167,6 +167,39 @@ func Test_setcellwidths()
   call assert_equal(2, strwidth("\u1339"))
   call assert_equal(1, strwidth("\u133a"))
 
+  for aw in ['single', 'double']
+    exe 'set ambiwidth=' . aw
+    " Handle \u0080 to \u009F as control chars even on MS-Windows.
+    set isprint=@,161-255
+
+    call setcellwidths([])
+    " Control chars
+    call assert_equal(4, strwidth("\u0081"))
+    call assert_equal(6, strwidth("\uFEFF"))
+    " Ambiguous width chars
+    call assert_equal((aw == 'single') ? 1 : 2, strwidth("\u00A1"))
+    call assert_equal((aw == 'single') ? 1 : 2, strwidth("\u2010"))
+
+    call setcellwidths([[0x81, 0x81, 1], [0xA1, 0xA1, 1],
+                      \ [0x2010, 0x2010, 1], [0xFEFF, 0xFEFF, 1]])
+    " Control chars
+    call assert_equal(4, strwidth("\u0081"))
+    call assert_equal(6, strwidth("\uFEFF"))
+    " Ambiguous width chars
+    call assert_equal(1, strwidth("\u00A1"))
+    call assert_equal(1, strwidth("\u2010"))
+
+    call setcellwidths([[0x81, 0x81, 2], [0xA1, 0xA1, 2],
+                      \ [0x2010, 0x2010, 2], [0xFEFF, 0xFEFF, 2]])
+    " Control chars
+    call assert_equal(4, strwidth("\u0081"))
+    call assert_equal(6, strwidth("\uFEFF"))
+    " Ambiguous width chars
+    call assert_equal(2, strwidth("\u00A1"))
+    call assert_equal(2, strwidth("\u2010"))
+  endfor
+  set ambiwidth& isprint&
+
   call setcellwidths([])
 
   call assert_fails('call setcellwidths(1)', 'E1211:')
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1223,
+/**/
     1222,
 /**/
     1221,