mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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)
This commit is contained in:
parent
8509014add
commit
47eec6716b
@ -8934,7 +8934,6 @@ f_screenchar(typval_T *argvars, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
int row;
|
int row;
|
||||||
int col;
|
int col;
|
||||||
int off;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (in_vim9script()
|
if (in_vim9script()
|
||||||
@ -8948,11 +8947,9 @@ f_screenchar(typval_T *argvars, typval_T *rettv)
|
|||||||
c = -1;
|
c = -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
off = LineOffset[row] + col;
|
char_u buf[MB_MAXBYTES + 1];
|
||||||
if (enc_utf8 && ScreenLinesUC[off] != 0)
|
screen_getbytes(row, col, buf, NULL);
|
||||||
c = ScreenLinesUC[off];
|
c = (*mb_ptr2char)(buf);
|
||||||
else
|
|
||||||
c = ScreenLines[off];
|
|
||||||
}
|
}
|
||||||
rettv->vval.v_number = c;
|
rettv->vval.v_number = c;
|
||||||
}
|
}
|
||||||
@ -8965,7 +8962,6 @@ f_screenchars(typval_T *argvars, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
int row;
|
int row;
|
||||||
int col;
|
int col;
|
||||||
int off;
|
|
||||||
int c;
|
int c;
|
||||||
int i;
|
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)
|
if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
off = LineOffset[row] + col;
|
char_u buf[MB_MAXBYTES + 1];
|
||||||
if (enc_utf8 && ScreenLinesUC[off] != 0)
|
screen_getbytes(row, col, buf, NULL);
|
||||||
c = ScreenLinesUC[off];
|
int pcc[MAX_MCO];
|
||||||
|
if (enc_utf8)
|
||||||
|
c = utfc_ptr2char(buf, pcc);
|
||||||
else
|
else
|
||||||
c = ScreenLines[off];
|
c = (*mb_ptr2char)(buf);
|
||||||
list_append_number(rettv->vval.v_list, (varnumber_T)c);
|
list_append_number(rettv->vval.v_list, (varnumber_T)c);
|
||||||
|
|
||||||
if (enc_utf8)
|
if (enc_utf8)
|
||||||
|
for (i = 0; i < Screen_mco && pcc[i] != 0; ++i)
|
||||||
for (i = 0; i < Screen_mco && ScreenLinesC[i][off] != 0; ++i)
|
list_append_number(rettv->vval.v_list, (varnumber_T)pcc[i]);
|
||||||
list_append_number(rettv->vval.v_list,
|
|
||||||
(varnumber_T)ScreenLinesC[i][off]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -9024,11 +9020,7 @@ f_screenstring(typval_T *argvars, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
int row;
|
int row;
|
||||||
int col;
|
int col;
|
||||||
int off;
|
|
||||||
int c;
|
|
||||||
int i;
|
|
||||||
char_u buf[MB_MAXBYTES + 1];
|
char_u buf[MB_MAXBYTES + 1];
|
||||||
int buflen = 0;
|
|
||||||
|
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
rettv->v_type = VAR_STRING;
|
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)
|
if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
off = LineOffset[row] + col;
|
screen_getbytes(row, col, buf, NULL);
|
||||||
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;
|
|
||||||
rettv->vval.v_string = vim_strsave(buf);
|
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.
|
* 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.
|
* Otherwise use the column number as a byte offset.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -1199,8 +1199,9 @@ screen_putchar(int c, int row, int col, int attr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a single character directly from ScreenLines into "bytes[]".
|
* Get a single character directly from ScreenLines into "bytes", which must
|
||||||
* Also return its attribute in *attrp;
|
* have a size of "MB_MAXBYTES + 1".
|
||||||
|
* If "attrp" is not NULL, return the character's attribute in "*attrp".
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
screen_getbytes(int row, int col, char_u *bytes, int *attrp)
|
screen_getbytes(int row, int col, char_u *bytes, int *attrp)
|
||||||
@ -1212,7 +1213,8 @@ screen_getbytes(int row, int col, char_u *bytes, int *attrp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
off = LineOffset[row] + col;
|
off = LineOffset[row] + col;
|
||||||
*attrp = ScreenAttrs[off];
|
if (attrp != NULL)
|
||||||
|
*attrp = ScreenAttrs[off];
|
||||||
bytes[0] = ScreenLines[off];
|
bytes[0] = ScreenLines[off];
|
||||||
bytes[1] = NUL;
|
bytes[1] = NUL;
|
||||||
|
|
||||||
|
@ -3217,6 +3217,31 @@ func Test_screen_functions()
|
|||||||
call assert_equal(-1, screenattr(-1, -1))
|
call assert_equal(-1, screenattr(-1, -1))
|
||||||
call assert_equal(-1, screenchar(-1, -1))
|
call assert_equal(-1, screenchar(-1, -1))
|
||||||
call assert_equal([], screenchars(-1, -1))
|
call assert_equal([], screenchars(-1, -1))
|
||||||
|
|
||||||
|
" Run this in a separate Vim instance to avoid messing up.
|
||||||
|
let after =<< trim [CODE]
|
||||||
|
scriptencoding utf-8
|
||||||
|
call setline(1, '口')
|
||||||
|
redraw
|
||||||
|
call assert_equal(0, screenattr(1, 1))
|
||||||
|
call assert_equal(char2nr('口'), screenchar(1, 1))
|
||||||
|
call assert_equal([char2nr('口')], screenchars(1, 1))
|
||||||
|
call assert_equal('口', screenstring(1, 1))
|
||||||
|
call writefile(v:errors, 'Xresult')
|
||||||
|
qall!
|
||||||
|
[CODE]
|
||||||
|
|
||||||
|
let encodings = ['utf-8', 'cp932', 'cp936', 'cp949', 'cp950']
|
||||||
|
if !has('win32')
|
||||||
|
let encodings += ['euc-jp']
|
||||||
|
endif
|
||||||
|
for enc in encodings
|
||||||
|
let msg = 'enc=' .. enc
|
||||||
|
if RunVim([], after, $'--clean --cmd "set encoding={enc}"')
|
||||||
|
call assert_equal([], readfile('Xresult'), msg)
|
||||||
|
endif
|
||||||
|
call delete('Xresult')
|
||||||
|
endfor
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Test for getcurpos() and setpos()
|
" Test for getcurpos() and setpos()
|
||||||
|
@ -135,6 +135,19 @@ func Test_screenchar_utf8()
|
|||||||
call assert_equal("B", screenstring(1, 2))
|
call assert_equal("B", screenstring(1, 2))
|
||||||
call assert_equal("C\u0308", screenstring(1, 3))
|
call assert_equal("C\u0308", screenstring(1, 3))
|
||||||
|
|
||||||
|
" 1-cell, with 6 composing characters
|
||||||
|
set maxcombine=6
|
||||||
|
call setline(1, ["ABC" .. repeat("\u0308", 6)])
|
||||||
|
redraw
|
||||||
|
call assert_equal([0x0041], screenchars(1, 1))
|
||||||
|
call assert_equal([0x0042], 1->screenchars(2))
|
||||||
|
" This should not use uninitialized memory
|
||||||
|
call assert_equal([0x0043] + repeat([0x0308], 6), screenchars(1, 3))
|
||||||
|
call assert_equal("A", screenstring(1, 1))
|
||||||
|
call assert_equal("B", screenstring(1, 2))
|
||||||
|
call assert_equal("C" .. repeat("\u0308", 6), screenstring(1, 3))
|
||||||
|
set maxcombine&
|
||||||
|
|
||||||
" 2-cells, with composing characters
|
" 2-cells, with composing characters
|
||||||
let text = "\u3042\u3044\u3046\u3099"
|
let text = "\u3042\u3044\u3046\u3099"
|
||||||
call setline(1, text)
|
call setline(1, text)
|
||||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1598,
|
||||||
/**/
|
/**/
|
||||||
1597,
|
1597,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user