From: Ralf Schandl Date: Fri, 28 May 2021 12:12:14 +0000 (+0200) Subject: patch 8.2.2893: multi-byte text in popup title shows up wrong X-Git-Tag: v8.2.2893 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc869874fedf094129831836f131c64f10d98854;p=vim patch 8.2.2893: multi-byte text in popup title shows up wrong Problem: Multi-byte text in popup title shows up wrong. Solution: Use the character width instead of the byte length. (Ralf Schandl, closes #8267, closes #8264) --- diff --git a/src/message_test.c b/src/message_test.c index 88335de26..882b591e4 100644 --- a/src/message_test.c +++ b/src/message_test.c @@ -120,6 +120,37 @@ test_trunc_string(void) vim_free(s); } +/* + * Test trunc_string() with mbyte chars. + */ + static void +test_trunc_string_mbyte(void) +{ + char_u *buf; // allocated every time to find uninit errors + char_u *s; + + buf = alloc(40); + s = vim_strsave((char_u *)"Ä text tha just fits"); + trunc_string(s, buf, 20, 40); + assert(STRCMP(buf, "Ä text tha just fits") == 0); + vim_free(buf); + vim_free(s); + + buf = alloc(40); + s = vim_strsave((char_u *)"a text ÄÖÜä nott fits"); + trunc_string(s, buf, 20, 40); + assert(STRCMP(buf, "a text Ä...nott fits") == 0); + vim_free(buf); + vim_free(s); + + buf = alloc(40); + s = vim_strsave((char_u *)"a text that not fitsÄ"); + trunc_string(s, buf, 20, 40); + assert(STRCMP(buf, "a text t...not fitsÄ") == 0); + vim_free(buf); + vim_free(s); +} + /* * Test vim_snprintf() with a focus on checking that truncation is * correct when buffer is small, since it cannot be tested from @@ -286,6 +317,7 @@ main(int argc, char **argv) set_option_value((char_u *)"encoding", 0, (char_u *)"utf-8", 0); init_chartab(); test_trunc_string(); + test_trunc_string_mbyte(); test_vim_snprintf(); set_option_value((char_u *)"encoding", 0, (char_u *)"latin1", 0); diff --git a/src/popupwin.c b/src/popupwin.c index 335345f3a..35c4b0af5 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -3822,17 +3822,29 @@ update_popups(void (*win_update)(win_T *wp)) title_wincol = wp->w_wincol + 1; if (wp->w_popup_title != NULL) { - char_u *title_text; + title_len = (int)MB_CHARLEN(wp->w_popup_title); - title_len = (int)STRLEN(wp->w_popup_title); - title_text = alloc(title_len + 1); - trunc_string(wp->w_popup_title, title_text, - total_width - 2, title_len + 1); - screen_puts(title_text, wp->w_winrow, title_wincol, - wp->w_popup_border[0] > 0 ? border_attr[0] : popup_attr); - vim_free(title_text); + // truncate the title if too long if (title_len > total_width - 2) + { + int title_byte_len = (int)STRLEN(wp->w_popup_title); + char_u *title_text = alloc(title_byte_len + 1); + + if (title_text != NULL) + { + trunc_string(wp->w_popup_title, title_text, + total_width - 2, title_byte_len + 1); + screen_puts(title_text, wp->w_winrow, title_wincol, + wp->w_popup_border[0] > 0 + ? border_attr[0] : popup_attr); + vim_free(title_text); + } + title_len = total_width - 2; + } + else + screen_puts(wp->w_popup_title, wp->w_winrow, title_wincol, + wp->w_popup_border[0] > 0 ? border_attr[0] : popup_attr); } wincol = wp->w_wincol - wp->w_popup_leftoff; diff --git a/src/testdir/dumps/Test_popupwin_multibytetitle.dump b/src/testdir/dumps/Test_popupwin_multibytetitle.dump new file mode 100644 index 000000000..e21c0cf2b --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_multibytetitle.dump @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @73 +|3| @73 +|4| @25|╔+0#0000001#ffd7ff255|▶|Ä|Ö|Ü|◀|═@12|╗| +0#0000000#ffffff0@27 +|5| @25|║+0#0000001#ffd7ff255| |T+0&#e0e0e08|h|i|s| |i|s| |a| |l|i|n|e| @1| +0&#ffd7ff255|║| +0#0000000#ffffff0@27 +|6| @25|║+0#0000001#ffd7ff255| |a|n|d| |a|n|o|t|h|e|r| |l|i|n|e| |║| +0#0000000#ffffff0@27 +|7| @25|╚+0#0000001#ffd7ff255|═@17|╝| +0#0000000#ffffff0@27 +|8| @73 +|9| @73 +@57|1|,|1| @10|T|o|p| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index f13252b05..13957e57c 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -1799,6 +1799,11 @@ func Test_popup_title() call term_sendkeys(buf, ":\") call VerifyScreenDump(buf, 'Test_popupwin_longtitle_4', {}) + call term_sendkeys(buf, ":call popup_clear()\") + call term_sendkeys(buf, ":call popup_menu(['This is a line', 'and another line'], #{title: '▶ÄÖÜ◀', })\") + call VerifyScreenDump(buf, 'Test_popupwin_multibytetitle', {}) + call term_sendkeys(buf, "x") + " clean up call StopVimInTerminal(buf) call delete('XtestPopupTitle') diff --git a/src/version.c b/src/version.c index fb8a7ad92..2dedcbfa5 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2893, /**/ 2892, /**/