From 47eec6716b8621fd43bac8ecc9c19089df26705e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 1 Jun 2023 20:26:55 +0100 Subject: 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) --- src/evalfunc.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) (limited to 'src/evalfunc.c') diff --git a/src/evalfunc.c b/src/evalfunc.c index 8f20ebee17..62e9a40624 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -8934,7 +8934,6 @@ f_screenchar(typval_T *argvars, typval_T *rettv) { int row; int col; - int off; int c; if (in_vim9script() @@ -8948,11 +8947,9 @@ f_screenchar(typval_T *argvars, typval_T *rettv) 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_T *rettv) { int row; int col; - int off; int c; int i; @@ -8982,18 +8978,18 @@ f_screenchars(typval_T *argvars, typval_T *rettv) 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_T *rettv) { 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_T *rettv) 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 *rettv) /* * 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 -- cgit v1.2.3