From 39b431b3ed5d5e7c9236655a874863489567174a Mon Sep 17 00:00:00 2001 From: ckelsel Date: Fri, 30 Jun 2017 20:18:41 +0800 Subject: [PATCH 01/22] fix hostname_spec.lua test failed --- test/functional/eval/hostname_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/eval/hostname_spec.lua b/test/functional/eval/hostname_spec.lua index f1867846c4..6d5b64b929 100644 --- a/test/functional/eval/hostname_spec.lua +++ b/test/functional/eval/hostname_spec.lua @@ -8,7 +8,7 @@ describe('hostname()', function() it('returns hostname string', function() local actual = call('hostname') - ok(string.len(actual) > 1) + ok(string.len(actual) > 0) if call('executable', 'hostname') == 1 then local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '') helpers.eq(expected, actual) From 3965449d05d02c619b44c2b939b9ff88ba542aa0 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sat, 1 Jul 2017 10:55:55 +0800 Subject: [PATCH 02/22] test --- travis_ci | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 travis_ci diff --git a/travis_ci b/travis_ci new file mode 100644 index 0000000000..e69de29bb2 From b96f43f2b86cbac3f34691fd97bce4cdb9d6aed9 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sat, 1 Jul 2017 10:56:46 +0800 Subject: [PATCH 03/22] rm test --- travis_ci | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 travis_ci diff --git a/travis_ci b/travis_ci deleted file mode 100644 index e69de29bb2..0000000000 From 8cc49f9f1ad4edface62284c32f05ef1140d8220 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Wed, 12 Jul 2017 11:34:22 +0800 Subject: [PATCH 04/22] ignore patch-2367,2364 --- src/nvim/version.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvim/version.c b/src/nvim/version.c index 094ca29b01..9d57da4caa 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -77,10 +77,10 @@ static char *features[] = { // clang-format off static const int included_patches[] = { - // 2367,NA + // 2367 NA // 2366 NA // 2365 NA - // 2364,NA + // 2364 NA // 2363 NA 2362, // 2361 NA From 5e66c429e33db1c9a272c273cb3ad95c9bf64627 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 01:51:08 +0200 Subject: [PATCH 05/22] vim-patch:8.0.0090 fix breakindent bug (original Vim commit-message is bogus) https://github.com/vim/vim/commit/6c896867c4f5d759616028ef7cbfce2a9ed32600 --- src/nvim/screen.c | 8 +- src/nvim/testdir/test_breakindent.vim | 241 ++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 3 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 src/nvim/testdir/test_breakindent.vim diff --git a/src/nvim/screen.c b/src/nvim/screen.c index cd4f4de40f..e3a2c1ffec 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2195,7 +2195,7 @@ win_line ( int change_start = MAXCOL; /* first col of changed area */ int change_end = -1; /* last col of changed area */ colnr_T trailcol = MAXCOL; /* start of trailing spaces */ - int need_showbreak = FALSE; + int need_showbreak = false; // overlong line, skip first x chars int line_attr = 0; /* attribute for the whole line */ matchitem_T *cur; /* points to the match list */ match_T *shl; /* points to search_hl or a match */ @@ -2805,8 +2805,10 @@ win_line ( // draw 'breakindent': indent wrapped text accodringly if (draw_state == WL_BRI - 1 && n_extra == 0) { draw_state = WL_BRI; - if (wp->w_p_bri && row != startrow && filler_lines == 0) { - char_attr = wp->w_hl_attr_normal; // was: hl_attr(HLF_AT); + // if need_showbreak is set, breakindent also applies + if (wp->w_p_bri && (row != startrow || need_showbreak) + && filler_lines == 0) { + char_attr = wp->w_hl_attr_normal; if (diff_hlf != (hlf_T)0) { char_attr = win_hl_attr(wp, diff_hlf); diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim new file mode 100644 index 0000000000..bf363dcf8c --- /dev/null +++ b/src/nvim/testdir/test_breakindent.vim @@ -0,0 +1,241 @@ +" Test for breakindent +" +" Note: if you get strange failures when adding new tests, it might be that +" while the test is run, the breakindent cacheing gets in its way. +" It helps to change the tabastop setting and force a redraw (e.g. see +" Test_breakindent08()) +if !exists('+breakindent') + finish +endif + +let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP" + +function s:screenline(lnum, width) abort + " always get 4 screen lines + redraw! + let line = [] + for j in range(3) + for c in range(1, a:width) + call add(line, nr2char(screenchar(a:lnum+j, c))) + endfor + call add(line, "\n") + endfor + return join(line, '') +endfunction + +function s:testwindows(...) + 10new + vsp + vert resize 20 + setl ts=4 sw=4 sts=4 breakindent + put =s:input + if a:0 + exe a:1 + endif +endfunction + +function s:close_windows(...) + bw! + if a:0 + exe a:1 + endif + unlet! g:line g:expect +endfunction + +function Test_breakindent01() + " simple breakindent test + call s:testwindows('setl briopt=min:0') + let g:line=s:screenline(line('.'),8) + let g:expect=" abcd\n qrst\n GHIJ\n" + call assert_equal(g:expect, g:line) + call s:close_windows() +endfunction + +function Test_breakindent02() + " simple breakindent test with showbreak set + call s:testwindows('setl briopt=min:0 sbr=>>') + let g:line=s:screenline(line('.'),8) + let g:expect=" abcd\n >>qr\n >>EF\n" + call assert_equal(g:expect, g:line) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent03() + " simple breakindent test with showbreak set and briopt including sbr + call s:testwindows('setl briopt=sbr,min:0 sbr=++') + let g:line=s:screenline(line('.'),8) + let g:expect=" abcd\n++ qrst\n++ GHIJ\n" + call assert_equal(g:expect, g:line) + " clean up + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent04() + " breakindent set with min width 18 + call s:testwindows('setl sbr= briopt=min:18') + let g:line=s:screenline(line('.'),8) + let g:expect=" abcd\n qrstuv\n IJKLMN\n" + call assert_equal(g:expect, g:line) + " clean up + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent05() + " breakindent set and shift by 2 + call s:testwindows('setl briopt=shift:2,min:0') + let g:line=s:screenline(line('.'),8) + let g:expect=" abcd\n qr\n EF\n" + call assert_equal(g:expect, g:line) + call s:close_windows() +endfunction + +function Test_breakindent06() + " breakindent set and shift by -1 + call s:testwindows('setl briopt=shift:-1,min:0') + let g:line=s:screenline(line('.'),8) + let g:expect=" abcd\n qrstu\n HIJKL\n" + call assert_equal(g:expect, g:line) + call s:close_windows() +endfunction + +function Test_breakindent07() + " breakindent set and shift by 1, Number set sbr=? and briopt:sbr + call s:testwindows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n') + let g:line=s:screenline(line('.'),10) + let g:expect=" 2 ab\n? m\n? x\n" + call assert_equal(g:expect, g:line) + " clean up + call s:close_windows('set sbr= cpo-=n') +endfunction + +function Test_breakindent07a() + " breakindent set and shift by 1, Number set sbr=? and briopt:sbr + call s:testwindows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4') + let g:line=s:screenline(line('.'),10) + let g:expect=" 2 ab\n ? m\n ? x\n" + call assert_equal(g:expect, g:line) + " clean up + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent08() + " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr + call s:testwindows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4') + " make sure, cache is invalidated! + set ts=8 + redraw! + set ts=4 + redraw! + let g:line=s:screenline(line('.'),10) + let g:expect=" 2 ^Iabcd\n# opq\n# BCD\n" + call assert_equal(g:expect, g:line) + call s:close_windows('set sbr= cpo-=n') +endfunction + +function Test_breakindent08a() + " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr + call s:testwindows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list') + let g:line=s:screenline(line('.'),10) + let g:expect=" 2 ^Iabcd\n # opq\n # BCD\n" + call assert_equal(g:expect, g:line) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent09() + " breakindent set and shift by 1, Number and list set sbr=# + call s:testwindows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list') + let g:line=s:screenline(line('.'),10) + let g:expect=" 2 ^Iabcd\n #op\n #AB\n" + call assert_equal(g:expect, g:line) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent10() + " breakindent set, Number set sbr=~ + call s:testwindows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0') + " make sure, cache is invalidated! + set ts=8 + redraw! + set ts=4 + redraw! + let g:line=s:screenline(line('.'),10) + let g:expect=" 2 ab\n~ mn\n~ yz\n" + call assert_equal(g:expect, g:line) + call s:close_windows('set sbr= cpo-=n') +endfunction + +function Test_breakindent11() + " test strdisplaywidth() + call s:testwindows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4') + let text=getline(2) + let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times + call assert_equal(width, strdisplaywidth(text)) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent12() + " test breakindent with long indent + let s:input="\t\t\t\t\t{" + call s:testwindows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-') + let g:line=s:screenline(2,16) + let g:expect=" 2 >--->--->--->\n ---{ \n~ \n" + call assert_equal(g:expect, g:line) + call s:close_windows('set nuw=4 listchars=') +endfunction + +function Test_breakindent13() + let s:input="" + call s:testwindows('setl breakindent briopt=min:10 ts=8') + vert resize 20 + call setline(1, [" a\tb\tc\td\te", " z y x w v"]) + 1 + norm! fbgj"ayl + 2 + norm! fygj"byl + call assert_equal('d', @a) + call assert_equal('w', @b) + call s:close_windows() +endfunction + +function Test_breakindent14() + let s:input="" + call s:testwindows('setl breakindent briopt= ts=8') + vert resize 30 + norm! 3a1234567890 + norm! a abcde + exec "norm! 0\tex" + let g:line=s:screenline(line('.'),8) + let g:expect="e \n~ \n~ \n" + call assert_equal(g:expect, g:line) + call s:close_windows() +endfunction + +function Test_breakindent15() + let s:input="" + call s:testwindows('setl breakindent briopt= ts=8 sw=8') + vert resize 30 + norm! 4a1234567890 + exe "normal! >>\3f0x" + let g:line=s:screenline(line('.'),20) + let g:expect=" 1234567890 \n~ \n~ \n" + call assert_equal(g:expect, g:line) + call s:close_windows() +endfunction + +function Test_breakindent16() + " Check that overlong lines are indented correctly. + " TODO: currently it does not fail even when the bug is not fixed. + let s:input="" + call s:testwindows('setl breakindent briopt=min:0 ts=4') + call setline(1, "\t".repeat("1234567890", 10)) + resize 6 + norm! 1gg$ + redraw! + let g:line=s:screenline(1,10) + let g:expect=" 123456\n 789012\n 345678\n" + call assert_equal(g:expect, g:line) + let g:line=s:screenline(4,10) + let g:expect=" 901234\n 567890\n 123456\n" + call assert_equal(g:expect, g:line) + call s:close_windows() +endfunction diff --git a/src/nvim/version.c b/src/nvim/version.c index 72af7dbafd..69d5cb8e8d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -862,7 +862,7 @@ static const int included_patches[] = { // 93 NA // 92, // 91, - // 90, + 90, // 89 NA 88, // 87 NA From dfd45f26f14179c6a4c75f06814c0ff6c0792349 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 02:26:21 +0200 Subject: [PATCH 06/22] vim-patch:8.0.0126 Problem: Display problem with 'foldcolumn' and a wide character. (esiegerman) Solution: Don't use "extra" but an allocated buffer. (Christian Brabandt, closes vim/vim#1310) https://github.com/vim/vim/commit/6270660611a151c5d0f614a5f0248ccdc80ed971 --- src/nvim/screen.c | 19 ++++++++++------ src/nvim/testdir/test_display.vim | 37 +++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 src/nvim/testdir/test_display.vim diff --git a/src/nvim/screen.c b/src/nvim/screen.c index e3a2c1ffec..3d558bdbdd 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2705,13 +2705,18 @@ win_line ( draw_state = WL_FOLD; if (fdc > 0) { - // Draw the 'foldcolumn'. - fill_foldcolumn(extra, wp, false, lnum); - n_extra = fdc; - p_extra = extra; - p_extra[n_extra] = NUL; - c_extra = NUL; - char_attr = win_hl_attr(wp, HLF_FC); + // Draw the 'foldcolumn'. Allocate a buffer, "extra" may + // already be in used. + p_extra_free = xmalloc(12 + 1); + + if (p_extra_free != NULL) { + fill_foldcolumn(p_extra_free, wp, false, lnum); + n_extra = fdc; + p_extra_free[n_extra] = NUL; + p_extra = p_extra_free; + c_extra = NUL; + char_attr = win_hl_attr(wp, HLF_FC); + } } } diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim new file mode 100644 index 0000000000..ba7b7d7626 --- /dev/null +++ b/src/nvim/testdir/test_display.vim @@ -0,0 +1,37 @@ +" Test for displaying stuff +if !has('gui_running') && has('unix') + set term=ansi +endif + +function! s:screenline(lnum, nr) abort + let line = [] + for j in range(a:nr) + for c in range(1, winwidth(0)) + call add(line, nr2char(screenchar(a:lnum+j, c))) + endfor + call add(line, "\n") + endfor + return join(line, '') +endfunction + +function! Test_display_foldcolumn() + new + vnew + vert resize 25 + + 1put='e more noise blah blah‚ more stuff here' + + let expect = "e more noise blah blah<82\n> more stuff here \n" + + call cursor(2, 1) + norm! zt + redraw! + call assert_equal(expect, s:screenline(1,2)) + set fdc=2 + redraw! + let expect = " e more noise blah blah<\n 82> more stuff here \n" + call assert_equal(expect, s:screenline(1,2)) + + quit! + quit! +endfunction diff --git a/src/nvim/version.c b/src/nvim/version.c index 69d5cb8e8d..ca1d64ac56 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -826,7 +826,7 @@ static const int included_patches[] = { // 129 NA // 128, 127, - // 126, + 126, // 125, 124, // 123 NA From 247c3385178383b7a4451210cbef22fe83427f92 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 02:30:54 +0200 Subject: [PATCH 07/22] vim-patch:8.0.0128 Problem: Display test fails on MS-Windows. Solution: Set 'isprint' to "@". https://github.com/vim/vim/commit/7089237885218eb8a19805bc2b75481c4efcd6ba --- src/nvim/testdir/test_display.vim | 2 ++ src/nvim/version.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim index ba7b7d7626..609e16c737 100644 --- a/src/nvim/testdir/test_display.vim +++ b/src/nvim/testdir/test_display.vim @@ -18,6 +18,8 @@ function! Test_display_foldcolumn() new vnew vert resize 25 + call assert_equal(25, winwidth(winnr())) + set isprint=@ 1put='e more noise blah blah‚ more stuff here' diff --git a/src/nvim/version.c b/src/nvim/version.c index ca1d64ac56..dfee84c1b2 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -824,7 +824,7 @@ static const int included_patches[] = { // 131, // 130 NA // 129 NA - // 128, + 128, 127, 126, // 125, From f5e55e93aa4b390e455d825a076cc0c29ba0e933 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 01:46:43 +0200 Subject: [PATCH 08/22] vim-patch:8.0.0311 Problem: Linebreak tests are old style. Solution: Turn the tests into new style. Share utility functions. (Ozaki Kiichi, closes vim/vim#1444) https://github.com/vim/vim/commit/544d3bc9f0e494cb712a33b61558b8e8e12b1e0b --- src/nvim/testdir/test_breakindent.vim | 246 +++++++++++++++---------- src/nvim/testdir/test_listlbr.vim | 219 ++++++++++++++++++++++ src/nvim/testdir/test_listlbr_utf8.vim | 195 ++++++++++++++++++++ src/nvim/testdir/view_util.vim | 30 +++ src/nvim/version.c | 2 +- 5 files changed, 597 insertions(+), 95 deletions(-) create mode 100644 src/nvim/testdir/test_listlbr.vim create mode 100644 src/nvim/testdir/test_listlbr_utf8.vim create mode 100644 src/nvim/testdir/view_util.vim diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim index bf363dcf8c..8721b35cdf 100644 --- a/src/nvim/testdir/test_breakindent.vim +++ b/src/nvim/testdir/test_breakindent.vim @@ -2,171 +2,209 @@ " " Note: if you get strange failures when adding new tests, it might be that " while the test is run, the breakindent cacheing gets in its way. -" It helps to change the tabastop setting and force a redraw (e.g. see +" It helps to change the tabstop setting and force a redraw (e.g. see " Test_breakindent08()) if !exists('+breakindent') finish endif +source view_util.vim + let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP" -function s:screenline(lnum, width) abort - " always get 4 screen lines - redraw! - let line = [] - for j in range(3) - for c in range(1, a:width) - call add(line, nr2char(screenchar(a:lnum+j, c))) - endfor - call add(line, "\n") - endfor - return join(line, '') +function s:screen_lines(lnum, width) abort + return ScreenLines([a:lnum, a:lnum + 2], a:width) endfunction -function s:testwindows(...) - 10new - vsp - vert resize 20 - setl ts=4 sw=4 sts=4 breakindent +function! s:compare_lines(expect, actual) + call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) +endfunction + +function s:test_windows(...) + call NewWindow(10, 20) + setl ts=4 sw=4 sts=4 breakindent put =s:input - if a:0 - exe a:1 - endif + exe get(a:000, 0, '') endfunction function s:close_windows(...) - bw! - if a:0 - exe a:1 - endif - unlet! g:line g:expect + call CloseWindow() + exe get(a:000, 0, '') endfunction function Test_breakindent01() " simple breakindent test - call s:testwindows('setl briopt=min:0') - let g:line=s:screenline(line('.'),8) - let g:expect=" abcd\n qrst\n GHIJ\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=min:0') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qrst", +\ " GHIJ", +\ ] + call s:compare_lines(expect, lines) call s:close_windows() endfunction function Test_breakindent02() " simple breakindent test with showbreak set - call s:testwindows('setl briopt=min:0 sbr=>>') - let g:line=s:screenline(line('.'),8) - let g:expect=" abcd\n >>qr\n >>EF\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=min:0 sbr=>>') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " >>qr", +\ " >>EF", +\ ] + call s:compare_lines(expect, lines) call s:close_windows('set sbr=') endfunction function Test_breakindent03() " simple breakindent test with showbreak set and briopt including sbr - call s:testwindows('setl briopt=sbr,min:0 sbr=++') - let g:line=s:screenline(line('.'),8) - let g:expect=" abcd\n++ qrst\n++ GHIJ\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=sbr,min:0 sbr=++') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ "++ qrst", +\ "++ GHIJ", +\ ] + call s:compare_lines(expect, lines) " clean up call s:close_windows('set sbr=') endfunction function Test_breakindent04() " breakindent set with min width 18 - call s:testwindows('setl sbr= briopt=min:18') - let g:line=s:screenline(line('.'),8) - let g:expect=" abcd\n qrstuv\n IJKLMN\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl sbr= briopt=min:18') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qrstuv", +\ " IJKLMN", +\ ] + call s:compare_lines(expect, lines) " clean up call s:close_windows('set sbr=') endfunction function Test_breakindent05() " breakindent set and shift by 2 - call s:testwindows('setl briopt=shift:2,min:0') - let g:line=s:screenline(line('.'),8) - let g:expect=" abcd\n qr\n EF\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=shift:2,min:0') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qr", +\ " EF", +\ ] + call s:compare_lines(expect, lines) call s:close_windows() endfunction function Test_breakindent06() " breakindent set and shift by -1 - call s:testwindows('setl briopt=shift:-1,min:0') - let g:line=s:screenline(line('.'),8) - let g:expect=" abcd\n qrstu\n HIJKL\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=shift:-1,min:0') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qrstu", +\ " HIJKL", +\ ] + call s:compare_lines(expect, lines) call s:close_windows() endfunction function Test_breakindent07() " breakindent set and shift by 1, Number set sbr=? and briopt:sbr - call s:testwindows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n') - let g:line=s:screenline(line('.'),10) - let g:expect=" 2 ab\n? m\n? x\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ab", +\ "? m", +\ "? x", +\ ] + call s:compare_lines(expect, lines) " clean up call s:close_windows('set sbr= cpo-=n') endfunction function Test_breakindent07a() " breakindent set and shift by 1, Number set sbr=? and briopt:sbr - call s:testwindows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4') - let g:line=s:screenline(line('.'),10) - let g:expect=" 2 ab\n ? m\n ? x\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ab", +\ " ? m", +\ " ? x", +\ ] + call s:compare_lines(expect, lines) " clean up call s:close_windows('set sbr=') endfunction function Test_breakindent08() " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr - call s:testwindows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4') + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4') " make sure, cache is invalidated! set ts=8 redraw! set ts=4 redraw! - let g:line=s:screenline(line('.'),10) - let g:expect=" 2 ^Iabcd\n# opq\n# BCD\n" - call assert_equal(g:expect, g:line) + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ^Iabcd", +\ "# opq", +\ "# BCD", +\ ] + call s:compare_lines(expect, lines) call s:close_windows('set sbr= cpo-=n') endfunction function Test_breakindent08a() " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr - call s:testwindows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list') - let g:line=s:screenline(line('.'),10) - let g:expect=" 2 ^Iabcd\n # opq\n # BCD\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ^Iabcd", +\ " # opq", +\ " # BCD", +\ ] + call s:compare_lines(expect, lines) call s:close_windows('set sbr=') endfunction function Test_breakindent09() " breakindent set and shift by 1, Number and list set sbr=# - call s:testwindows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list') - let g:line=s:screenline(line('.'),10) - let g:expect=" 2 ^Iabcd\n #op\n #AB\n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ^Iabcd", +\ " #op", +\ " #AB", +\ ] + call s:compare_lines(expect, lines) call s:close_windows('set sbr=') endfunction function Test_breakindent10() " breakindent set, Number set sbr=~ - call s:testwindows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0') + call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0') " make sure, cache is invalidated! set ts=8 redraw! set ts=4 redraw! - let g:line=s:screenline(line('.'),10) - let g:expect=" 2 ab\n~ mn\n~ yz\n" - call assert_equal(g:expect, g:line) + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ab", +\ "~ mn", +\ "~ yz", +\ ] + call s:compare_lines(expect, lines) call s:close_windows('set sbr= cpo-=n') endfunction function Test_breakindent11() " test strdisplaywidth() - call s:testwindows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4') + call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4') let text=getline(2) let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times call assert_equal(width, strdisplaywidth(text)) @@ -176,16 +214,20 @@ endfunction function Test_breakindent12() " test breakindent with long indent let s:input="\t\t\t\t\t{" - call s:testwindows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-') - let g:line=s:screenline(2,16) - let g:expect=" 2 >--->--->--->\n ---{ \n~ \n" - call assert_equal(g:expect, g:line) + call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-') + let lines=s:screen_lines(2,16) + let expect=[ +\ " 2 >--->--->--->", +\ " ---{ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) call s:close_windows('set nuw=4 listchars=') endfunction function Test_breakindent13() let s:input="" - call s:testwindows('setl breakindent briopt=min:10 ts=8') + call s:test_windows('setl breakindent briopt=min:10 ts=8') vert resize 20 call setline(1, [" a\tb\tc\td\te", " z y x w v"]) 1 @@ -199,26 +241,34 @@ endfunction function Test_breakindent14() let s:input="" - call s:testwindows('setl breakindent briopt= ts=8') + call s:test_windows('setl breakindent briopt= ts=8') vert resize 30 norm! 3a1234567890 norm! a abcde exec "norm! 0\tex" - let g:line=s:screenline(line('.'),8) - let g:expect="e \n~ \n~ \n" - call assert_equal(g:expect, g:line) + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ "e ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) call s:close_windows() endfunction function Test_breakindent15() let s:input="" - call s:testwindows('setl breakindent briopt= ts=8 sw=8') + call s:test_windows('setl breakindent briopt= ts=8 sw=8') vert resize 30 norm! 4a1234567890 exe "normal! >>\3f0x" - let g:line=s:screenline(line('.'),20) - let g:expect=" 1234567890 \n~ \n~ \n" - call assert_equal(g:expect, g:line) + let lines=s:screen_lines(line('.'),20) + let expect=[ +\ " 1234567890 ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) call s:close_windows() endfunction @@ -226,16 +276,24 @@ function Test_breakindent16() " Check that overlong lines are indented correctly. " TODO: currently it does not fail even when the bug is not fixed. let s:input="" - call s:testwindows('setl breakindent briopt=min:0 ts=4') + call s:test_windows('setl breakindent briopt=min:0 ts=4') call setline(1, "\t".repeat("1234567890", 10)) resize 6 norm! 1gg$ redraw! - let g:line=s:screenline(1,10) - let g:expect=" 123456\n 789012\n 345678\n" - call assert_equal(g:expect, g:line) - let g:line=s:screenline(4,10) - let g:expect=" 901234\n 567890\n 123456\n" - call assert_equal(g:expect, g:line) + let lines=s:screen_lines(1,10) + let expect=[ +\ " 123456", +\ " 789012", +\ " 345678", +\ ] + call s:compare_lines(expect, lines) + let lines=s:screen_lines(4,10) + let expect=[ +\ " 901234", +\ " 567890", +\ " 123456", +\ ] + call s:compare_lines(expect, lines) call s:close_windows() endfunction diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim new file mode 100644 index 0000000000..71366a161e --- /dev/null +++ b/src/nvim/testdir/test_listlbr.vim @@ -0,0 +1,219 @@ +" Test for linebreak and list option (non-utf8) + +set encoding=latin1 +scriptencoding latin1 + +if !exists("+linebreak") || !has("conceal") + finish +endif + +source view_util.vim + +function s:screen_lines(lnum, width) abort + return ScreenLines(a:lnum, a:width) +endfunction + +function! s:compare_lines(expect, actual) + call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) +endfunction + +function s:test_windows(...) + call NewWindow(10, 20) + setl ts=8 sw=4 sts=4 linebreak sbr= wrap + exe get(a:000, 0, '') +endfunction + +function s:close_windows(...) + call CloseWindow() + exe get(a:000, 0, '') +endfunction + +func Test_set_linebreak() + call s:test_windows('setl ts=4 sbr=+') + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ") + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ " abcdef ", +\ "+hijklmn ", +\ "+pqrstuvwxyz_1060ABC", +\ "+DEFGHIJKLMNOP ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_list() + call s:test_windows('setl ts=4 sbr=+ list listchars=') + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ") + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "^Iabcdef hijklmn^I ", +\ "+pqrstuvwxyz_1060ABC", +\ "+DEFGHIJKLMNOP ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_nolist() + call s:test_windows('setl ts=4 sbr=+ nolist') + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ") + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ " abcdef ", +\ "+hijklmn ", +\ "+pqrstuvwxyz_1060ABC", +\ "+DEFGHIJKLMNOP ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_should_break() + call s:test_windows('setl sbr=+ nolist') + call setline(1, "1\t" . repeat('a', winwidth(0)-2)) + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "1 ", +\ "+aaaaaaaaaaaaaaaaaa ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_conceal() + call s:test_windows('setl cpo&vim sbr=+ list conceallevel=2 concealcursor=nv listchars=tab:ab') + call setline(1, "_S_\t bla") + syn match ConcealVar contained /_/ conceal + syn match All /.*/ contains=ConcealVar + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "Sabbbbbb bla ", +\ "~ ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_virtual_block() + call s:test_windows('setl sbr=+') + call setline(1, [ +\ "REMOVE: this not", +\ "REMOVE: aaaaaaaaaaaaa", +\ ]) + exe "norm! 1/^REMOVE:" + exe "norm! 0\jf x" + $put + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "this not ", +\ "aaaaaaaaaaaaa ", +\ "REMOVE: ", +\ "REMOVE: ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_virtual_block_and_vbA() + call s:test_windows() + call setline(1, "long line: " . repeat("foobar ", 40) . "TARGET at end") + exe "norm! $3B\eAx\" + let lines = s:screen_lines([1, 10], winwidth(0)) + let expect = [ +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar TARGETx at ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_virtual_char_and_block() + call s:test_windows() + call setline(1, "1111-1111-1111-11-1111-1111-1111") + exe "norm! 0f-lv3lc2222\bgj." + let lines = s:screen_lines([1, 2], winwidth(0)) + let expect = [ +\ "1111-2222-1111-11- ", +\ "1111-2222-1111 ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_undo_after_block_visual() + call s:test_windows() + call setline(1, ["aaa", "aaa", "a"]) + exe "norm! gg\2j~e." + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ "AaA ", +\ "AaA ", +\ "A ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_norm_after_block_visual() + call s:test_windows() + call setline(1, ["abcd{ef", "ghijklm", "no}pgrs"]) + exe "norm! ggf{\\c%" + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ "abcdpgrs ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_block_replace_after_wrapping() + call s:test_windows() + call setline(1, repeat("a", 150)) + exe "norm! 0yypk147|\jr0" + call assert_equal(repeat("a", 146) . "0aaa", getline(1)) + call assert_equal(repeat("a", 146) . "0aaa", getline(2)) + let lines = s:screen_lines([1, 10], winwidth(0)) + let expect = [ +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaa0aaa ", +\ "@ ", +\ "@ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_with_listchars() + call s:test_windows('setl list listchars=space:_,trail:-,tab:>-,eol:$') + call setline(1, "a aaaaaaaaaaaaaaaaaaaaaa\ta ") + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ "a_ ", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aa>-----a-$ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim new file mode 100644 index 0000000000..807b6ad31a --- /dev/null +++ b/src/nvim/testdir/test_listlbr_utf8.vim @@ -0,0 +1,195 @@ +" Test for linebreak and list option in utf-8 mode + +set encoding=utf-8 +scriptencoding utf-8 + +if !exists("+linebreak") || !has("conceal") || !has("signs") + finish +endif + +source view_util.vim + +function s:screen_lines(lnum, width) abort + return ScreenLines(a:lnum, a:width) +endfunction + +function! s:compare_lines(expect, actual) + call assert_equal(a:expect, a:actual) +endfunction + +function s:screen_attr(lnum, chars, ...) abort + let line = getline(a:lnum) + let attr = [] + let prefix = get(a:000, 0, 0) + for i in range(a:chars[0], a:chars[1]) + let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1 + let attr += [screenattr(a:lnum, scol + prefix)] + endfor + return attr +endfunction + +function s:test_windows(...) + call NewWindow(10, 20) + setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap + exe get(a:000, 0, '') +endfunction + +function s:close_windows(...) + call CloseWindow() + exe get(a:000, 0, '') +endfunction + +func Test_linebreak_with_fancy_listchars() + call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ") + redraw! + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "▕———abcdef ", +\ "+hijklmn▕——— ", +\ "+pqrstuvwxyz␣1060ABC", +\ "+DEFGHIJKLMNOPˑ¶ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_nolinebreak_with_list() + call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ") + redraw! + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "▕———abcdef hijklmn▕—", +\ "+pqrstuvwxyz␣1060ABC", +\ "+DEFGHIJKLMNOPˑ¶ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_nolist() + call s:test_windows('setl nolist') + call setline(1, "\t*mask = nil;") + redraw! + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ " *mask = nil; ", +\ "~ ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_and_concealing1() + call s:test_windows('setl list listchars=tab:>- cole=1') + call setline(1, [ +\ "#define ABCDE\t\t1", +\ "#define ABCDEF\t\t1", +\ "#define ABCDEFG\t\t1", +\ "#define ABCDEFGH\t1", +\ "#define MSG_MODE_FILE\t\t\t1", +\ "#define MSG_MODE_CONSOLE\t\t2", +\ "#define MSG_MODE_FILE_AND_CONSOLE\t3", +\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4", +\ ]) + vert resize 40 + syn match Conceal conceal cchar=>'AB\|MSG_MODE' + redraw! + let lines = s:screen_lines([1, 7], winwidth(0)) + let expect = [ +\ "#define ABCDE>-->---1 ", +\ "#define >CDEF>-->---1 ", +\ "#define >CDEFG>->---1 ", +\ "#define >CDEFGH>----1 ", +\ "#define >_FILE>--------->--->---1 ", +\ "#define >_CONSOLE>---------->---2 ", +\ "#define >_FILE_AND_CONSOLE>---------3 ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_and_concealing2() + call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n') + call setline(1, "bbeeeeee\t\t;\tsome text") + vert resize 40 + syn clear + syn match meaning /;\s*\zs.*/ + syn match hasword /^\x\{8}/ contains=word + syn match word /\<\x\{8}\>/ contains=beginword,endword contained + syn match beginword /\<\x\x/ contained conceal + syn match endword /\x\{6}\>/ contained + hi meaning guibg=blue + hi beginword guibg=green + hi endword guibg=red + redraw! + let lines = s:screen_lines([1, 1], winwidth(0)) + let expect = [ +\ "eeeeee>--->-;>some text ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_screenattr_for_comment() + call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, " /*\t\t and some more */") + norm! gg0 + syntax on + hi SpecialKey term=underline ctermfg=red guifg=red + redraw! + let line = getline(1) + let attr = s:screen_attr(1, [1, 6]) + call assert_notequal(attr[0], attr[1]) + call assert_notequal(attr[1], attr[3]) + call assert_notequal(attr[3], attr[5]) + call s:close_windows() +endfunc + +func Test_visual_block_and_selection_exclusive() + call s:test_windows('setl selection=exclusive') + call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end") + exe "norm! $3B\eAx\" + let lines = s:screen_lines([1, 10], winwidth(0)) + let expect = [ +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar TARGETÃx' ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_multibyte_sign_and_colorcolumn() + call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, ["", "a b c", "a b c"]) + exe "sign define foo text=\uff0b" + exe "sign place 1 name=foo line=2 buffer=" . bufnr('%') + redraw! + norm! ggj0 + let signwidth = strdisplaywidth("\uff0b") + let attr1 = s:screen_attr(2, [1, 3], signwidth) + let attr2 = s:screen_attr(3, [1, 3], signwidth) + call assert_equal(attr1[0], attr2[0]) + call assert_equal(attr1[1], attr2[1]) + call assert_equal(attr1[2], attr2[2]) + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ " ¶ ", +\ "+a b c¶ ", +\ " a b c¶ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim new file mode 100644 index 0000000000..eb92630761 --- /dev/null +++ b/src/nvim/testdir/view_util.vim @@ -0,0 +1,30 @@ +" Functions about view shared by several tests + +" ScreenLines(lnum, width) or +" ScreenLines([start, end], width) +function! ScreenLines(lnum, width) abort + redraw! + if type(a:lnum) == v:t_list + let start = a:lnum[0] + let end = a:lnum[1] + else + let start = a:lnum + let end = a:lnum + endif + let lines = [] + for l in range(start, end) + let lines += [join(map(range(1, a:width), 'nr2char(screenchar(l, v:val))'), '')] + endfor + return lines +endfunction + +function! NewWindow(height, width) abort + exe a:height . 'new' + exe a:width . 'vsp' + redraw! +endfunction + +function! CloseWindow() abort + bw! + redraw! +endfunction diff --git a/src/nvim/version.c b/src/nvim/version.c index dfee84c1b2..7fca8aee82 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -641,7 +641,7 @@ static const int included_patches[] = { // 314, // 313, // 312, - // 311, + 311, // 310, // 309, // 308, From a7b98246b3385d3cacfe5c0691c83f7558c2143e Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 02:11:31 +0200 Subject: [PATCH 09/22] vim-patch:8.0.0290 vim-patch:8.0.0394 vim-patch:8.0.0290: cursor positioning wrong if wide character wraps Problem: If a wide character doesn't fit at the end of the screen line, and the line doesn't fit on the screen, then the cursor position may be wrong. (anliting) Solution: Don't skip over wide character. (Christian Brabandt, closes vim/1408) vim-patch:8.0.0394 Problem: Tabs are not aligned when scrolling horizontally and a Tab doesn't fit. (Axel Bender) Solution: Handle a Tab as a not fitting character. (Christian Brabandt) Also fix that ":redraw" does not scroll horizontally to show the cursor. And fix the test that depended on the old behavior. https://github.com/vim/vim/commit/abc39ab642791ae3d22a524516eeedb673a95d9d --- src/nvim/ex_docmd.c | 1 + src/nvim/screen.c | 24 ++++++++++-------- src/nvim/testdir/test_breakindent.vim | 5 ++-- src/nvim/testdir/test_listlbr.vim | 16 ++++++++++++ src/nvim/testdir/test_listlbr_utf8.vim | 34 ++++++++++++++++++++++++++ src/nvim/version.c | 4 +-- 6 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 29788a9865..6e7938046a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7690,6 +7690,7 @@ static void ex_redraw(exarg_T *eap) RedrawingDisabled = 0; p_lz = FALSE; + validate_cursor(); update_topline(); update_screen(eap->forceit ? CLEAR : VIsual_active ? INVERTED : diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 3d558bdbdd..27701c4643 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2112,16 +2112,16 @@ win_line ( bool nochange /* not updating for changed text */ ) { - int col; /* visual column on screen */ - unsigned off; /* offset in ScreenLines/ScreenAttrs */ - int c = 0; /* init for GCC */ - long vcol = 0; /* virtual column (for tabs) */ + int col = 0; // visual column on screen + unsigned off; // offset in ScreenLines/ScreenAttrs + int c = 0; // init for GCC + long vcol = 0; // virtual column (for tabs) long vcol_sbr = -1; // virtual column after showbreak - long vcol_prev = -1; /* "vcol" of previous character */ - char_u *line; /* current line */ - char_u *ptr; /* current position in "line" */ - int row; /* row in the window, excl w_winrow */ - int screen_row; /* row on the screen, incl w_winrow */ + long vcol_prev = -1; // "vcol" of previous character + char_u *line; // current line + char_u *ptr; // current position in "line" + int row; // row in the window, excl w_winrow + int screen_row; // row on the screen, incl w_winrow char_u extra[18]; /* line number and 'fdc' must fit in here */ int n_extra = 0; /* number of extra chars */ @@ -2522,7 +2522,11 @@ win_line ( if (vcol > v) { vcol -= c; ptr = prev_ptr; - n_skip = v - vcol; + // If the character fits on the screen, don't need to skip it. + // Except for a TAB. + if (((*mb_ptr2cells)(ptr) >= c || *ptr == TAB) && col == 0) { + n_skip = v - vcol; + } } /* diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim index 8721b35cdf..7deffbe452 100644 --- a/src/nvim/testdir/test_breakindent.vim +++ b/src/nvim/testdir/test_breakindent.vim @@ -274,7 +274,6 @@ endfunction function Test_breakindent16() " Check that overlong lines are indented correctly. - " TODO: currently it does not fail even when the bug is not fixed. let s:input="" call s:test_windows('setl breakindent briopt=min:0 ts=4') call setline(1, "\t".repeat("1234567890", 10)) @@ -283,16 +282,16 @@ function Test_breakindent16() redraw! let lines=s:screen_lines(1,10) let expect=[ -\ " 123456", \ " 789012", \ " 345678", +\ " 901234", \ ] call s:compare_lines(expect, lines) let lines=s:screen_lines(4,10) let expect=[ -\ " 901234", \ " 567890", \ " 123456", +\ " 7890 ", \ ] call s:compare_lines(expect, lines) call s:close_windows() diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim index 71366a161e..7856ee82ab 100644 --- a/src/nvim/testdir/test_listlbr.vim +++ b/src/nvim/testdir/test_listlbr.vim @@ -217,3 +217,19 @@ func Test_list_with_listchars() call s:compare_lines(expect, lines) call s:close_windows() endfunc + +func Test_list_with_tab_and_skipping_first_chars() + call s:test_windows('setl list listchars=tab:>- ts=70 nowrap') + call setline(1, ["iiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa"]) + call cursor(4,64) + norm! 2zl + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "---------------aaaaa", +\ "---------------aaaaa", +\ "---------------aaaaa", +\ "iiiiiiiii>-----aaaaa", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfu diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim index 807b6ad31a..980d67d49d 100644 --- a/src/nvim/testdir/test_listlbr_utf8.vim +++ b/src/nvim/testdir/test_listlbr_utf8.vim @@ -193,3 +193,37 @@ func Test_multibyte_sign_and_colorcolumn() call s:compare_lines(expect, lines) call s:close_windows() endfunc + +func Test_chinese_char_on_wrap_column() + call s:test_windows("setl nolbr wrap sbr=") + syntax off + call setline(1, [ +\ 'aaaaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'hello']) + call cursor(1,1) + norm! $ + redraw! + let expect=[ +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中hello '] + let lines = s:screen_lines([1, 10], winwidth(0)) + call s:compare_lines(expect, lines) + call s:close_windows() +endfu diff --git a/src/nvim/version.c b/src/nvim/version.c index 7fca8aee82..a7479c6b18 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -558,7 +558,7 @@ static const int included_patches[] = { // 397, // 396, // 395, - // 394, + 394, 393, // 392, // 391, @@ -662,7 +662,7 @@ static const int included_patches[] = { // 293, // 292, // 291, - // 290, + 290, // 289, // 288 NA // 287, From 9b4cbd5cdcc807a69da649b96f52e8a3d56c1ff4 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 01:44:58 +0200 Subject: [PATCH 10/22] vim-patch:8.0.0518 Closes #7086 Problem: Storing a zero byte from a multi-byte character causes fold text to show up wrong. Solution: Avoid putting zero in ScreenLines. (Christian Brabandt, closes vim/vim#1567) https://github.com/vim/vim/commit/c6cd8409c2993b1476e123fba11cb4b8d743b896 --- src/nvim/screen.c | 8 +++-- src/nvim/testdir/test_display.vim | 56 +++++++++++++++++++++---------- src/nvim/version.c | 2 +- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 27701c4643..c302ac695e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1924,10 +1924,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T if (fill_fold >= 0x80) { ScreenLinesUC[off + col] = fill_fold; ScreenLinesC[0][off + col] = 0; - } else + ScreenLines[off + col] = 0x80; // avoid storing zero + } else { ScreenLinesUC[off + col] = 0; + } + col++; + } else { + ScreenLines[off + col++] = fill_fold; } - ScreenLines[off + col++] = fill_fold; } if (text != buf) diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim index 609e16c737..4253b56933 100644 --- a/src/nvim/testdir/test_display.vim +++ b/src/nvim/testdir/test_display.vim @@ -3,18 +3,12 @@ if !has('gui_running') && has('unix') set term=ansi endif -function! s:screenline(lnum, nr) abort - let line = [] - for j in range(a:nr) - for c in range(1, winwidth(0)) - call add(line, nr2char(screenchar(a:lnum+j, c))) - endfor - call add(line, "\n") - endfor - return join(line, '') -endfunction +source view_util.vim -function! Test_display_foldcolumn() +func! Test_display_foldcolumn() + if !has("folding") + return + endif new vnew vert resize 25 @@ -23,17 +17,43 @@ function! Test_display_foldcolumn() 1put='e more noise blah blah‚ more stuff here' - let expect = "e more noise blah blah<82\n> more stuff here \n" + let expect = [ + \ "e more noise blah blah<82", + \ "> more stuff here " + \ ] call cursor(2, 1) norm! zt - redraw! - call assert_equal(expect, s:screenline(1,2)) + let lines=ScreenLines([1,2], winwidth(0)) + call assert_equal(expect, lines) set fdc=2 - redraw! - let expect = " e more noise blah blah<\n 82> more stuff here \n" - call assert_equal(expect, s:screenline(1,2)) + let lines=ScreenLines([1,2], winwidth(0)) + let expect = [ + \ " e more noise blah blah<", + \ " 82> more stuff here " + \ ] + call assert_equal(expect, lines) quit! quit! -endfunction +endfunc + +func! Test_display_foldtext_mbyte() + if !has("folding") || !has("multi_byte") + return + endif + call NewWindow(10, 40) + call append(0, range(1,20)) + exe "set foldmethod=manual foldtext=foldtext() fillchars=fold:\u2500,vert:\u2502 fdc=2" + call cursor(2, 1) + norm! zf13G + let lines=ScreenLines([1,3], winwidth(0)+1) + let expect=[ + \ " 1 \u2502", + \ "+ +-- 12 lines: 2". repeat("\u2500", 23). "\u2502", + \ " 14 \u2502", + \ ] + call assert_equal(expect, lines) + set foldtext& fillchars& foldmethod& fdc& + bw! +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index a7479c6b18..b6386049bf 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -434,7 +434,7 @@ static const int included_patches[] = { // 521, // 520, // 519, - // 518, + 518, // 517, // 516, // 515, From 5ed2ab6d5327ed7c54edc9fa5eb1cfa447edbf2a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Jul 2017 02:40:25 +0200 Subject: [PATCH 11/22] vim-patch:8.0.0524 Problem: Folds are messed up when 'encodin' is "utf-8". Solution: Also set the fold character when it's not multi-byte. https://github.com/vim/vim/commit/8da1e6cedf839902e15987a98733ebd31b5f1b81 --- src/nvim/screen.c | 1 + src/nvim/testdir/test_display.vim | 10 ++++++++++ src/nvim/version.c | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/nvim/screen.c b/src/nvim/screen.c index c302ac695e..dd958eec80 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1927,6 +1927,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T ScreenLines[off + col] = 0x80; // avoid storing zero } else { ScreenLinesUC[off + col] = 0; + ScreenLines[off + col] = fill_fold; } col++; } else { diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim index 4253b56933..48b7a2318e 100644 --- a/src/nvim/testdir/test_display.vim +++ b/src/nvim/testdir/test_display.vim @@ -54,6 +54,16 @@ func! Test_display_foldtext_mbyte() \ " 14 \u2502", \ ] call assert_equal(expect, lines) + + set fillchars=fold:-,vert:\| + let lines=ScreenLines([1,3], winwidth(0)+1) + let expect=[ + \ " 1 |", + \ "+ +-- 12 lines: 2". repeat("-", 23). "|", + \ " 14 |", + \ ] + call assert_equal(expect, lines) + set foldtext& fillchars& foldmethod& fdc& bw! endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index b6386049bf..a1655f1caa 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -428,7 +428,7 @@ static const int included_patches[] = { // 527, // 526, // 525, - // 524, + 524, // 523, // 522, // 521, From e214cc2cdc5bd262ef0c4b20f1daf7647c490063 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 10 Aug 2017 04:11:35 +0200 Subject: [PATCH 12/22] oldtest: cannot `:set term` in Nvim --- src/nvim/testdir/test_display.vim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim index 48b7a2318e..0ed672d577 100644 --- a/src/nvim/testdir/test_display.vim +++ b/src/nvim/testdir/test_display.vim @@ -1,7 +1,9 @@ " Test for displaying stuff -if !has('gui_running') && has('unix') - set term=ansi -endif + +" Nvim: `:set term` is not supported. +" if !has('gui_running') && has('unix') +" set term=ansi +" endif source view_util.vim From cd5f9d638eb61dd364689f2f2fa645efe4e1b6a5 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 12 Aug 2017 18:22:47 +0200 Subject: [PATCH 13/22] vim-patch:8.0.0235 Problem: Memory leak detected when running tests for diff mode. Solution: Free p_extra_free. https://github.com/vim/vim/commit/b031c4ea04eb1e37a873fbb85e90d835aa1e2b1c --- src/nvim/screen.c | 21 +++++++++++---------- src/nvim/version.c | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/nvim/screen.c b/src/nvim/screen.c index dd958eec80..f8d519ab36 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2715,17 +2715,15 @@ win_line ( draw_state = WL_FOLD; if (fdc > 0) { // Draw the 'foldcolumn'. Allocate a buffer, "extra" may - // already be in used. + // already be in use. + xfree(p_extra_free); p_extra_free = xmalloc(12 + 1); - - if (p_extra_free != NULL) { - fill_foldcolumn(p_extra_free, wp, false, lnum); - n_extra = fdc; - p_extra_free[n_extra] = NUL; - p_extra = p_extra_free; - c_extra = NUL; - char_attr = win_hl_attr(wp, HLF_FC); - } + fill_foldcolumn(p_extra_free, wp, false, lnum); + n_extra = fdc; + p_extra_free[n_extra] = NUL; + p_extra = p_extra_free; + c_extra = NUL; + char_attr = win_hl_attr(wp, HLF_FC); } } @@ -3526,6 +3524,7 @@ win_line ( p = xmalloc(len + 1); memset(p, ' ', len); p[len] = NUL; + xfree(p_extra_free); p_extra_free = p; for (i = 0; i < tab_len; i++) { mb_char2bytes(lcs_tab2, p); @@ -3641,6 +3640,7 @@ win_line ( memset(p, ' ', n_extra); STRNCPY(p, p_extra + 1, STRLEN(p_extra) - 1); p[n_extra] = NUL; + xfree(p_extra_free); p_extra_free = p_extra = p; } else { n_extra = byte2cells(c) - 1; @@ -4314,6 +4314,7 @@ win_line ( cap_col = 0; } + xfree(p_extra_free); return row; } diff --git a/src/nvim/version.c b/src/nvim/version.c index a1655f1caa..f4984864f3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -717,7 +717,7 @@ static const int included_patches[] = { // 238, // 237, // 236, - // 235, + 235, // 234, // 233, // 232 NA From 809420233c591c81aede48679a42fce90e75bb6f Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Mon, 10 Jul 2017 09:37:54 +0200 Subject: [PATCH 14/22] tui: fix DECSCUSR logic #6997 Fix linuxvt cursor shape codes Fix konsole cursor_shapes (even when inside tmux) Do not trust old VTE terminal lies Closes #6978 Closes #7002 Closes #7049 --- src/nvim/tui/tui.c | 90 ++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 97a0398c80..b5af5b0333 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1256,7 +1256,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool teraterm = terminfo_is_term_family(term, "teraterm"); bool putty = terminfo_is_term_family(term, "putty"); bool screen = terminfo_is_term_family(term, "screen"); - bool tmux = terminfo_is_term_family(term, "tmux"); + bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); bool st = terminfo_is_term_family(term, "st"); bool gnome = terminfo_is_term_family(term, "gnome") || terminfo_is_term_family(term, "vte"); @@ -1270,7 +1270,6 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool mate_pretending_xterm = xterm && colorterm && strstr(colorterm, "mate-terminal"); bool true_xterm = xterm && !!xterm_version; - bool tmux_pretending_screen = screen && !!os_getenv("TMUX"); char *fix_normal = (char *)unibi_get_str(ut, unibi_cursor_normal); if (fix_normal) { @@ -1347,7 +1346,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // per the screen manual; 2017-04 terminfo.src lacks these. unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_"); unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\"); - } else if (terminfo_is_term_family(term, "tmux")) { + } else if (tmux) { unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_"); unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\"); } else if (terminfo_is_term_family(term, "interix")) { @@ -1408,12 +1407,11 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256_COLON); unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256_COLON); } else if (konsole || xterm || gnome || rxvt || st || putty - || linuxvt // Linux 4.8+ supports 256-colour SGR. - || mate_pretending_xterm || gnome_pretending_xterm - || tmux || tmux_pretending_screen - || (colorterm && strstr(colorterm, "256")) - || (term && strstr(term, "256")) - ) { + || linuxvt // Linux 4.8+ supports 256-colour SGR. + || mate_pretending_xterm || gnome_pretending_xterm + || tmux + || (colorterm && strstr(colorterm, "256")) + || (term && strstr(term, "256"))) { unibi_set_num(ut, unibi_max_colors, 256); unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256); unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256); @@ -1429,12 +1427,17 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, } } - // Dickey ncurses terminfo has included the Ss and Se capabilities, pioneered - // by tmux, since 2011-07-14. So adding them to terminal types, that do - // actually have such control sequences but lack the correct definitions in - // terminfo, is a fixup, not an augmentation. - data->unibi_ext.reset_cursor_style = unibi_find_ext_str(ut, "Se"); - data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss"); + // Some terminals can not currently be trusted to report if they support + // DECSCUSR or not. So we need to have a blacklist for when we should not + // trust the reported features. + if (!((vte_version != 0 && vte_version < 3900) || konsole)) { + // Dickey ncurses terminfo has included the Ss and Se capabilities, + // pioneered by tmux, since 2011-07-14. So adding them to terminal types, + // that do actually have such control sequences but lack the correct + // definitions in terminfo, is a fixup, not an augmentation. + data->unibi_ext.reset_cursor_style = unibi_find_ext_str(ut, "Se"); + data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss"); + } if (-1 == data->unibi_ext.set_cursor_style) { // The DECSCUSR sequence to change the cursor shape is widely // supported by several terminal types and should be in many @@ -1442,6 +1445,13 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // https://github.com/gnachman/iTerm2/pull/92 for more. // xterm even has an extended version that has a vertical bar. if (true_xterm // per xterm ctlseqs doco (since version 282) + // per MinTTY 0.4.3-1 release notes from 2009 + || putty + // per https://bugzilla.gnome.org/show_bug.cgi?id=720821 + || (vte_version >= 3900) + || tmux // per tmux manual page + // https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html + || screen || rxvt // per command.C // per analysis of VT100Terminal.m || iterm || iterm_pretending_xterm @@ -1454,50 +1464,34 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q"); if (-1 == data->unibi_ext.reset_cursor_style) { data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b[ q"); - } else if ( - // per MinTTY 0.4.3-1 release notes from 2009 - putty - // per https://bugzilla.gnome.org/show_bug.cgi?id=720821 - || (vte_version >= 3900) - // per tmux manual page and per - // https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html - || screen) { - // Since we use the xterm extension, we must map it to the unextended form - data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", - "\x1b[%?" - "%p1%{4}%>" "%t%p1%{2}%-" // a bit of a bodge for extension values - "%e%p1" // the conventional codes are just passed through - "%;%d q"); - if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); - } - unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, - "\x1b[ q"); } else if (linuxvt) { // Linux uses an idiosyncratic escape code to set the cursor shape and // does not support DECSCUSR. + // See http://linuxgazette.net/137/anonymous.html for more info data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", "\x1b[?" "%?" // The parameter passed to Ss is the DECSCUSR parameter, so the // terminal capability has to translate into the Linux idiosyncratic // parameter. - "%p1%{2}%<" "%t%{8}" // blink block - "%p1%{2}%=" "%t%{24}" // steady block - "%p1%{3}%=" "%t%{1}" // blink underline - "%p1%{4}%=" "%t%{17}" // steady underline - "%p1%{5}%=" "%t%{1}" // blink bar - "%p1%{6}%=" "%t%{17}" // steady bar - "%e%{0}" // anything else + // + // linuxvt only supports block and underline. It is also only + // possible to have a steady block (no steady underline) + "%p1%{2}%<" "%t%{8}" // blink block + "%e%p1%{2}%=" "%t%{112}" // steady block + "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block) + "%e%p1%{4}%=" "%t%{4}" // steady underline + "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline) + "%e%p1%{6}%=" "%t%{2}" // steady bar + "%e%{0}" // anything else "%;" "%dc"); if (-1 == data->unibi_ext.reset_cursor_style) { data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b[?c"); @@ -1507,17 +1501,17 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // nonce profile, which has side-effects on temporary font resizing. // In an ideal world, Konsole would just support DECSCUSR. data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", - "\x1b]50;CursorShape=%?" + TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?" "%p1%{3}%<" "%t%{0}" // block - "%e%p1%{4}%<" "%t%{2}" // underline + "%e%p1%{5}%<" "%t%{2}" // underline "%e%{1}" // everything else is bar "%;%d;BlinkingCursorEnabled=%?" "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special, "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag. - "%;%d\x07"); + "%;%d\x07")); if (-1 == data->unibi_ext.reset_cursor_style) { data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b]50;\x07"); From e6c528d9fc527d555a85ae12dc6cc8b74ab09e38 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 13 Aug 2017 10:01:39 -0400 Subject: [PATCH 15/22] travis: Move TSAN to last stage and allow failure TSAN build has been much less reliable lately, so it shouldn't hold up the other tests. --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45c2dcb832..2bab1635ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,9 +57,6 @@ jobs: env: > CLANG_SANITIZER=ASAN_UBSAN CMAKE_FLAGS="$CMAKE_FLAGS -DPREFER_LUA=ON" - - os: linux - compiler: clang-4.0 - env: CLANG_SANITIZER=TSAN - stage: normal builds os: linux compiler: gcc-5 @@ -79,12 +76,16 @@ jobs: - stage: lint os: linux env: CI_TARGET=lint - - stage: coverage + - stage: Flaky builds os: linux compiler: gcc-5 env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON" + - os: linux + compiler: clang-4.0 + env: CLANG_SANITIZER=TSAN allow_failures: - env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON" + - env: CLANG_SANITIZER=TSAN fast_finish: true before_install: ci/before_install.sh From d0cb175cab56da47fbd08e4b65ca02832a93bc38 Mon Sep 17 00:00:00 2001 From: Nikolai Aleksandrovich Pavlov Date: Sun, 13 Aug 2017 18:37:35 +0300 Subject: [PATCH 16/22] lua/executor: Fix crash when printing empty string (#7157) --- src/nvim/lua/executor.c | 2 +- test/functional/lua/overrides_spec.lua | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 9ec5bfb8ad..eb821f7831 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -519,7 +519,7 @@ static int nlua_print(lua_State *const lstate) } msg((char_u *)str + start); } - if (str[len - 1] == NUL) { // Last was newline + if (len && str[len - 1] == NUL) { // Last was newline msg((char_u *)""); } } diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua index 6e1d50071d..8ca5fe57ba 100644 --- a/test/functional/lua/overrides_spec.lua +++ b/test/functional/lua/overrides_spec.lua @@ -69,6 +69,13 @@ describe('print', function() eq('\nT^@', redir_exec([[lua print("T\0")]])) eq('\nT\n', redir_exec([[lua print("T\n")]])) end) + it('prints empty strings correctly', function() + -- Regression: first test used to crash + eq('', redir_exec('lua print("")')) + eq('\n def', redir_exec('lua print("", "def")')) + eq('\nabc ', redir_exec('lua print("abc", "")')) + eq('\nabc def', redir_exec('lua print("abc", "", "def")')) + end) end) describe('debug.debug', function() From c4e214a99cf0dfc53c1e903178c08fad9cb05354 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 13 Aug 2017 18:46:09 +0200 Subject: [PATCH 17/22] io: more guards against NULL filename (#7159) References ac055d677aa9 References #4370 --- src/nvim/main.c | 1 + src/nvim/memfile.c | 1 + src/nvim/memline.c | 2 ++ src/nvim/os/fs.c | 5 ++++- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index a46c1a58f8..3f828d7be9 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1825,6 +1825,7 @@ static int process_env(char *env, bool is_viminit) /// os_fileinfo_link() respectively for extra security. static bool file_owned(const char *fname) { + assert(fname != NULL); uid_t uid = getuid(); FileInfo file_info; bool file_owned = os_fileinfo(fname, &file_info) diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 9429703620..4428dd42aa 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -895,6 +895,7 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags) { // fname cannot be NameBuff, because it must have been allocated. mf_set_fnames(mfp, fname); + assert(mfp->mf_fname != NULL); /// Extra security check: When creating a swap file it really shouldn't /// exist yet. If there is a symbolic link, this is most likely an attack. diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 55e7e01825..f28a9e60f4 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1460,6 +1460,7 @@ static int process_still_running; */ static time_t swapfile_info(char_u *fname) { + assert(fname != NULL); int fd; struct block0 b0; time_t x = (time_t)0; @@ -3135,6 +3136,7 @@ attention_message ( char_u *fname /* swap file name */ ) { + assert(buf->b_fname != NULL); time_t x, sx; char *p; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 6ac9d682d7..78627f8703 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -859,8 +859,11 @@ bool os_fileinfo(const char *path, FileInfo *file_info) /// @param[out] file_info Pointer to a FileInfo to put the information in. /// @return `true` on success, `false` for failure. bool os_fileinfo_link(const char *path, FileInfo *file_info) - FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_ARG(2) { + if (path == NULL) { + return false; + } uv_fs_t request; int result = uv_fs_lstat(&fs_loop, &request, path, NULL); file_info->stat = request.statbuf; From 583b68f5a94f362c44ff29c62909969e6908438b Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 11:06:16 +0800 Subject: [PATCH 18/22] vim-patch:8.0.0101 Problem: Some options are not strictly checked. Solution: Add flags for strickter checks. https://github.com/vim/vim/commit/031cb743ae154cfb727a9b7787bdcb61202ff1c8 --- src/nvim/option.c | 13 +++++++------ src/nvim/options.lua | 2 ++ src/nvim/version.c | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/nvim/option.c b/src/nvim/option.c index 74250e83e6..ae1a2b1b24 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3172,17 +3172,18 @@ did_set_string_option ( } else { // Options that are a list of flags. p = NULL; - if (varp == &p_ww) + if (varp == &p_ww) { // 'whichwrap' p = (char_u *)WW_ALL; - if (varp == &p_shm) + } + if (varp == &p_shm) { // 'shortmess' p = (char_u *)SHM_ALL; - else if (varp == &(p_cpo)) + } else if (varp == &(p_cpo)) { // 'cpoptions' p = (char_u *)CPO_VI; - else if (varp == &(curbuf->b_p_fo)) + } else if (varp == &(curbuf->b_p_fo)) { // 'formatoptions' p = (char_u *)FO_ALL; - else if (varp == &curwin->w_p_cocu) + } else if (varp == &curwin->w_p_cocu) { // 'concealcursor' p = (char_u *)COCU_ALL; - else if (varp == &p_mouse) { + } else if (varp == &p_mouse) { // 'mouse' p = (char_u *)MOUSE_ALL; } if (p != NULL) { diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 103227f6b5..757fac9465 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -575,6 +575,7 @@ return { full_name='dictionary', abbreviation='dict', type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, + normal_fname_chars=true, vi_def=true, expand=true, varname='p_dict', @@ -1750,6 +1751,7 @@ return { { full_name='printexpr', abbreviation='pexpr', type='string', scope={'global'}, + secure=true, vi_def=true, varname='p_pexpr', defaults={if_true={vi=""}} diff --git a/src/nvim/version.c b/src/nvim/version.c index d4f9c0232f..feb69cae52 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -851,7 +851,7 @@ static const int included_patches[] = { // 104, // 103 NA // 102, - // 101, + 101, 100, 99, // 98 NA From d2eba872fb80ec9ace3a244aa706e55c82a48e83 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 11:06:16 +0800 Subject: [PATCH 19/22] vim-patch:8.0.0101 Problem: Some options are not strictly checked. Solution: Add flags for strickter checks. https://github.com/vim/vim/commit/031cb743ae154cfb727a9b7787bdcb61202ff1c8 --- src/nvim/option.c | 13 +++++++------ src/nvim/options.lua | 2 ++ src/nvim/version.c | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/nvim/option.c b/src/nvim/option.c index 74250e83e6..ae1a2b1b24 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3172,17 +3172,18 @@ did_set_string_option ( } else { // Options that are a list of flags. p = NULL; - if (varp == &p_ww) + if (varp == &p_ww) { // 'whichwrap' p = (char_u *)WW_ALL; - if (varp == &p_shm) + } + if (varp == &p_shm) { // 'shortmess' p = (char_u *)SHM_ALL; - else if (varp == &(p_cpo)) + } else if (varp == &(p_cpo)) { // 'cpoptions' p = (char_u *)CPO_VI; - else if (varp == &(curbuf->b_p_fo)) + } else if (varp == &(curbuf->b_p_fo)) { // 'formatoptions' p = (char_u *)FO_ALL; - else if (varp == &curwin->w_p_cocu) + } else if (varp == &curwin->w_p_cocu) { // 'concealcursor' p = (char_u *)COCU_ALL; - else if (varp == &p_mouse) { + } else if (varp == &p_mouse) { // 'mouse' p = (char_u *)MOUSE_ALL; } if (p != NULL) { diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 103227f6b5..757fac9465 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -575,6 +575,7 @@ return { full_name='dictionary', abbreviation='dict', type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, + normal_fname_chars=true, vi_def=true, expand=true, varname='p_dict', @@ -1750,6 +1751,7 @@ return { { full_name='printexpr', abbreviation='pexpr', type='string', scope={'global'}, + secure=true, vi_def=true, varname='p_pexpr', defaults={if_true={vi=""}} diff --git a/src/nvim/version.c b/src/nvim/version.c index d4f9c0232f..feb69cae52 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -851,7 +851,7 @@ static const int included_patches[] = { // 104, // 103 NA // 102, - // 101, + 101, 100, 99, // 98 NA From cd13c24427a3191c7383b76a0bf9467bee2736e3 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 11:54:40 +0800 Subject: [PATCH 20/22] vim-patch:8.0.0102 Problem: Cannot set 'dictionary' to a path. Solution: Allow for slash and backslash. Add a test (partly by Daisuke Suzuki, closes vim/vim#1279, closes vim/vim#1284) https://github.com/vim/vim/commit/7554da4033498c4da0af3cde542c3e87e9097b73 --- src/nvim/generators/gen_options.lua | 1 + src/nvim/option.c | 13 ++++++++----- src/nvim/options.lua | 4 ++-- src/nvim/testdir/test_options.vim | 15 +++++++++++++++ src/nvim/version.c | 2 +- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index ca0134043c..36562c0be9 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -74,6 +74,7 @@ local get_flags = function(o) {'gettext'}, {'noglob'}, {'normal_fname_chars', 'P_NFNAME'}, + {'normal_dname_chars', 'P_NDNAME'}, {'pri_mkrc'}, {'deny_in_modelines', 'P_NO_ML'}, {'deny_duplicates', 'P_NODUP'}, diff --git a/src/nvim/option.c b/src/nvim/option.c index ae1a2b1b24..6ed4989a4c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -242,6 +242,7 @@ typedef struct vimoption { #define P_NO_DEF_EXP 0x8000000U ///< Do not expand default value. #define P_RWINONLY 0x10000000U ///< only redraw current window +#define P_NDNAME 0x20000000U ///< only normal dir name chars allowed #define HIGHLIGHT_INIT \ "8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \ @@ -2454,11 +2455,13 @@ did_set_string_option ( if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) { errmsg = e_secure; - } else if ((options[opt_idx].flags & P_NFNAME) - && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL) { - // Check for a "normal" file name in some options. Disallow a path - // separator (slash and/or backslash), wildcards and characters that are - // often illegal in a file name. + } else if ((((options[opt_idx].flags & P_NFNAME) + && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL)) + || ((options[opt_idx].flags & P_NDNAME) + && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) { + // Check for a "normal" directory or file name in some options. Disallow a + // path separator (slash and/or backslash), wildcards and characters that + // are often illegal in a file name. errmsg = e_invarg; } /* 'backupcopy' */ diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 757fac9465..cce9e10409 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -7,7 +7,7 @@ -- enable_if=nil, -- defaults={condition=nil, if_true={vi=224, vim=0}, if_false=nil}, -- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil, --- pri_mkrc=nil, deny_in_modelines=nil, +-- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil, -- expand=nil, nodefault=nil, no_mkrc=nil, vi_def=true, vim=true, -- alloced=nil, -- save_pv_indir=nil, @@ -575,7 +575,7 @@ return { full_name='dictionary', abbreviation='dict', type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, - normal_fname_chars=true, + normal_dname_chars=true, vi_def=true, expand=true, varname='p_dict', diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 2ffe63787b..ea020d9ca0 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -103,3 +103,18 @@ func Test_keymap_valid() call assert_fails(":set kmp=trunc\x00name", "E544:") call assert_fails(":set kmp=trunc\x00name", "trunc") endfunc + +func Test_dictionary() + " Check that it's possible to set the option. + set dictionary=/usr/share/dict/words + call assert_equal('/usr/share/dict/words', &dictionary) + set dictionary=/usr/share/dict/words,/and/there + call assert_equal('/usr/share/dict/words,/and/there', &dictionary) + set dictionary=/usr/share/dict\ words + call assert_equal('/usr/share/dict words', &dictionary) + + " Check rejecting weird characters. + call assert_fails("set dictionary=/not&there", "E474:") + call assert_fails("set dictionary=/not>there", "E474:") + call assert_fails("set dictionary=/not.*there", "E474:") +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index feb69cae52..890587b307 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -850,7 +850,7 @@ static const int included_patches[] = { // 105 NA // 104, // 103 NA - // 102, + 102, 101, 100, 99, From 25a3f77f614260c945c32a56607b36a603b914be Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 13:21:07 +0800 Subject: [PATCH 21/22] vim-patch:8.0.0106 Problem: Cannot use a semicolon in 'backupext'. (Jeff) Solution: Allow for a few more characters when "secure" isn't set. https://github.com/vim/vim/commit/0945eaface83e78138fbd40f95cc590bab0e8c86 --- src/nvim/option.c | 7 ++++--- src/nvim/version.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nvim/option.c b/src/nvim/option.c index 6ed4989a4c..e989f700ae 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2455,13 +2455,14 @@ did_set_string_option ( if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) { errmsg = e_secure; - } else if ((((options[opt_idx].flags & P_NFNAME) - && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL)) + } else if (((options[opt_idx].flags & P_NFNAME) + && vim_strpbrk(*varp, (char_u *)(secure + ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL) || ((options[opt_idx].flags & P_NDNAME) && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) { // Check for a "normal" directory or file name in some options. Disallow a // path separator (slash and/or backslash), wildcards and characters that - // are often illegal in a file name. + // are often illegal in a file name. Be more permissive if "secure" is off. errmsg = e_invarg; } /* 'backupcopy' */ diff --git a/src/nvim/version.c b/src/nvim/version.c index 06482bf490..f6a9418dbf 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -846,7 +846,7 @@ static const int included_patches[] = { // 109 NA // 108 NA // 107 NA - // 106, + 106, // 105 NA 104, // 103 NA From 3a1c33a6c3ad5074bfc442507282a438726f1b58 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 13:21:07 +0800 Subject: [PATCH 22/22] vim-patch:8.0.0106 Problem: Cannot use a semicolon in 'backupext'. (Jeff) Solution: Allow for a few more characters when "secure" isn't set. https://github.com/vim/vim/commit/0945eaface83e78138fbd40f95cc590bab0e8c86 --- src/nvim/option.c | 7 ++++--- src/nvim/version.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nvim/option.c b/src/nvim/option.c index 6ed4989a4c..e989f700ae 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2455,13 +2455,14 @@ did_set_string_option ( if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) { errmsg = e_secure; - } else if ((((options[opt_idx].flags & P_NFNAME) - && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL)) + } else if (((options[opt_idx].flags & P_NFNAME) + && vim_strpbrk(*varp, (char_u *)(secure + ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL) || ((options[opt_idx].flags & P_NDNAME) && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) { // Check for a "normal" directory or file name in some options. Disallow a // path separator (slash and/or backslash), wildcards and characters that - // are often illegal in a file name. + // are often illegal in a file name. Be more permissive if "secure" is off. errmsg = e_invarg; } /* 'backupcopy' */ diff --git a/src/nvim/version.c b/src/nvim/version.c index 06482bf490..f6a9418dbf 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -846,7 +846,7 @@ static const int included_patches[] = { // 109 NA // 108 NA // 107 NA - // 106, + 106, // 105 NA 104, // 103 NA