Skip to content

Commit 6daeef1

Browse files
committed
patch 8.0.1203: terminal window mistreats composing characters
Problem: Terminal window mistreats composing characters. Solution: Count composing characters with the base character. (Ozaki Kiichi, closes #2195)
1 parent 059db5c commit 6daeef1

4 files changed

Lines changed: 74 additions & 6 deletions

File tree

src/mbyte.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,8 @@ static struct interval ambiguous[] =
14021402
int
14031403
utf_uint2cells(UINT32_T c)
14041404
{
1405+
if (c >= 0x100 && utf_iscomposing((int)c))
1406+
return 0;
14051407
return utf_char2cells((int)c);
14061408
}
14071409
#endif

src/terminal.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,9 @@
4040
* TODO:
4141
* - in GUI vertical split causes problems. Cursor is flickering. (Hirohito
4242
* Higashi, 2017 Sep 19)
43-
* - patch to handle composing characters. (Ozaki Kiichi, #2195)
4443
* - double click in Window toolbar starts Visual mode (but not always?).
4544
* - Shift-Tab does not work.
4645
* - after resizing windows overlap. (Boris Staletic, #2164)
47-
* - :wall gives an error message. (Marius Gedminas, #2190)
48-
* patch suggested by Yasuhiro Matsumoto, Oct 10
4946
* - Redirecting output does not work on MS-Windows, Test_terminal_redir_file()
5047
* is disabled.
5148
* - cursor blinks in terminal on widows with a timer. (xtal8, #2142)
@@ -2299,7 +2296,6 @@ term_update_window(win_T *wp)
22992296
if (vterm_screen_get_cell(screen, pos, &cell) == 0)
23002297
vim_memset(&cell, 0, sizeof(cell));
23012298

2302-
/* TODO: composing chars */
23032299
c = cell.chars[0];
23042300
if (c == NUL)
23052301
{
@@ -2311,7 +2307,18 @@ term_update_window(win_T *wp)
23112307
{
23122308
if (enc_utf8)
23132309
{
2314-
if (c >= 0x80)
2310+
int i;
2311+
2312+
/* composing chars */
2313+
for (i = 0; i < Screen_mco
2314+
&& i + 1 < VTERM_MAX_CHARS_PER_CELL; ++i)
2315+
{
2316+
ScreenLinesC[i][off] = cell.chars[i + 1];
2317+
if (cell.chars[i + 1] == 0)
2318+
break;
2319+
}
2320+
if (c >= 0x80 || (Screen_mco > 0
2321+
&& ScreenLinesC[0][off] != 0))
23152322
{
23162323
ScreenLines[off] = ' ';
23172324
ScreenLinesUC[off] = c;
@@ -3157,7 +3164,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
31573164
while (*msg != NUL)
31583165
{
31593166
send_keys_to_term(term, PTR2CHAR(msg), FALSE);
3160-
msg += MB_PTR2LEN(msg);
3167+
msg += MB_CPTR2LEN(msg);
31613168
}
31623169
}
31633170

src/testdir/test_terminal.vim

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,3 +685,60 @@ func Test_terminal_wall()
685685
exe buf . 'bwipe'
686686
unlet g:job
687687
endfunc
688+
689+
func Test_terminal_composing_unicode()
690+
let save_enc = &encoding
691+
set encoding=utf-8
692+
693+
if has('win32')
694+
let cmd = "cmd /K chcp 65001"
695+
let lnum = [3, 6, 9]
696+
else
697+
let cmd = &shell
698+
let lnum = [1, 3, 5]
699+
endif
700+
701+
enew
702+
let buf = term_start(cmd, {'curwin': bufnr('')})
703+
let job = term_getjob(buf)
704+
call term_wait(buf, 50)
705+
706+
" ascii + composing
707+
let txt = "a\u0308bc"
708+
call term_sendkeys(buf, "echo " . txt . "\r")
709+
call term_wait(buf, 50)
710+
call assert_match("echo " . txt, term_getline(buf, lnum[0]))
711+
call assert_equal(txt, term_getline(buf, lnum[0] + 1))
712+
let l = term_scrape(buf, lnum[0] + 1)
713+
call assert_equal("a\u0308", l[0].chars)
714+
call assert_equal("b", l[1].chars)
715+
call assert_equal("c", l[2].chars)
716+
717+
" multibyte + composing
718+
let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099"
719+
call term_sendkeys(buf, "echo " . txt . "\r")
720+
call term_wait(buf, 50)
721+
call assert_match("echo " . txt, term_getline(buf, lnum[1]))
722+
call assert_equal(txt, term_getline(buf, lnum[1] + 1))
723+
let l = term_scrape(buf, lnum[1] + 1)
724+
call assert_equal("\u304b\u3099", l[0].chars)
725+
call assert_equal("\u304e", l[1].chars)
726+
call assert_equal("\u304f\u3099", l[2].chars)
727+
call assert_equal("\u3052", l[3].chars)
728+
call assert_equal("\u3053\u3099", l[4].chars)
729+
730+
" \u00a0 + composing
731+
let txt = "abc\u00a0\u0308"
732+
call term_sendkeys(buf, "echo " . txt . "\r")
733+
call term_wait(buf, 50)
734+
call assert_match("echo " . txt, term_getline(buf, lnum[2]))
735+
call assert_equal(txt, term_getline(buf, lnum[2] + 1))
736+
let l = term_scrape(buf, lnum[2] + 1)
737+
call assert_equal("\u00a0\u0308", l[3].chars)
738+
739+
call term_sendkeys(buf, "exit\r")
740+
call WaitFor('job_status(job) == "dead"')
741+
call assert_equal('dead', job_status(job))
742+
bwipe!
743+
let &encoding = save_enc
744+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1203,
764766
/**/
765767
1202,
766768
/**/

0 commit comments

Comments
 (0)