diff src/evalfunc.c @ 32533:aa64fdad1f60 v9.0.1598

patch 9.0.1598: screenchar() and others are wrong with DBCS 'encoding' Commit: https://github.com/vim/vim/commit/47eec6716b8621fd43bac8ecc9c19089df26705e Author: zeertzjq <zeertzjq@outlook.com> Date: Thu Jun 1 20:26:55 2023 +0100 patch 9.0.1598: screenchar() and others are wrong with DBCS 'encoding' Problem: screenchar(), screenchars() and screenstring() do not work properly when 'encoding' is set to a double-byte encoding. Solution: Fix the way the bytes of the characters are obtained. (issue #12469)
author Bram Moolenaar <Bram@vim.org>
date Thu, 01 Jun 2023 21:30:03 +0200
parents 3c2c1cb61004
children 5d8cff99a027
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -8934,7 +8934,6 @@ f_screenchar(typval_T *argvars, typval_T
 {
     int		row;
     int		col;
-    int		off;
     int		c;
 
     if (in_vim9script()
@@ -8948,11 +8947,9 @@ f_screenchar(typval_T *argvars, typval_T
 	c = -1;
     else
     {
-	off = LineOffset[row] + col;
-	if (enc_utf8 && ScreenLinesUC[off] != 0)
-	    c = ScreenLinesUC[off];
-	else
-	    c = ScreenLines[off];
+	char_u buf[MB_MAXBYTES + 1];
+	screen_getbytes(row, col, buf, NULL);
+	c = (*mb_ptr2char)(buf);
     }
     rettv->vval.v_number = c;
 }
@@ -8965,7 +8962,6 @@ f_screenchars(typval_T *argvars, typval_
 {
     int		row;
     int		col;
-    int		off;
     int		c;
     int		i;
 
@@ -8982,18 +8978,18 @@ f_screenchars(typval_T *argvars, typval_
     if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
 	return;
 
-    off = LineOffset[row] + col;
-    if (enc_utf8 && ScreenLinesUC[off] != 0)
-	c = ScreenLinesUC[off];
+    char_u buf[MB_MAXBYTES + 1];
+    screen_getbytes(row, col, buf, NULL);
+    int pcc[MAX_MCO];
+    if (enc_utf8)
+	c = utfc_ptr2char(buf, pcc);
     else
-	c = ScreenLines[off];
+	c = (*mb_ptr2char)(buf);
     list_append_number(rettv->vval.v_list, (varnumber_T)c);
 
     if (enc_utf8)
-
-	for (i = 0; i < Screen_mco && ScreenLinesC[i][off] != 0; ++i)
-	    list_append_number(rettv->vval.v_list,
-				       (varnumber_T)ScreenLinesC[i][off]);
+	for (i = 0; i < Screen_mco && pcc[i] != 0; ++i)
+	    list_append_number(rettv->vval.v_list, (varnumber_T)pcc[i]);
 }
 
 /*
@@ -9024,11 +9020,7 @@ f_screenstring(typval_T *argvars, typval
 {
     int		row;
     int		col;
-    int		off;
-    int		c;
-    int		i;
     char_u	buf[MB_MAXBYTES + 1];
-    int		buflen = 0;
 
     rettv->vval.v_string = NULL;
     rettv->v_type = VAR_STRING;
@@ -9043,18 +9035,7 @@ f_screenstring(typval_T *argvars, typval
     if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
 	return;
 
-    off = LineOffset[row] + col;
-    if (enc_utf8 && ScreenLinesUC[off] != 0)
-	c = ScreenLinesUC[off];
-    else
-	c = ScreenLines[off];
-    buflen += mb_char2bytes(c, buf);
-
-    if (enc_utf8 && ScreenLinesUC[off] != 0)
-	for (i = 0; i < Screen_mco && ScreenLinesC[i][off] != 0; ++i)
-	    buflen += mb_char2bytes(ScreenLinesC[i][off], buf + buflen);
-
-    buf[buflen] = NUL;
+    screen_getbytes(row, col, buf, NULL);
     rettv->vval.v_string = vim_strsave(buf);
 }
 
@@ -9433,7 +9414,7 @@ f_searchpos(typval_T *argvars, typval_T 
 
 /*
  * Set the cursor or mark position.
- * If 'charpos' is TRUE, then use the column number as a character offset.
+ * If "charpos" is TRUE, then use the column number as a character offset.
  * Otherwise use the column number as a byte offset.
  */
     static void