From 39b431b3ed5d5e7c9236655a874863489567174a Mon Sep 17 00:00:00 2001 From: ckelsel Date: Fri, 30 Jun 2017 20:18:41 +0800 Subject: [PATCH 01/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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 e6d4b7686ca31d44de854bdfd417da083fea5fc4 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 27 Sep 2017 08:20:43 -0400 Subject: [PATCH 18/43] vim-patch.sh: Exclude testdir/ files from src/ file pruning Without the testdir/ exclusion, all directories under src/ were affected by this cleanup. However, testdir/ has its own pruning that happens later. --- scripts/vim-patch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh index 5ebb6a38b3..4f6bb40488 100755 --- a/scripts/vim-patch.sh +++ b/scripts/vim-patch.sh @@ -133,7 +133,7 @@ preprocess_patch() { # Remove *.proto, Make*, gui_*, some if_* local na_src='proto\|Make*\|gui_*\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv' - 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%('${na_src}'\)@norm! d/\v(^diff)|%$ ' +w +q "$file" + 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%(testdir/\)\@ Date: Wed, 27 Sep 2017 08:27:31 -0400 Subject: [PATCH 19/43] oldtest: Run test_mksession_utf8 tests --- src/nvim/testdir/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 9133bfc0a2..38caa8815d 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -59,6 +59,7 @@ NEW_TESTS ?= \ test_matchadd_conceal.res \ test_matchadd_conceal_utf8.res \ test_mksession.res \ + test_mksession_utf8.res \ test_nested_function.res \ test_normal.res \ test_quickfix.res \ From ba7277cfb4e2556f246446d06b53f3427f28130f Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Wed, 26 Jul 2017 23:28:26 +0200 Subject: [PATCH 20/43] Adds nvim_get_hl_by_name/by_id ...in order to retrieve highlights. Added test/functional/api/highlight_spec.lua HL_NORMAL is not really a good name, since it's more like an empty attribute than the normal's one. If one pays attention, syn_cterm_attr2entry is never called with attr=0 because it's always special cased before. I suggest in subsequent PRs we remove the ATTR_OFF and just insert an EMPTY ATTR/RESET_ATTR/UNINITIALIZED for id 0. --- src/nvim/api/ui.c | 34 +----- src/nvim/api/vim.c | 37 ++++++ src/nvim/syntax.c | 22 ++-- src/nvim/tui/tui.c | 6 +- src/nvim/ugrid.c | 4 +- src/nvim/ugrid.h | 2 - src/nvim/ui.c | 149 +++++++++++++++++++------ src/nvim/ui.h | 3 + test/functional/api/highlight_spec.lua | 54 +++++++++ 9 files changed, 220 insertions(+), 91 deletions(-) create mode 100644 test/functional/api/highlight_spec.lua diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index bbbd5ab2dc..afbee09c1c 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -242,39 +242,7 @@ static void push_call(UI *ui, char *name, Array args) static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) { Array args = ARRAY_DICT_INIT; - Dictionary hl = ARRAY_DICT_INIT; - - if (attrs.bold) { - PUT(hl, "bold", BOOLEAN_OBJ(true)); - } - - if (attrs.underline) { - PUT(hl, "underline", BOOLEAN_OBJ(true)); - } - - if (attrs.undercurl) { - PUT(hl, "undercurl", BOOLEAN_OBJ(true)); - } - - if (attrs.italic) { - PUT(hl, "italic", BOOLEAN_OBJ(true)); - } - - if (attrs.reverse) { - PUT(hl, "reverse", BOOLEAN_OBJ(true)); - } - - if (attrs.foreground != -1) { - PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground)); - } - - if (attrs.background != -1) { - PUT(hl, "background", INTEGER_OBJ(attrs.background)); - } - - if (attrs.special != -1) { - PUT(hl, "special", INTEGER_OBJ(attrs.special)); - } + Dictionary hl = hlattrs2dict(attrs); ADD(args, DICTIONARY_OBJ(hl)); push_call(ui, "highlight_set", args); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index ab893a4c0f..0459d9235d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -33,6 +33,7 @@ #include "nvim/syntax.h" #include "nvim/getchar.h" #include "nvim/os/input.h" +#include "nvim/ui.h" #define LINE_BUFFER_SIZE 4096 @@ -55,6 +56,42 @@ void nvim_command(String command, Error *err) try_end(err); } +/// Retrieves highlight description from its name +/// +/// @param name Highlight group name +/// @return a highlight description e.g. {'bold': true, 'bg': 123, 'fg': 42} +/// @see nvim_get_hl_by_id +Dictionary nvim_get_hl_by_name(String name, Error *err) + FUNC_API_SINCE(3) +{ + Dictionary result = ARRAY_DICT_INIT; + int id = syn_name2id((const char_u *)name.data); + + if (id == 0) { + api_set_error(err, kErrorTypeException, "Invalid highlight name %s", + name.data); + return result; + } + result = nvim_get_hl_by_id(id, err); + return result; +} + +/// Retrieves highlight description from its id +/// +/// @param hl_id highlight id as returned by hlID() +/// @see nvim_get_hl_by_name +Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) + FUNC_API_SINCE(3) +{ + Dictionary dic = ARRAY_DICT_INIT; + if (syn_get_final_id((int)hl_id) == 0) { + api_set_error(err, kErrorTypeException, "Invalid highlight id %d", hl_id); + return dic; + } + int attrcode = syn_id2attr((int)hl_id); + return get_attr_by_id(attrcode, err); +} + /// Passes input keys to Nvim. /// On VimL error: Does not fail, but updates v:errmsg. /// diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 65c0e2464a..fdb7196fc4 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -42,6 +42,7 @@ #include "nvim/ui.h" #include "nvim/os/os.h" #include "nvim/os/time.h" +#include "nvim/api/private/helpers.h" static bool did_syntax_onoff = false; @@ -6622,7 +6623,6 @@ do_highlight(char_u *line, int forceit, int init) { syn_unadd_group(); } else { if (is_normal_group) { - HL_TABLE()[idx].sg_attr = 0; // Need to update all groups, because they might be using "bg" and/or // "fg", which have been changed now. highlight_attr_set_all(); @@ -6826,7 +6826,7 @@ int hl_combine_attr(int char_attr, int prim_attr) // Copy all attributes from char_aep to the new entry new_en = *char_aep; } else { - memset(&new_en, 0, sizeof(new_en)); + new_en = (attrentry_T)ATTRENTRY_INIT; } spell_aep = syn_cterm_attr2entry(prim_attr); @@ -6859,6 +6859,7 @@ int hl_combine_attr(int char_attr, int prim_attr) /// \note this function does not apply exclusively to cterm attr contrary /// to what its name implies +/// \warn don't call it with attr 0 (i.e., the null attribute) attrentry_T *syn_cterm_attr2entry(int attr) { attr -= ATTR_OFF; @@ -7103,22 +7104,15 @@ syn_list_header(int did_header, int outlen, int id) return newline; } -/* - * Set the attribute numbers for a highlight group. - * Called after one of the attributes has changed. - */ -static void -set_hl_attr ( - int idx /* index in array */ -) +/// Set the attribute numbers for a highlight group. +/// Called after one of the attributes has changed. +/// @param idx corrected highlight index +static void +set_hl_attr(int idx) { attrentry_T at_en = ATTRENTRY_INIT; struct hl_group *sgp = HL_TABLE() + idx; - // The "Normal" group doesn't need an attribute number - if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) { - return; - } at_en.cterm_ae_attr = sgp->sg_cterm; at_en.cterm_fg_color = sgp->sg_cterm_fg; diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 256772489d..8e0e905bcd 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -288,7 +288,7 @@ static void terminfo_stop(UI *ui) static void tui_terminal_start(UI *ui) { TUIData *data = ui->data; - data->print_attrs = EMPTY_ATTRS; + data->print_attrs = HLATTRS_INIT; ugrid_init(&data->grid); terminfo_start(ui); update_size(ui); @@ -628,7 +628,7 @@ static void clear_region(UI *ui, int top, int bot, int left, int right) if (grid->bg == -1 && right == ui->width -1) { // Background is set to the default color and the right edge matches the // screen end, try to use terminal codes for clearing the requested area. - HlAttrs clear_attrs = EMPTY_ATTRS; + HlAttrs clear_attrs = HLATTRS_INIT; clear_attrs.foreground = grid->fg; clear_attrs.background = grid->bg; update_attrs(ui, clear_attrs); @@ -926,7 +926,7 @@ static void tui_scroll(UI *ui, Integer count) cursor_goto(ui, grid->top, grid->left); // also set default color attributes or some terminals can become funny if (scroll_clears_to_current_colour) { - HlAttrs clear_attrs = EMPTY_ATTRS; + HlAttrs clear_attrs = HLATTRS_INIT; clear_attrs.foreground = grid->fg; clear_attrs.background = grid->bg; update_attrs(ui, clear_attrs); diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c index 7a0a16687e..2b5e96ee60 100644 --- a/src/nvim/ugrid.c +++ b/src/nvim/ugrid.c @@ -16,7 +16,7 @@ void ugrid_init(UGrid *grid) { - grid->attrs = EMPTY_ATTRS; + grid->attrs = HLATTRS_INIT; grid->fg = grid->bg = -1; grid->cells = NULL; } @@ -118,7 +118,7 @@ UCell *ugrid_put(UGrid *grid, uint8_t *text, size_t size) static void clear_region(UGrid *grid, int top, int bot, int left, int right) { - HlAttrs clear_attrs = EMPTY_ATTRS; + HlAttrs clear_attrs = HLATTRS_INIT; clear_attrs.foreground = grid->fg; clear_attrs.background = grid->bg; UGRID_FOREACH_CELL(grid, top, bot, left, right, { diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h index 268362bf1b..1cf047502d 100644 --- a/src/nvim/ugrid.h +++ b/src/nvim/ugrid.h @@ -21,8 +21,6 @@ struct ugrid { UCell **cells; }; -#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 }) - #define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \ do { \ for (int row = top; row <= bot; row++) { \ diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 01d3604159..184ae56cf2 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -166,6 +166,115 @@ void ui_event(char *name, Array args) } } +/// Retrieves attribute description from its id +/// +/// @param attr_id attribute id +Dictionary get_attr_by_id(Integer attr_id, Error *err) +{ + HlAttrs attrs = HLATTRS_INIT; + Dictionary dic = ARRAY_DICT_INIT; + + if (attr_id == 0) { + goto end; + } + + attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); + if (!aep) { + api_set_error(err, kErrorTypeException, + "Invalid attribute id %d", attr_id); + return dic; + } + + attrs = attrentry2hlattrs(aep, p_tgc); + +end: + return hlattrs2dict(attrs); +} + + +/// Converts an attrentry_T into an HlAttrs +/// +/// @param[in] aep data to convert +/// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*' +HlAttrs attrentry2hlattrs(const attrentry_T *aep, bool use_rgb) +{ + assert(aep); + + HlAttrs attrs = HLATTRS_INIT; + int mask = 0; + + mask = use_rgb ? aep->rgb_ae_attr : aep->cterm_ae_attr; + + attrs.bold = mask & HL_BOLD; + attrs.underline = mask & HL_UNDERLINE; + attrs.undercurl = mask & HL_UNDERCURL; + attrs.italic = mask & HL_ITALIC; + attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT); + + if (use_rgb) { + if (aep->rgb_fg_color != -1) { + attrs.foreground = aep->rgb_fg_color; + } + + if (aep->rgb_bg_color != -1) { + attrs.background = aep->rgb_bg_color; + } + + if (aep->rgb_sp_color != -1) { + attrs.special = aep->rgb_sp_color; + } + } else { + if (cterm_normal_fg_color != aep->cterm_fg_color) { + attrs.foreground = aep->cterm_fg_color - 1; + } + + if (cterm_normal_bg_color != aep->cterm_bg_color) { + attrs.background = aep->cterm_bg_color - 1; + } + } + + return attrs; +} + +Dictionary hlattrs2dict(HlAttrs attrs) +{ + Dictionary hl = ARRAY_DICT_INIT; + + if (attrs.bold) { + PUT(hl, "bold", BOOLEAN_OBJ(true)); + } + + if (attrs.underline) { + PUT(hl, "underline", BOOLEAN_OBJ(true)); + } + + if (attrs.undercurl) { + PUT(hl, "undercurl", BOOLEAN_OBJ(true)); + } + + if (attrs.italic) { + PUT(hl, "italic", BOOLEAN_OBJ(true)); + } + + if (attrs.reverse) { + PUT(hl, "reverse", BOOLEAN_OBJ(true)); + } + + if (attrs.foreground != -1) { + PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground)); + } + + if (attrs.background != -1) { + PUT(hl, "background", INTEGER_OBJ(attrs.background)); + } + + if (attrs.special != -1) { + PUT(hl, "special", INTEGER_OBJ(attrs.special)); + } + + return hl; +} + void ui_refresh(void) { if (!ui_active()) { @@ -405,54 +514,20 @@ void ui_flush(void) static void set_highlight_args(int attr_code) { - HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1, -1 }; + HlAttrs rgb_attrs = HLATTRS_INIT; HlAttrs cterm_attrs = rgb_attrs; if (attr_code == HL_NORMAL) { goto end; } - - int rgb_mask = 0; - int cterm_mask = 0; attrentry_T *aep = syn_cterm_attr2entry(attr_code); if (!aep) { goto end; } - rgb_mask = aep->rgb_ae_attr; - cterm_mask = aep->cterm_ae_attr; - - rgb_attrs.bold = rgb_mask & HL_BOLD; - rgb_attrs.underline = rgb_mask & HL_UNDERLINE; - rgb_attrs.undercurl = rgb_mask & HL_UNDERCURL; - rgb_attrs.italic = rgb_mask & HL_ITALIC; - rgb_attrs.reverse = rgb_mask & (HL_INVERSE | HL_STANDOUT); - cterm_attrs.bold = cterm_mask & HL_BOLD; - cterm_attrs.underline = cterm_mask & HL_UNDERLINE; - cterm_attrs.undercurl = cterm_mask & HL_UNDERCURL; - cterm_attrs.italic = cterm_mask & HL_ITALIC; - cterm_attrs.reverse = cterm_mask & (HL_INVERSE | HL_STANDOUT); - - if (aep->rgb_fg_color != normal_fg) { - rgb_attrs.foreground = aep->rgb_fg_color; - } - - if (aep->rgb_bg_color != normal_bg) { - rgb_attrs.background = aep->rgb_bg_color; - } - - if (aep->rgb_sp_color != normal_sp) { - rgb_attrs.special = aep->rgb_sp_color; - } - - if (cterm_normal_fg_color != aep->cterm_fg_color) { - cterm_attrs.foreground = aep->cterm_fg_color - 1; - } - - if (cterm_normal_bg_color != aep->cterm_bg_color) { - cterm_attrs.background = aep->cterm_bg_color - 1; - } + rgb_attrs = attrentry2hlattrs(aep, true); + cterm_attrs = attrentry2hlattrs(aep, false); end: UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs)); diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 064f77fee1..f1ea0716e6 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -21,6 +21,9 @@ typedef struct { int foreground, background, special; } HlAttrs; +#define HLATTRS_INIT \ + ((HlAttrs){ false, false, false, false, false, -1, -1, -1 }) + typedef struct ui_t UI; struct ui_t { diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua new file mode 100644 index 0000000000..1aacfaed03 --- /dev/null +++ b/test/functional/api/highlight_spec.lua @@ -0,0 +1,54 @@ + +local helpers = require('test.functional.helpers')(after_each) +local clear, nvim = helpers.clear, helpers.nvim +local Screen = require('test.functional.ui.screen') +local eq, eval = helpers.eq, helpers.eval +local command = helpers.command +local ok = helpers.ok +local meths = helpers.meths + + +describe('highlight api', function() + + before_each(function() + clear('--cmd', 'set termguicolors') + end) + + it("nvim_get_hl_by_id", function() + local expected_hl = { background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Blue + } + + command('hi NewHighlight guifg=red guibg=yellow guisp=blue') + + local hl_id = eval("hlID('NewHighlight')") + eq(expected_hl, nvim("get_hl_by_id", hl_id)) + + -- assume there is no hl with 30000 + local err, emsg = pcall(meths.get_hl_by_id, 30000) + eq(false, err) + ok(string.find(emsg, 'Invalid highlight id') ~= nil) + end) + + it("nvim_get_hl_by_name", function() + local expected_hl = { background = Screen.colors.Yellow, + foreground = Screen.colors.Red } + + -- test "Normal" hl defaults + eq({}, nvim("get_hl_by_name", 'Normal')) + + command('hi NewHighlight guifg=red guibg=yellow') + eq(expected_hl, nvim("get_hl_by_name", 'NewHighlight')) + + command('hi Normal guifg=red guibg=yellow') + eq(expected_hl, nvim("get_hl_by_name", 'Normal')) + local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight') + eq(false, err) + ok(string.find(emsg, 'Invalid highlight name') ~= nil) + end) + + + +end) + From e3a2cca3878f44252eccdc1918cc8854145de860 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Sun, 27 Aug 2017 00:33:36 +0200 Subject: [PATCH 21/43] Increased test coverage for RGB and cterm --- src/nvim/api/vim.c | 4 +-- src/nvim/syntax.c | 26 +++++++++++++++ src/nvim/ui.c | 25 --------------- test/functional/api/highlight_spec.lua | 44 +++++++++++++++----------- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0459d9235d..bf3e4bc6a0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -78,7 +78,7 @@ Dictionary nvim_get_hl_by_name(String name, Error *err) /// Retrieves highlight description from its id /// -/// @param hl_id highlight id as returned by hlID() +/// @param hl_id highlight id as returned by |hlID()| /// @see nvim_get_hl_by_name Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) FUNC_API_SINCE(3) @@ -89,7 +89,7 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) return dic; } int attrcode = syn_id2attr((int)hl_id); - return get_attr_by_id(attrcode, err); + return hl_get_attr_by_id(attrcode, err); } /// Passes input keys to Nvim. diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index fdb7196fc4..2f48cc8757 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -8221,6 +8221,32 @@ RgbValue name_to_color(const uint8_t *name) return -1; } +/// Retrieves attribute description from its id +/// +/// @param attr_id attribute id +Dictionary hl_get_attr_by_id(Integer attr_id, Error *err) +{ + HlAttrs attrs = HLATTRS_INIT; + Dictionary dic = ARRAY_DICT_INIT; + + if (attr_id == 0) { + goto end; + } + + attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); + if (!aep) { + api_set_error(err, kErrorTypeException, + "Invalid attribute id %d", attr_id); + return dic; + } + + attrs = attrentry2hlattrs(aep, p_tgc); + +end: + return hlattrs2dict(attrs); +} + + /************************************** * End of Highlighting stuff * **************************************/ diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 184ae56cf2..afe7a51d43 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -166,31 +166,6 @@ void ui_event(char *name, Array args) } } -/// Retrieves attribute description from its id -/// -/// @param attr_id attribute id -Dictionary get_attr_by_id(Integer attr_id, Error *err) -{ - HlAttrs attrs = HLATTRS_INIT; - Dictionary dic = ARRAY_DICT_INIT; - - if (attr_id == 0) { - goto end; - } - - attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); - if (!aep) { - api_set_error(err, kErrorTypeException, - "Invalid attribute id %d", attr_id); - return dic; - } - - attrs = attrentry2hlattrs(aep, p_tgc); - -end: - return hlattrs2dict(attrs); -} - /// Converts an attrentry_T into an HlAttrs /// diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index 1aacfaed03..a5d3871d13 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -8,47 +8,53 @@ local ok = helpers.ok local meths = helpers.meths -describe('highlight api', function() +describe('highlight api',function() + local expected_rgb = { background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Blue, + bold = true, + } + + local expected_cterm = { background = 10, + underline = true, + } before_each(function() - clear('--cmd', 'set termguicolors') + clear() + command("hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold") end) it("nvim_get_hl_by_id", function() - local expected_hl = { background = Screen.colors.Yellow, - foreground = Screen.colors.Red, - special = Screen.colors.Blue - } - - command('hi NewHighlight guifg=red guibg=yellow guisp=blue') - local hl_id = eval("hlID('NewHighlight')") - eq(expected_hl, nvim("get_hl_by_id", hl_id)) - -- assume there is no hl with 30000 + eq(expected_cterm, nvim("get_hl_by_id", hl_id)) + + command('set termguicolors') + hl_id = eval("hlID('NewHighlight')") + eq(expected_rgb, nvim("get_hl_by_id", hl_id)) + + -- assume there is no hl with id 30000 local err, emsg = pcall(meths.get_hl_by_id, 30000) eq(false, err) ok(string.find(emsg, 'Invalid highlight id') ~= nil) end) it("nvim_get_hl_by_name", function() - local expected_hl = { background = Screen.colors.Yellow, + local expected_normal = { background = Screen.colors.Yellow, foreground = Screen.colors.Red } -- test "Normal" hl defaults eq({}, nvim("get_hl_by_name", 'Normal')) - command('hi NewHighlight guifg=red guibg=yellow') - eq(expected_hl, nvim("get_hl_by_name", 'NewHighlight')) + eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight')) + command('set termguicolors') + eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight')) command('hi Normal guifg=red guibg=yellow') - eq(expected_hl, nvim("get_hl_by_name", 'Normal')) + eq(expected_normal, nvim("get_hl_by_name", 'Normal')) + local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight') eq(false, err) ok(string.find(emsg, 'Invalid highlight name') ~= nil) end) - - - end) - From 3a006486397d611234abd9b429bce0b44d6b7747 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Sun, 3 Sep 2017 05:25:57 +0200 Subject: [PATCH 22/43] Changed prototypes to accept a boolean "rgb" --- src/nvim/api/vim.c | 10 ++++++---- src/nvim/syntax.c | 4 ++-- test/functional/api/highlight_spec.lua | 20 +++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index bf3e4bc6a0..0c3c497533 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -59,9 +59,10 @@ void nvim_command(String command, Error *err) /// Retrieves highlight description from its name /// /// @param name Highlight group name +/// @param rgb True to export GUI values /// @return a highlight description e.g. {'bold': true, 'bg': 123, 'fg': 42} /// @see nvim_get_hl_by_id -Dictionary nvim_get_hl_by_name(String name, Error *err) +Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Error *err) FUNC_API_SINCE(3) { Dictionary result = ARRAY_DICT_INIT; @@ -72,15 +73,16 @@ Dictionary nvim_get_hl_by_name(String name, Error *err) name.data); return result; } - result = nvim_get_hl_by_id(id, err); + result = nvim_get_hl_by_id(id, rgb, err); return result; } /// Retrieves highlight description from its id /// /// @param hl_id highlight id as returned by |hlID()| +/// @param rgb True to export GUI values /// @see nvim_get_hl_by_name -Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) +Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Error *err) FUNC_API_SINCE(3) { Dictionary dic = ARRAY_DICT_INIT; @@ -89,7 +91,7 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) return dic; } int attrcode = syn_id2attr((int)hl_id); - return hl_get_attr_by_id(attrcode, err); + return hl_get_attr_by_id(attrcode, rgb, err); } /// Passes input keys to Nvim. diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 2f48cc8757..32567a63de 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -8224,7 +8224,7 @@ RgbValue name_to_color(const uint8_t *name) /// Retrieves attribute description from its id /// /// @param attr_id attribute id -Dictionary hl_get_attr_by_id(Integer attr_id, Error *err) +Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) { HlAttrs attrs = HLATTRS_INIT; Dictionary dic = ARRAY_DICT_INIT; @@ -8240,7 +8240,7 @@ Dictionary hl_get_attr_by_id(Integer attr_id, Error *err) return dic; } - attrs = attrentry2hlattrs(aep, p_tgc); + attrs = attrentry2hlattrs(aep, rgb); end: return hlattrs2dict(attrs); diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index a5d3871d13..4082b0daf9 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -27,14 +27,13 @@ describe('highlight api',function() it("nvim_get_hl_by_id", function() local hl_id = eval("hlID('NewHighlight')") - eq(expected_cterm, nvim("get_hl_by_id", hl_id)) + eq(expected_cterm, nvim("get_hl_by_id", hl_id, false)) - command('set termguicolors') hl_id = eval("hlID('NewHighlight')") - eq(expected_rgb, nvim("get_hl_by_id", hl_id)) + eq(expected_rgb, nvim("get_hl_by_id", hl_id, true)) - -- assume there is no hl with id 30000 - local err, emsg = pcall(meths.get_hl_by_id, 30000) + -- assume there is no hl with id = 30000 + local err, emsg = pcall(meths.get_hl_by_id, 30000, false) eq(false, err) ok(string.find(emsg, 'Invalid highlight id') ~= nil) end) @@ -44,16 +43,15 @@ describe('highlight api',function() foreground = Screen.colors.Red } -- test "Normal" hl defaults - eq({}, nvim("get_hl_by_name", 'Normal')) + eq({}, nvim("get_hl_by_name", 'Normal', true)) - eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight')) - command('set termguicolors') - eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight')) + eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight', false)) + eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight', true)) command('hi Normal guifg=red guibg=yellow') - eq(expected_normal, nvim("get_hl_by_name", 'Normal')) + eq(expected_normal, nvim("get_hl_by_name", 'Normal', true)) - local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight') + local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight', false) eq(false, err) ok(string.find(emsg, 'Invalid highlight name') ~= nil) end) From 481e40cc8ca061f5c3a68f56f30ee96e9086da4d Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Sat, 30 Sep 2017 11:44:50 +0900 Subject: [PATCH 23/43] Remove duplicate ATTRENTRY_INIT --- src/nvim/syntax.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 32567a63de..933baad901 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6825,8 +6825,6 @@ int hl_combine_attr(int char_attr, int prim_attr) if (char_aep != NULL) { // Copy all attributes from char_aep to the new entry new_en = *char_aep; - } else { - new_en = (attrentry_T)ATTRENTRY_INIT; } spell_aep = syn_cterm_attr2entry(prim_attr); From 95458609ab1a97416b2f329613704be44a2f562e Mon Sep 17 00:00:00 2001 From: E Kawashima Date: Sat, 30 Sep 2017 20:45:08 +0900 Subject: [PATCH 24/43] runtime/syntax/vim.vim: highlight nvim groups #7338 regressed by 86b596dc7a49f1b148ef82a356b972b93ed0f6d4 --- runtime/syntax/vim.vim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 295bc6f898..26eea03a3c 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -939,6 +939,11 @@ if !exists("skip_vim_syntax_inits") hi def link vimUserFunc Normal hi def link vimVar Identifier hi def link vimWarn WarningMsg + + hi def link nvimAutoEvent vimAutoEvent + hi def link nvimHLGroup vimHLGroup + hi def link nvimMap vimMap + hi def link nvimUnmap vimUnmap endif " Current Syntax Variable: {{{2 From 981387b7c83026c1446cdddf6b374f63973a2b86 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 30 Sep 2017 16:06:13 +0200 Subject: [PATCH 25/43] ci/appveyor: modify compression options for cache Attempt to workaround #7317 by using a different compression algorithm. --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index ecea6c5fa3..2d6135c7a2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,6 @@ version: '{build}' +environment: + APPVEYOR_CACHE_ENTRY_ZIP_ARGS: "-t7z -m0=lzma -mx=9" configuration: - MINGW_64 - MINGW_32 From 2b133101cf67b523c2503ef715dfb9ebfa732da2 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius Date: Mon, 18 Sep 2017 21:06:55 +0300 Subject: [PATCH 26/43] win: vim_FullName(): force backslashes #7287 - Replace obvious cases of '/' literal with PATHSEP. (There are still some remaining cases that need closer inspection.) - Fixup tests: ui/screen_basic closes #7117 ref https://github.com/neovim/neovim/issues/2471#issuecomment-271193714 --- src/nvim/path.c | 10 +++- test/functional/core/path_spec.lua | 61 ++++++++++++++++++++++++ test/functional/ui/screen_basic_spec.lua | 10 +++- test/unit/path_spec.lua | 14 ++++++ 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 test/functional/core/path_spec.lua diff --git a/src/nvim/path.c b/src/nvim/path.c index f2339c8046..51adcfb135 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1690,6 +1690,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force) if (strlen(fname) > (len - 1)) { xstrlcpy(buf, fname, len); // truncate +#ifdef WIN32 + slash_adjust(buf); +#endif return FAIL; } @@ -1702,6 +1705,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force) if (rv == FAIL) { xstrlcpy(buf, fname, len); // something failed; use the filename } +#ifdef WIN32 + slash_adjust(buf); +#endif return rv; } @@ -2196,11 +2202,11 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf, // expand it if forced or not an absolute path if (force || !path_is_absolute_path(fname)) { - if ((p = vim_strrchr(fname, '/')) != NULL) { + if ((p = vim_strrchr(fname, PATHSEP)) != NULL) { // relative to root if (p == fname) { // only one path component - relative_directory[0] = '/'; + relative_directory[0] = PATHSEP; relative_directory[1] = NUL; } else { assert(p >= fname); diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua new file mode 100644 index 0000000000..44e69fff7b --- /dev/null +++ b/test/functional/core/path_spec.lua @@ -0,0 +1,61 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local eq = helpers.eq +local eval = helpers.eval +local get_pathsep = helpers.get_pathsep +local command = helpers.command + +describe("'%:p' expanding", function() + local pathsep + local targetdir + local expected_path + + local function get_full_path() + return eval('expand("%:p")') + end + + local function join_path(...) + return table.concat({...}, pathsep) + end + + before_each(function() + clear() + pathsep = get_pathsep() + targetdir = join_path('test', 'functional', 'fixtures') + clear(join_path(targetdir, 'tty-test.c')) + expected_path = get_full_path() + end) + + it('given a relative path with current directory in the middle #7117', function() + clear(join_path(targetdir, '.', 'tty-test.c')) + eq(expected_path, get_full_path()) + end) + + it('given a relative path with current directory #7117', function() + clear(join_path('.', targetdir, 'tty-test.c')) + eq(expected_path, get_full_path()) + end) + + it('given a relative path with current directory to a file when changing directory #7117', function() + clear(join_path('.', targetdir, 'tty-test.c')) + command('cd test') + eq(expected_path, get_full_path()) + end) + + it('given a relative path with directory up the tree to a file #7117', function() + clear(join_path(targetdir, '..', 'fixtures', 'tty-test.c')) + eq(expected_path, get_full_path()) + end) + + it('given a different starting directory and a relative path with directory up the tree #7117', function() + command('cd test') + command('e ' .. join_path('..', targetdir, 'tty-test.c')) + eq(expected_path, get_full_path()) + end) + + it('given a different starting directory and a relative path with current directory and up the tree #7117', function() + command('cd test') + command('e ' .. join_path('.', '..', targetdir, 'tty-test.c')) + eq(expected_path, get_full_path()) + end) +end) diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index bfcdc7f652..9032239b31 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -5,6 +5,7 @@ local feed, command = helpers.feed, helpers.command local insert = helpers.insert local eq = helpers.eq local eval = helpers.eval +local iswin = helpers.iswin describe('screen', function() local screen @@ -120,8 +121,15 @@ describe('Screen', function() it('has correct default title with named file', function() local expected = 'myfile (/mydir) - NVIM' + if iswin() then + expected = 'myfile (C:\\mydir) - NVIM' + end command('set title') - command('file /mydir/myfile') + if iswin() then + command('file C:\\mydir\\myfile') + else + command('file /mydir/myfile') + end screen:expect(function() eq(expected, screen.title) end) diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index a9cba7df84..0400747e72 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -481,6 +481,20 @@ describe('path.c', function() eq('/tmp', ffi.string(buffer)) eq(OK, result) end) + + itp('works with a relative path with the current directory prefix #7117', function() + local force_expansion = 1 + local result = vim_FullName('./unit-test-directory/test.file', buffer, length, force_expansion) + eq(OK, result) + eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer))) + end) + + itp('works with a relative path with the directory name mentioned twice #7117', function() + local force_expansion = 1 + local result = vim_FullName('unit-test-directory/../unit-test-directory/test.file', buffer, length, force_expansion) + eq(OK, result) + eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer))) + end) end) describe('path_fix_case', function() From e9dba214eada40a2d64b89616f1799b87cab1e5e Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius Date: Thu, 21 Sep 2017 16:50:56 +0300 Subject: [PATCH 27/43] test/shada: fixup for Windows backslashes #7287 --- test/functional/shada/compatibility_spec.lua | 29 +-- test/functional/shada/merging_spec.lua | 187 ++++++++++--------- 2 files changed, 115 insertions(+), 101 deletions(-) diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua index 1287ac010c..a5ef60d91f 100644 --- a/test/functional/shada/compatibility_spec.lua +++ b/test/functional/shada/compatibility_spec.lua @@ -10,6 +10,13 @@ local read_shada_file = shada_helpers.read_shada_file local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compatibility.shada') +local mock_file_path = '/a/b/' +local mock_file_path2 = '/d/e/' +if helpers.iswin() then + mock_file_path = 'C:/a/' + mock_file_path2 = 'C:/d/' +end + describe('ShaDa forward compatibility support code', function() before_each(reset) after_each(function() @@ -114,14 +121,14 @@ describe('ShaDa forward compatibility support code', function() funcs.garbagecollect(1) end) - for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006/a/b/c\161nA'}, - {name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'}, - {name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006/a/b/c\161na'}, - {name='change', mpack='\011\001\015\130\162mX\195\161f\196\006/a/b/c'}, + for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161nA'}, + {name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'}, + {name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161na'}, + {name='change', mpack='\011\001\015\130\162mX\195\161f\196\006' .. mock_file_path .. 'c'}, }) do it('works with ' .. v.name .. ' item with BOOL unknown (mX) key value', function() - nvim_command('silent noautocmd edit /a/b/c') - eq('/a/b/c', funcs.bufname('%')) + nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c') + eq('' .. mock_file_path .. 'c', funcs.bufname('%')) funcs.setline('.', {'1', '2', '3'}) wshada(v.mpack) eq(0, exc_exec(sdrcmd(true))) @@ -159,12 +166,12 @@ describe('ShaDa forward compatibility support code', function() if v.name == 'global mark' or v.name == 'local mark' then it('works with ' .. v.name .. ' item with name', function() - nvim_command('silent noautocmd edit /a/b/c') - eq('/a/b/c', funcs.bufname('%')) + nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c') + eq('' .. mock_file_path .. 'c', funcs.bufname('%')) funcs.setline('.', {'1', '2', '3'}) wshada(v.mpack:gsub('n.$', 'n\001') .. v.mpack:gsub('n.$', 'n\002') - .. v.mpack:gsub('n.$', 'n\003'):gsub('/a/b/c', '/d/e/f')) + .. v.mpack:gsub('n.$', 'n\003'):gsub('' .. mock_file_path .. 'c', '' .. mock_file_path2 .. 'f')) eq(0, exc_exec(sdrcmd(true))) nvim_command('wshada ' .. shada_fname) local found = 0 @@ -307,10 +314,10 @@ describe('ShaDa forward compatibility support code', function() it('works with buffer list item with BOOL unknown (bX) key', function() nvim_command('set shada+=%') - wshada('\009\000\016\145\130\161f\196\006/a/b/c\162bX\195') + wshada('\009\000\016\145\130\161f\196\006' .. mock_file_path .. 'c\162bX\195') eq(0, exc_exec(sdrcmd())) eq(2, funcs.bufnr('$')) - eq('/a/b/c', funcs.bufname(2)) + eq('' .. mock_file_path .. 'c', funcs.bufname(2)) os.remove(shada_fname) nvim_command('wshada ' .. shada_fname) local found = false diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua index 25c73b99eb..7a15c8908b 100644 --- a/test/functional/shada/merging_spec.lua +++ b/test/functional/shada/merging_spec.lua @@ -13,6 +13,11 @@ local read_shada_file = shada_helpers.read_shada_file local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-merging.shada') +local mock_file_path = '/a/b/' +if helpers.iswin() then + mock_file_path = 'C:/a/' +end + describe('ShaDa history merging code', function() before_each(reset) after_each(function() @@ -512,9 +517,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from instance when reading', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -522,9 +527,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from file when reading with !', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd(true))) nvim_command('normal! `A') eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -532,9 +537,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with eq timestamp from instance when reading', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -542,9 +547,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from file when reading', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\002\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -552,15 +557,15 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from instance when writing', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 7 and v.value.f == '/a/b/-' then + if v.type == 7 and v.value.f == '' .. mock_file_path .. '-' then found = found + 1 end end @@ -569,15 +574,15 @@ describe('ShaDa marks support code', function() it('uses last A mark with eq timestamp from instance when writing', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 7 and v.value.f == '/a/b/-' then + if v.type == 7 and v.value.f == mock_file_path .. '-' then found = found + 1 end end @@ -586,15 +591,15 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from file when writing', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\002\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 7 and v.value.f == '/a/b/?' then + if v.type == 7 and v.value.f == '' .. mock_file_path .. '?' then found = found + 1 end end @@ -603,11 +608,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from instance when reading', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') eq('-', funcs.getline('.')) @@ -615,11 +620,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from file when reading with !', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd(true))) nvim_command('normal! `a') eq('?', funcs.getline('.')) @@ -627,11 +632,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with eq timestamp from instance when reading', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\001\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') eq('-', funcs.getline('.')) @@ -639,11 +644,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from file when reading', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\002\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') eq('?', funcs.getline('.')) @@ -651,17 +656,17 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from instance when writing', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') eq('-', funcs.getline('.')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then + if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then eq(true, v.value.l == 1 or v.value.l == nil) found = found + 1 end @@ -671,17 +676,17 @@ describe('ShaDa marks support code', function() it('uses last a mark with eq timestamp from instance when writing', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\001\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') eq('-', funcs.getline('.')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then + if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then eq(true, v.value.l == 1 or v.value.l == nil) found = found + 1 end @@ -691,17 +696,17 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from file when writing', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\002\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then + if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then eq(2, v.value.l) found = found + 1 end @@ -813,41 +818,41 @@ describe('ShaDa jumps support code', function() end) it('merges jumps when reading', function() - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\002' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/e\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002') eq(0, exc_exec(sdrcmd())) - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\003' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/f\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002') eq(0, exc_exec(sdrcmd())) eq('', curbufmeths.get_name()) eq('\n' .. ' jump line col file/text\n' - .. ' 6 2 0 /a/b/c\n' - .. ' 5 2 0 /a/b/d\n' - .. ' 4 3 0 /a/b/d\n' - .. ' 3 2 0 /a/b/e\n' - .. ' 2 2 0 /a/b/f\n' + .. ' 6 2 0 ' .. mock_file_path .. 'c\n' + .. ' 5 2 0 ' .. mock_file_path .. 'd\n' + .. ' 4 3 0 ' .. mock_file_path .. 'd\n' + .. ' 3 2 0 ' .. mock_file_path .. 'e\n' + .. ' 2 2 0 ' .. mock_file_path .. 'f\n' .. ' 1 1 0 \n' .. '>', redir_exec('jumps')) end) it('merges jumps when writing', function() - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\002' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/e\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002') eq(0, exc_exec(sdrcmd())) - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\003' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/f\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002') eq(0, exc_exec('wshada ' .. shada_fname)) local jumps = { - {file='/a/b/c', line=2}, - {file='/a/b/d', line=2}, - {file='/a/b/d', line=3}, - {file='/a/b/e', line=2}, - {file='/a/b/f', line=2}, + {file='' .. mock_file_path .. 'c', line=2}, + {file='' .. mock_file_path .. 'd', line=2}, + {file='' .. mock_file_path .. 'd', line=3}, + {file='' .. mock_file_path .. 'e', line=2}, + {file='' .. mock_file_path .. 'f', line=2}, } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -864,9 +869,9 @@ describe('ShaDa jumps support code', function() local jumps = {} local shada = '' for i = 1,100 do - shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' + shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' ):format(i, i) - jumps[i] = {file='/a/b/c', line=i} + jumps[i] = {file='' .. mock_file_path .. 'c', line=i} end wshada(shada) eq(0, exc_exec(sdrcmd())) @@ -874,9 +879,9 @@ describe('ShaDa jumps support code', function() for i = 1,101 do local t = i * 2 shada = shada .. ( - '\008\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c' + '\008\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' ):format(t, t) - jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='/a/b/c', line=t} + jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='' .. mock_file_path .. 'c', line=t} end wshada(shada) eq(0, exc_exec('wshada ' .. shada_fname)) @@ -904,15 +909,15 @@ describe('ShaDa changes support code', function() end) it('merges changes when reading', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(7))') - wshada('\011\001\018\131\162mX\195\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\011\007\018\131\162mX\195\161f\196\006/a/b/c\161l\003') + wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003') eq(0, exc_exec(sdrcmd())) - wshada('\011\001\018\131\162mX\194\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\005' - .. '\011\008\018\131\162mX\195\161f\196\006/a/b/c\161l\004') + wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005' + .. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004') eq(0, exc_exec(sdrcmd())) eq('\n' .. 'change line col text\n' @@ -925,15 +930,15 @@ describe('ShaDa changes support code', function() end) it('merges changes when writing', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(7))') - wshada('\011\001\018\131\162mX\195\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\011\007\018\131\162mX\195\161f\196\006/a/b/c\161l\003') + wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003') eq(0, exc_exec(sdrcmd())) - wshada('\011\001\018\131\162mX\194\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\005' - .. '\011\008\018\131\162mX\195\161f\196\006/a/b/c\161l\004') + wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005' + .. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004') eq(0, exc_exec('wshada ' .. shada_fname)) local changes = { {line=1}, @@ -944,7 +949,7 @@ describe('ShaDa changes support code', function() } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 11 and v.value.f == '/a/b/c' then + if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then found = found + 1 eq(changes[found].line, v.value.l or 1) end @@ -953,12 +958,12 @@ describe('ShaDa changes support code', function() end) it('merges JUMPLISTSIZE changes when writing', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(202))') local changes = {} local shada = '' for i = 1,100 do - shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' + shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' ):format(i, i) changes[i] = {line=i} end @@ -968,7 +973,7 @@ describe('ShaDa changes support code', function() for i = 1,101 do local t = i * 2 shada = shada .. ( - '\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c' + '\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' ):format(t, t) changes[(t > #changes + 1) and (#changes + 1) or t] = {line=t} end @@ -980,7 +985,7 @@ describe('ShaDa changes support code', function() end local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 11 and v.value.f == '/a/b/c' then + if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then found = found + 1 eq(changes[found].line, v.value.l) end @@ -990,20 +995,20 @@ describe('ShaDa changes support code', function() it('merges JUMPLISTSIZE changes when writing, with new items between old', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(202))') local shada = '' for i = 1,101 do local t = i * 2 shada = shada .. ( - '\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c' + '\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' ):format(t, t) end wshada(shada) eq(0, exc_exec(sdrcmd())) shada = '' for i = 1,100 do - shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' + shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' ):format(i, i) end local changes = {} @@ -1022,7 +1027,7 @@ describe('ShaDa changes support code', function() end local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 11 and v.value.f == '/a/b/c' then + if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then found = found + 1 eq(changes[found].line, v.value.l) end @@ -1030,3 +1035,5 @@ describe('ShaDa changes support code', function() eq(found, 100) end) end) + +-- vim: ts=2 sw=2 From 6f7754dfa0c6a9ec2a1e7db3685ffd41b207b882 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 2 Oct 2017 00:24:19 +0200 Subject: [PATCH 28/43] test: avoid extra clear() calls also: various other cleanup --- test/functional/core/path_spec.lua | 53 +++++++++++------------- test/functional/ui/screen_basic_spec.lua | 12 ++---- test/unit/path_spec.lua | 4 +- 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua index 44e69fff7b..669bc99136 100644 --- a/test/functional/core/path_spec.lua +++ b/test/functional/core/path_spec.lua @@ -2,60 +2,55 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local eval = helpers.eval -local get_pathsep = helpers.get_pathsep local command = helpers.command +local iswin = helpers.iswin -describe("'%:p' expanding", function() - local pathsep +describe('path collapse', function() local targetdir local expected_path - local function get_full_path() - return eval('expand("%:p")') - end - local function join_path(...) + local pathsep = (iswin() and '\\' or '/') return table.concat({...}, pathsep) end before_each(function() - clear() - pathsep = get_pathsep() targetdir = join_path('test', 'functional', 'fixtures') - clear(join_path(targetdir, 'tty-test.c')) - expected_path = get_full_path() + clear() + command('edit '..join_path(targetdir, 'tty-test.c')) + expected_path = eval('expand("%:p")') end) - it('given a relative path with current directory in the middle #7117', function() - clear(join_path(targetdir, '.', 'tty-test.c')) - eq(expected_path, get_full_path()) + it('with /./ segment #7117', function() + command('edit '..join_path(targetdir, '.', 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) end) - it('given a relative path with current directory #7117', function() - clear(join_path('.', targetdir, 'tty-test.c')) - eq(expected_path, get_full_path()) + it('with ./ prefix #7117', function() + command('edit '..join_path('.', targetdir, 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) end) - it('given a relative path with current directory to a file when changing directory #7117', function() - clear(join_path('.', targetdir, 'tty-test.c')) + it('with ./ prefix, after directory change #7117', function() + command('edit '..join_path('.', targetdir, 'tty-test.c')) command('cd test') - eq(expected_path, get_full_path()) + eq(expected_path, eval('expand("%:p")')) end) - it('given a relative path with directory up the tree to a file #7117', function() - clear(join_path(targetdir, '..', 'fixtures', 'tty-test.c')) - eq(expected_path, get_full_path()) + it('with /../ segment #7117', function() + command('edit '..join_path(targetdir, '..', 'fixtures', 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) end) - it('given a different starting directory and a relative path with directory up the tree #7117', function() + it('with ../ and different starting directory #7117', function() command('cd test') - command('e ' .. join_path('..', targetdir, 'tty-test.c')) - eq(expected_path, get_full_path()) + command('edit '..join_path('..', targetdir, 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) end) - it('given a different starting directory and a relative path with current directory and up the tree #7117', function() + it('with ./../ and different starting directory #7117', function() command('cd test') - command('e ' .. join_path('.', '..', targetdir, 'tty-test.c')) - eq(expected_path, get_full_path()) + command('edit '..join_path('.', '..', targetdir, 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) end) end) diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 9032239b31..b31d9cb32f 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -120,16 +120,10 @@ describe('Screen', function() end) it('has correct default title with named file', function() - local expected = 'myfile (/mydir) - NVIM' - if iswin() then - expected = 'myfile (C:\\mydir) - NVIM' - end + local expected = (iswin() and 'myfile (C:\\mydir) - NVIM' + or 'myfile (/mydir) - NVIM') command('set title') - if iswin() then - command('file C:\\mydir\\myfile') - else - command('file /mydir/myfile') - end + command(iswin() and 'file C:\\mydir\\myfile' or 'file /mydir/myfile') screen:expect(function() eq(expected, screen.title) end) diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index 0400747e72..befb204d0a 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -482,14 +482,14 @@ describe('path.c', function() eq(OK, result) end) - itp('works with a relative path with the current directory prefix #7117', function() + itp('expands "./" to the current directory #7117', function() local force_expansion = 1 local result = vim_FullName('./unit-test-directory/test.file', buffer, length, force_expansion) eq(OK, result) eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer))) end) - itp('works with a relative path with the directory name mentioned twice #7117', function() + itp('collapses "foo/../foo" to "foo" #7117', function() local force_expansion = 1 local result = vim_FullName('unit-test-directory/../unit-test-directory/test.file', buffer, length, force_expansion) eq(OK, result) From 235fda5f86d80b1aa7d7cbcb41e3399c556b7455 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 3 Oct 2017 14:53:11 -0400 Subject: [PATCH 29/43] Stub ngettext when libintl isn't available This should have been included in #6547 as part of vim-patch:7.4.2152. Closes #7352 --- cmake/FindLibIntl.cmake | 1 + src/nvim/gettext.h | 1 + 2 files changed, 2 insertions(+) diff --git a/cmake/FindLibIntl.cmake b/cmake/FindLibIntl.cmake index 75926200c1..ab4632cf45 100644 --- a/cmake/FindLibIntl.cmake +++ b/cmake/FindLibIntl.cmake @@ -46,6 +46,7 @@ check_c_source_compiles(" int main(int argc, char** argv) { gettext(\"foo\"); + ngettext(\"foo\", \"bar\", 1); bindtextdomain(\"foo\", \"bar\"); bind_textdomain_codeset(\"foo\", \"bar\"); textdomain(\"foo\"); diff --git a/src/nvim/gettext.h b/src/nvim/gettext.h index aa0e97233e..60317b8484 100644 --- a/src/nvim/gettext.h +++ b/src/nvim/gettext.h @@ -13,6 +13,7 @@ #else # define _(x) ((char *)(x)) # define N_(x) x +# define ngettext(x, xs, n) ((n) == 1 ? (x) : (xs)) # define bindtextdomain(x, y) // empty # define bind_textdomain_codeset(x, y) // empty # define textdomain(x) // empty From b7fe15d8f9162888dd2ca944e61e1e12abe84815 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 4 Oct 2017 03:18:03 -0400 Subject: [PATCH 30/43] editorconfig: handle Vim help files (#7354) --- .editorconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.editorconfig b/.editorconfig index b08a27f2a2..ac902ecec5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,10 @@ end_of_line = lf insert_final_newline = true charset = utf_8 +[runtime/doc/*.txt] +indent_style = tab +indent_size = 8 + [Makefile] indent_style = tab tab_width = 4 From 5f4d2edeeea4d05761811d652dee8067fdbbae2a Mon Sep 17 00:00:00 2001 From: nate Date: Sat, 19 Aug 2017 18:33:14 -0700 Subject: [PATCH 31/43] 'titleold': set UI title on exit #7191 closes #7129 ref #4063 --- src/nvim/buffer.c | 13 ++++++++++--- src/nvim/globals.h | 1 + src/nvim/option.c | 1 + src/nvim/os_unix.c | 7 +++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 724a8578ac..950010b13b 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3069,9 +3069,16 @@ static bool ti_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); - ui_call_set_icon(cstr_as_string((char *)lasticon)); - ui_flush(); + // if icon change, should the title be reset too? + if (p_icon) { + ui_call_set_title(cstr_as_string((char *)lasttitle)); + ui_call_set_icon(cstr_as_string((char *)lasticon)); + } else if (p_title) { + ui_call_set_title(cstr_as_string((char *)lasttitle)); + } + if (p_title || p_icon) { + ui_flush(); + } } # if defined(EXITFREE) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 300e506854..62bb817c4c 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -279,6 +279,7 @@ EXTERN int need_wait_return INIT(= 0); /* need to wait for return later */ EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and nothing written since then */ EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */ +EXTERN int did_enable_title INIT(= FALSE); /* did set title */ EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */ #if defined(UNIX) || defined(MACOS_X) diff --git a/src/nvim/option.c b/src/nvim/option.c index 13aadb71bb..3a7499f195 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1953,6 +1953,7 @@ did_set_title ( if (starting != NO_SCREEN) { maketitle(); resettitle(); + did_enable_title = true; } } diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 692bcc97f4..5855a874c4 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -15,6 +15,7 @@ #include #include "nvim/api/private/handle.h" +#include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/os_unix.h" @@ -137,6 +138,12 @@ void mch_exit(int r) FUNC_ATTR_NORETURN { exiting = true; + if ((p_title + || (did_enable_title + && (p_titlestring == NULL || STRLEN(p_titlestring) == 0))) + && p_titleold != NULL) { + ui_call_set_title(cstr_as_string((char *)p_titleold)); + } ui_builtin_stop(); ui_flush(); ml_close_all(true); // remove all memfiles From 70e84a7c4c7bfad9b3a0ec18fd219f51205c03f8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Oct 2017 09:14:18 +0200 Subject: [PATCH 32/43] 'titleold': simplify behavior - default 'titleold' to empty - set title on exit if 'title' is enabled and 'titleold' is non-empty - update docs --- runtime/doc/options.txt | 13 ++++++------- src/nvim/buffer.c | 5 +---- src/nvim/globals.h | 1 - src/nvim/option.c | 1 - src/nvim/options.lua | 2 +- src/nvim/os_unix.c | 5 +---- 6 files changed, 9 insertions(+), 18 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index c6965648ef..462fda4bfd 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6267,11 +6267,11 @@ A jump table for the options with a short description can be found at |Q_op|. when part of a command has been typed. *'title'* *'notitle'* -'title' boolean (default off, on when title can be restored) +'title' boolean (default off) global When on, the title of the window will be set to the value of 'titlestring' (if it is not empty), or to: - filename [+=-] (path) - VIM + filename [+=-] (path) - NVIM Where: filename the name of the file being edited - indicates the file cannot be modified, 'ma' off @@ -6279,7 +6279,7 @@ A jump table for the options with a short description can be found at |Q_op|. = indicates the file is read-only =+ indicates the file is read-only and modified (path) is the path of the file being edited - - VIM the server name |v:servername| or "VIM" + - NVIM the server name |v:servername| or "NVIM" *'titlelen'* 'titlelen' number (default 85) @@ -6295,11 +6295,10 @@ A jump table for the options with a short description can be found at |Q_op|. 'titlelen' is also used for the 'titlestring' option. *'titleold'* -'titleold' string (default "Thanks for flying Vim") +'titleold' string (default "") global - This option will be used for the window title when exiting Vim if the - original title cannot be restored. Only happens if 'title' is on or - 'titlestring' is not empty. + If not empty, this option will be used to set the window title when + exiting. Only if 'title' is enabled. This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. *'titlestring'* diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 950010b13b..fbfb4e02ea 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3069,14 +3069,11 @@ static bool ti_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - // if icon change, should the title be reset too? if (p_icon) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); ui_call_set_icon(cstr_as_string((char *)lasticon)); - } else if (p_title) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); } if (p_title || p_icon) { + ui_call_set_title(cstr_as_string((char *)lasttitle)); ui_flush(); } } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 62bb817c4c..300e506854 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -279,7 +279,6 @@ EXTERN int need_wait_return INIT(= 0); /* need to wait for return later */ EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and nothing written since then */ EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */ -EXTERN int did_enable_title INIT(= FALSE); /* did set title */ EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */ #if defined(UNIX) || defined(MACOS_X) diff --git a/src/nvim/option.c b/src/nvim/option.c index 3a7499f195..13aadb71bb 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1953,7 +1953,6 @@ did_set_title ( if (starting != NO_SCREEN) { maketitle(); resettitle(); - did_enable_title = true; } } diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 103227f6b5..84ccb2e28d 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2498,7 +2498,7 @@ return { no_mkrc=true, vi_def=true, varname='p_titleold', - defaults={if_true={vi=N_("Thanks for flying Vim")}} + defaults={if_true={vi=N_("")}} }, { full_name='titlestring', diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 5855a874c4..2748de7329 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -138,10 +138,7 @@ void mch_exit(int r) FUNC_ATTR_NORETURN { exiting = true; - if ((p_title - || (did_enable_title - && (p_titlestring == NULL || STRLEN(p_titlestring) == 0))) - && p_titleold != NULL) { + if (p_title && *p_titleold != NUL) { ui_call_set_title(cstr_as_string((char *)p_titleold)); } ui_builtin_stop(); From 73b50de925c10aaf0db2ffed47ec8459b0730cd1 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Oct 2017 09:49:17 +0200 Subject: [PATCH 33/43] 'titleold': move logic to getout() --- src/nvim/main.c | 5 +++++ src/nvim/os_unix.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 024c56dd05..ea7a58bda3 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -649,6 +649,11 @@ void getout(int exitval) /* Position the cursor again, the autocommands may have moved it */ ui_cursor_goto((int)Rows - 1, 0); + // Apply 'titleold'. + if (p_title && *p_titleold != NUL) { + ui_call_set_title(cstr_as_string((char *)p_titleold)); + } + #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) iconv_end(); #endif diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 2748de7329..692bcc97f4 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -15,7 +15,6 @@ #include #include "nvim/api/private/handle.h" -#include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/os_unix.h" @@ -138,9 +137,6 @@ void mch_exit(int r) FUNC_ATTR_NORETURN { exiting = true; - if (p_title && *p_titleold != NUL) { - ui_call_set_title(cstr_as_string((char *)p_titleold)); - } ui_builtin_stop(); ui_flush(); ml_close_all(true); // remove all memfiles From a4019bc9f6478941fe75879e81d37bd628bc94c5 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Sat, 7 Oct 2017 06:45:23 -0400 Subject: [PATCH 34/43] eval.c: ga_concat_esc() #7357 vim-patch:2368917d8f0c0a997eac7a51ddfaa748dc528392 closes #7256 --- src/nvim/eval.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 5ee91d417a..86b99c2783 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6733,6 +6733,39 @@ static void prepare_assert_error(garray_T *gap) } } +// Append "str" to "gap", escaping unprintable characters. +// Changes NL to \n, CR to \r, etc. +static void ga_concat_esc(garray_T *gap, char_u *str) +{ + char_u *p; + char_u buf[NUMBUFLEN]; + + if (str == NULL) { + ga_concat(gap, (char_u *)"NULL"); + return; + } + + for (p = str; *p != NUL; p++) { + switch (*p) { + case BS: ga_concat(gap, (char_u *)"\\b"); break; + case ESC: ga_concat(gap, (char_u *)"\\e"); break; + case FF: ga_concat(gap, (char_u *)"\\f"); break; + case NL: ga_concat(gap, (char_u *)"\\n"); break; + case TAB: ga_concat(gap, (char_u *)"\\t"); break; + case CAR: ga_concat(gap, (char_u *)"\\r"); break; + case '\\': ga_concat(gap, (char_u *)"\\\\"); break; + default: + if (*p < ' ') { + vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); + ga_concat(gap, buf); + } else { + ga_append(gap, *p); + } + break; + } + } +} + // Fill "gap" with information about an assert error. static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, @@ -6753,11 +6786,11 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, ga_concat(gap, (char_u *)"Expected "); } if (exp_str == NULL) { - tofree = (char_u *) encode_tv2string(exp_tv, NULL); - ga_concat(gap, tofree); + tofree = (char_u *)encode_tv2string(exp_tv, NULL); + ga_concat_esc(gap, tofree); xfree(tofree); } else { - ga_concat(gap, exp_str); + ga_concat_esc(gap, exp_str); } if (atype != ASSERT_NOTEQUAL) { if (atype == ASSERT_MATCH) { @@ -6768,7 +6801,7 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, ga_concat(gap, (char_u *)" but got "); } tofree = (char_u *)encode_tv2string(got_tv, NULL); - ga_concat(gap, tofree); + ga_concat_esc(gap, tofree); xfree(tofree); } } From 9ad7529f705c883e13fba9a014696fb37318145f Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sat, 7 Oct 2017 20:32:37 +0800 Subject: [PATCH 35/43] vim-patch:8.0.0157 (#7362) Problem: No command line completion for ":syntax spell" and ":syntax sync". Solution: Implement the completion. (Dominique Pelle) https://github.com/vim/vim/commit/2d02839050a2557bf36dab37ccd9f92168a757d1 --- src/nvim/syntax.c | 36 +++++++++++++++++++++++++------- src/nvim/testdir/test_syntax.vim | 8 +++++++ src/nvim/version.c | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 65c0e2464a..ddc3f5c27b 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5567,8 +5567,10 @@ bool syntax_present(win_T *win) static enum { - EXP_SUBCMD, /* expand ":syn" sub-commands */ - EXP_CASE /* expand ":syn case" arguments */ + EXP_SUBCMD, // expand ":syn" sub-commands + EXP_CASE, // expand ":syn case" arguments + EXP_SPELL, // expand ":syn spell" arguments + EXP_SYNC // expand ":syn sync" arguments } expand_what; /* @@ -5612,6 +5614,10 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) xp->xp_context = EXPAND_NOTHING; } else if (STRNICMP(arg, "case", p - arg) == 0) { expand_what = EXP_CASE; + } else if (STRNICMP(arg, "spell", p - arg) == 0) { + expand_what = EXP_SPELL; + } else if (STRNICMP(arg, "sync", p - arg) == 0) { + expand_what = EXP_SYNC; } else if (STRNICMP(arg, "keyword", p - arg) == 0 || STRNICMP(arg, "region", p - arg) == 0 || STRNICMP(arg, "match", p - arg) == 0 @@ -5624,17 +5630,33 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) } } -static char *(case_args[]) = {"match", "ignore", NULL}; - /* * Function given to ExpandGeneric() to obtain the list syntax names for * expansion. */ char_u *get_syntax_name(expand_T *xp, int idx) { - if (expand_what == EXP_SUBCMD) - return (char_u *)subcommands[idx].name; - return (char_u *)case_args[idx]; + switch (expand_what) { + case EXP_SUBCMD: + return (char_u *)subcommands[idx].name; + case EXP_CASE: { + static char *case_args[] = { "match", "ignore", NULL }; + return (char_u *)case_args[idx]; + } + case EXP_SPELL: { + static char *spell_args[] = + { "toplevel", "notoplevel", "default", NULL }; + return (char_u *)spell_args[idx]; + } + case EXP_SYNC: { + static char *sync_args[] = + { "ccomment", "clear", "fromstart", + "linebreaks=", "linecont", "lines=", "match", + "maxlines=", "minlines=", "region", NULL }; + return (char_u *)sync_args[idx]; + } + } + return NULL; } diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index af2cbbfe8e..05e930d984 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -76,3 +76,11 @@ func Test_syntax_after_reload() call assert_true(exists('g:gotit')) call delete('Xsomefile') endfunc + +func Test_syntax_completion() + call feedkeys(":syn spell \\\"\", 'tx') + call assert_equal('"syn spell default notoplevel toplevel', @:) + + call feedkeys(":syn sync \\\"\", 'tx') + call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index b0d4e194fa..76897088a1 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -946,7 +946,7 @@ static const int included_patches[] = { // 160, 159, 158, - // 157, + 157, 156, // 155, // 154, From 7a832c312f13bd6be9350952cdac3bd30613a824 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 7 Oct 2017 15:55:25 +0200 Subject: [PATCH 36/43] syntax: 'cursorcolumn', 'colorcolumn': low priority #6380 --- runtime/doc/options.txt | 18 +++++++++--------- runtime/doc/vim_diff.txt | 4 ++++ src/nvim/screen.c | 34 ++++++++++++++++------------------ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 462fda4bfd..d55eb7405c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6747,19 +6747,19 @@ A jump table for the options with a short description can be found at |Q_op|. *'winhighlight'* *'winhl'* 'winhighlight' 'winhl' string (default empty) local to window - Window-local highlights. Comma-delimited list of |group-name| pairs - "{hl-builtin}:{hl-group},..." where each {hl-builtin} is a group (from - |highlight-groups|) to be overridden by {hl-group} in the window where - this option was set. Only builting ui highlights are supported, not - syntax highlighting. For that purpose, use |:ownsyntax|. + Window-local highlights. Comma-delimited list of highlight + |group-name| pairs "{hl-builtin}:{hl},..." where each {hl-builtin} is + a built-in |highlight-groups| item to be overridden by {hl} group in + the window. Only built-in |highlight-groups| are supported, not + syntax highlighting (use |:ownsyntax| for that). - Most highlights occuring within the frame of a window are supported. Highlights of vertical separators are determined by the window to the left of the separator. The highlight of a tabpage in |tabline| is - determined by the last focused window in the tabpage. Highlights of + determine by the last-focused window of the tabpage. Highlights of the popupmenu are determined by the current window. Highlights in the - message area are not overridable. Example for overriding the - backgrond color: > + message area cannot be overridden. + + Example: show a different color for non-current windows: > set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC < *'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'* diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index eb3c4d50ce..5df3852d8e 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -280,6 +280,10 @@ other arguments if used). |input()| and |inputdialog()| support user-defined cmdline highlighting. +Highlight groups: + |hl-ColorColumn|, |hl-CursorColumn| are lower priority than most other + groups + ============================================================================== 5. Missing legacy features *nvim-features-missing* diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 921ef06c7b..a6418a6f27 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2201,16 +2201,16 @@ win_line ( int change_end = -1; /* last col of changed area */ colnr_T trailcol = MAXCOL; /* start of trailing spaces */ 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 */ - int shl_flag; /* flag to indicate whether search_hl - has been processed or not */ - int prevcol_hl_flag; /* flag to indicate whether prevcol - equals startcol of search_hl or one - of the matches */ - int prev_c = 0; /* previous Arabic character */ - int prev_c1 = 0; /* first composing char for prev_c */ + 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 + int shl_flag; // flag to indicate whether search_hl + // has been processed or not + int prevcol_hl_flag; // flag to indicate whether prevcol + // equals startcol of search_hl or one + // of the matches + int prev_c = 0; // previous Arabic character + int prev_c1 = 0; // first composing char for prev_c int did_line_attr = 0; bool search_attr_from_match = false; // if search_attr is from :match @@ -3594,15 +3594,13 @@ win_line ( && lcs_eol_one > 0) { // Display a '$' after the line or highlight an extra // character if the line break is included. - // For a diff line the highlighting continues after the - // "$". + // For a diff line the highlighting continues after the "$". if (diff_hlf == (hlf_T)0 && line_attr == 0) { - /* In virtualedit, visual selections may extend - * beyond end of line. */ + // In virtualedit, visual selections may extend beyond end of line. if (area_highlighting && virtual_active() - && tocol != MAXCOL && vcol < tocol) + && tocol != MAXCOL && vcol < tocol) { n_extra = 0; - else { + } else { p_extra = at_end_str; n_extra = 1; c_extra = NUL; @@ -4035,10 +4033,10 @@ win_line ( if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum) { vcol_save_attr = char_attr; - char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUC)); + char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), char_attr); } else if (draw_color_col && VCOL_HLC == *color_cols) { vcol_save_attr = char_attr; - char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_MC)); + char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), char_attr); } } From d1874ab2821d076397290cc154d87ec2dc352c79 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 7 Oct 2017 16:06:46 +0200 Subject: [PATCH 37/43] syntax: 'cursorline': low priority #6380 --- runtime/doc/vim_diff.txt | 4 +-- src/nvim/screen.c | 42 +++++++++++++-------------- test/functional/ui/highlight_spec.lua | 6 ++-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 5df3852d8e..861fa65c3a 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -281,8 +281,8 @@ other arguments if used). |input()| and |inputdialog()| support user-defined cmdline highlighting. Highlight groups: - |hl-ColorColumn|, |hl-CursorColumn| are lower priority than most other - groups + |hl-ColorColumn|, |hl-CursorColumn|, |hl-CursorLine| are lower priority than + (overridden by) most other highlight groups. ============================================================================== 5. Missing legacy features *nvim-features-missing* diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a6418a6f27..5659f30f64 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2202,6 +2202,7 @@ win_line ( colnr_T trailcol = MAXCOL; /* start of trailing spaces */ int need_showbreak = false; // overlong line, skip first x chars int line_attr = 0; // attribute for the whole line + int line_attr_low_priority = 0; // current line, lowest priority matchitem_T *cur; // points to the match list match_T *shl; // points to search_hl or a match int shl_flag; // flag to indicate whether search_hl @@ -2427,10 +2428,17 @@ win_line ( filler_lines = wp->w_topfill; filler_todo = filler_lines; - /* If this line has a sign with line highlighting set line_attr. */ + // 'cursorline' highlighting for the current window. Not when Visual mode is + // active, because it's not clear what is selected then. + if (wp->w_p_cul && lnum == wp->w_cursor.lnum + && !(wp == curwin && VIsual_active)) { + line_attr_low_priority = win_hl_attr(wp, HLF_CUL); + } + v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL); - if (v != 0) - line_attr = sign_get_attr((int)v, TRUE); + if (v != 0) { + line_attr = sign_get_attr((int)v, true); + } // Highlight the current line in the quickfix window. if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) { @@ -2441,7 +2449,7 @@ win_line ( line_attr = hl_combine_attr(wp->w_hl_attr_normal, line_attr); } - if (line_attr != 0) { + if (line_attr_low_priority || line_attr) { area_highlighting = true; } @@ -2663,20 +2671,6 @@ win_line ( cur = cur->next; } - /* Cursor line highlighting for 'cursorline' in the current window. Not - * when Visual mode is active, because it's not clear what is selected - * then. */ - if (wp->w_p_cul && lnum == wp->w_cursor.lnum - && !(wp == curwin && VIsual_active)) { - if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer) - && qf_current_entry(wp) == lnum) { - line_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), line_attr); - } else { - line_attr = win_hl_attr(wp, HLF_CUL); - } - area_highlighting = true; - } - off = (unsigned)(current_ScreenLine - ScreenLines); col = 0; if (wp->w_p_rl) { @@ -3595,7 +3589,9 @@ win_line ( // Display a '$' after the line or highlight an extra // character if the line break is included. // For a diff line the highlighting continues after the "$". - if (diff_hlf == (hlf_T)0 && line_attr == 0) { + if (diff_hlf == (hlf_T)0 + && line_attr == 0 + && line_attr_low_priority == 0) { // In virtualedit, visual selections may extend beyond end of line. if (area_highlighting && virtual_active() && tocol != MAXCOL && vcol < tocol) { @@ -3659,7 +3655,7 @@ win_line ( (col < wp->w_width))) { c = ' '; ptr--; // put it back at the NUL - } else if ((diff_hlf != (hlf_T)0 || line_attr != 0) + } else if ((diff_hlf != (hlf_T)0 || line_attr_low_priority || line_attr) && (wp->w_p_rl ? (col >= 0) : (col - boguscols < wp->w_width))) { @@ -3671,7 +3667,8 @@ win_line ( did_line_attr++; // don't do search HL for the rest of the line - if (line_attr != 0 && char_attr == search_attr && col > 0) { + if ((line_attr_low_priority || line_attr) + && char_attr == search_attr && col > 0) { char_attr = line_attr; } if (diff_hlf == HLF_TXD) { @@ -4040,6 +4037,9 @@ win_line ( } } + // Apply `line_attr_low_priority` now, so that everthing can override it. + char_attr = hl_combine_attr(line_attr_low_priority, char_attr); + /* * Store character to be displayed. * Skip characters that are left of the screen for 'nowrap'. diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index d1357ea525..077b0ec14c 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -518,7 +518,7 @@ describe("'listchars' highlight", function() ]]) feed_command('set cursorline') screen:expect([[ - {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{4:>}| + {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{3:>}| {5:>-------.}abcd{5:*}{4:¬} | {4:¬} | {4:~ }| @@ -526,7 +526,7 @@ describe("'listchars' highlight", function() ]]) feed('$') screen:expect([[ - {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| + {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| {4:<} | {4:<} | {4:~ }| @@ -607,7 +607,7 @@ describe("'listchars' highlight", function() feed('$') screen:expect([[ {4:<} | - {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| + {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| {4:<} | {4:~ }| | From c0e45d97b0cbc700cd6f2b9733c15875339262df Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sat, 30 Sep 2017 21:43:03 +0800 Subject: [PATCH 38/43] vim-patch:8.0.0148 #7344 Problem: When a C preprocessor statement has two line continuations the following line does not have the right indent. (Ken Takata) Solution: Add the indent of the previous continuation line. (Hirohito Higashi) https://github.com/vim/vim/commit/c6aa475a27e3ed1645446b014c32ebf68d005d49 --- src/nvim/indent_c.c | 82 ++++++++++++--------- src/nvim/version.c | 2 +- test/functional/legacy/003_cindent_spec.lua | 34 +++++++++ 3 files changed, 83 insertions(+), 35 deletions(-) diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 4a6393ac36..279d45bb0a 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -734,16 +734,20 @@ static int cin_ispreproc(char_u *s) return FALSE; } -/* - * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a - * continuation line of a preprocessor statement. Decrease "*lnump" to the - * start and return the line in "*pp". - */ -static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump) +/// Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a +/// continuation line of a preprocessor statement. Decrease "*lnump" to the +/// start and return the line in "*pp". +/// Put the amount of indent in "*amount". +static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount) { char_u *line = *pp; linenr_T lnum = *lnump; - int retval = FALSE; + int retval = false; + int candidate_amount = *amount; + + if (*line != NUL && line[STRLEN(line) - 1] == '\\') { + candidate_amount = get_indent_lnum(lnum); + } for (;; ) { if (cin_ispreproc(line)) { @@ -758,8 +762,12 @@ static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump) break; } - if (lnum != *lnump) + if (lnum != *lnump) { *pp = ml_get(*lnump); + } + if (retval) { + *amount = candidate_amount; + } return retval; } @@ -1994,10 +2002,12 @@ int get_c_indent(void) amount = -1; for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) { l = skipwhite(ml_get(lnum)); - if (cin_nocode(l)) /* skip comment lines */ + if (cin_nocode(l)) { // skip comment lines continue; - if (cin_ispreproc_cont(&l, &lnum)) - continue; /* ignore #define, #if, etc. */ + } + if (cin_ispreproc_cont(&l, &lnum, &amount)) { + continue; // ignore #define, #if, etc. + } curwin->w_cursor.lnum = lnum; /* Skip a comment or raw string. XXX */ @@ -2353,15 +2363,14 @@ int get_c_indent(void) * up with it. */ if (curwin->w_cursor.lnum <= ourscope) { - /* we reached end of scope: - * if looking for an enum or structure initialization - * go further back: - * if it is an initializer (enum xxx or xxx =), then - * don't add ind_continuation, otherwise it is a variable - * declaration: - * int x, - * here; <-- add ind_continuation - */ + // We reached end of scope: + // If looking for a enum or structure initialization + // go further back: + // If it is an initializer (enum xxx or xxx =), then + // don't add ind_continuation, otherwise it is a variable + // declaration: + // int x, + // here; <-- add ind_continuation if (lookfor == LOOKFOR_ENUM_OR_INIT) { if (curwin->w_cursor.lnum == 0 || curwin->w_cursor.lnum @@ -2389,11 +2398,12 @@ int get_c_indent(void) continue; } - /* - * Skip preprocessor directives and blank lines. - */ - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + // + // Skip preprocessor directives and blank lines. + // + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) { continue; + } if (cin_nocode(l)) continue; @@ -2497,9 +2507,10 @@ int get_c_indent(void) continue; } - /* Skip preprocessor directives and blank lines. */ - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + // Skip preprocessor directives and blank lines. + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) { continue; + } /* Finally the actual check for "namespace". */ if (cin_is_cpp_namespace(l)) { @@ -2662,9 +2673,10 @@ int get_c_indent(void) * unlocked it) */ l = get_cursor_line_ptr(); - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum) - || cin_nocode(l)) + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount) + || cin_nocode(l)) { continue; + } /* * Are we at the start of a cpp base class declaration or @@ -3309,11 +3321,12 @@ term_again: break; } - /* - * Skip preprocessor directives and blank lines. - */ - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + // + // Skip preprocessor directives and blank lines. + // + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) { continue; + } if (cin_nocode(l)) continue; @@ -3405,9 +3418,10 @@ term_again: while (curwin->w_cursor.lnum > 1) { look = ml_get(--curwin->w_cursor.lnum); - if (!(cin_nocode(look) || cin_ispreproc_cont( - &look, &curwin->w_cursor.lnum))) + if (!(cin_nocode(look) + || cin_ispreproc_cont(&look, &curwin->w_cursor.lnum, &amount))) { break; + } } if (curwin->w_cursor.lnum > 0 && cin_ends_in(look, (char_u *)"}", NULL)) diff --git a/src/nvim/version.c b/src/nvim/version.c index 76897088a1..8bcf8c7a59 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -955,7 +955,7 @@ static const int included_patches[] = { // 151, 150, 149, - // 148, + 148, 147, 146, // 145 NA diff --git a/test/functional/legacy/003_cindent_spec.lua b/test/functional/legacy/003_cindent_spec.lua index 202baadd4c..58e87354fb 100644 --- a/test/functional/legacy/003_cindent_spec.lua +++ b/test/functional/legacy/003_cindent_spec.lua @@ -4718,4 +4718,38 @@ describe('cindent', function() JSEND ]=]) end) + + it('line continuations in macros / vim-patch 8.0.0148', function() + insert_([=[ + /* start of define */ + { + } + #define AAA \ + BBB\ + CCC + + #define CNT \ + 1 + \ + 2 + \ + 4 + /* end of define */]=]) + + feed_command('set cino&') + feed_command('/start of define') + feed('=/end of define') + + expect([=[ + /* start of define */ + { + } + #define AAA \ + BBB\ + CCC + + #define CNT \ + 1 + \ + 2 + \ + 4 + /* end of define */]=]) + end) end) From e3ca1e604630d930ddc49fccb9a1541d381b1915 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sat, 7 Oct 2017 23:20:34 +0800 Subject: [PATCH 39/43] vim-patch:8.0.0142 (#7335) see also #7082 Problem: Normal colors are wrong with 'termguicolors'. Solution: Initialize to INVALCOLOR instead of zero. (Ben Jackson, closes vim/vim#1344) https://github.com/vim/vim/commit/0cdb72aa38c4a0140c94d56bf8bc17cb30260ebf --- src/nvim/syntax.c | 2 -- src/nvim/version.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index ddc3f5c27b..8de81f02df 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6847,8 +6847,6 @@ int hl_combine_attr(int char_attr, int prim_attr) if (char_aep != NULL) { // Copy all attributes from char_aep to the new entry new_en = *char_aep; - } else { - memset(&new_en, 0, sizeof(new_en)); } spell_aep = syn_cterm_attr2entry(prim_attr); diff --git a/src/nvim/version.c b/src/nvim/version.c index 8bcf8c7a59..8015d7520d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -961,7 +961,7 @@ static const int included_patches[] = { // 145 NA // 144 NA 143, - // 142, + 142, // 141, // 140, // 139 NA From d916ea107a243768ff5b272a0bf2522e42f51b65 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 7 Oct 2017 18:05:02 +0200 Subject: [PATCH 40/43] resettitle(): remove conditions (#7360) These conditions were added in #7358 for no apparent reason. ref https://github.com/neovim/neovim/pull/7358#discussion_r143064448 --- src/nvim/buffer.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index fbfb4e02ea..fc5bb90973 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3069,13 +3069,9 @@ static bool ti_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - if (p_icon) { - ui_call_set_icon(cstr_as_string((char *)lasticon)); - } - if (p_title || p_icon) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); - ui_flush(); - } + ui_call_set_icon(cstr_as_string((char *)lasticon)); + ui_call_set_title(cstr_as_string((char *)lasttitle)); + ui_flush(); } # if defined(EXITFREE) From e565fc229412dde1378db7d4dc80ed7ac9dfbcaf Mon Sep 17 00:00:00 2001 From: timothy eichler Date: Sun, 8 Oct 2017 18:26:44 +0200 Subject: [PATCH 41/43] gitignore: cmake-build-debug (#7359) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3a8994a5f6..61b96c158f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Build/deps dir /build/ +/cmake-build-debug/ /dist/ /.deps/ /tmp/ From 1663599bebd7bd360f116b003b9f572b01d7a8d8 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 9 Oct 2017 00:52:57 +0800 Subject: [PATCH 42/43] vim-patch:8.0.0164 (#7368) Problem: Outdated and misplaced comments. Solution: Fix the comments. https://github.com/vim/vim/commit/caa55b65c204946d160c1b743c5f8f3b506dc4d3 --- src/nvim/charset.c | 2 +- src/nvim/eval.c | 2 +- src/nvim/getchar.c | 25 ++++++++++--------------- src/nvim/version.c | 2 +- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 403ef65c4f..577fc13a31 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -762,7 +762,7 @@ bool vim_isIDc(int c) } /// Check that "c" is a keyword character: -/// Letters and characters from 'iskeyword' option for current buffer. +/// Letters and characters from 'iskeyword' option for the current buffer. /// For multi-byte characters mb_get_class() is used (builtin rules). /// /// @param c character to check diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 86b99c2783..b2a0d9a767 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17528,7 +17528,7 @@ static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_dict_add_nr(dict, S_LEN("skipcol"), (varnumber_T)curwin->w_skipcol); } -/// Writes list of strings to file +/// Write "list" of strings to file "fd". /// /// @param fp File to write to. /// @param[in] list List to write. diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index f5949333bd..4f8a8528a0 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -868,20 +868,15 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent) addlen = (int)STRLEN(str); - /* - * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off] - */ if (offset == 0 && addlen <= typebuf.tb_off) { + // Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off] typebuf.tb_off -= addlen; memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen); - } - /* - * Need to allocate a new buffer. - * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4 - * characters. We add some extra room to avoid having to allocate too - * often. - */ - else { + } else { + // Need to allocate a new buffer. + // In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4 + // characters. We add some extra room to avoid having to allocate too + // often. newoff = MAXMAPLEN + 4; newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4); if (newlen < 0) { /* string is getting too long */ @@ -1663,10 +1658,10 @@ static int vgetorpeek(int advance) } if (c != NUL && !got_int) { if (advance) { - /* KeyTyped = FALSE; When the command that stuffed something - * was typed, behave like the stuffed command was typed. - * needed for CTRL-W CTRl-] to open a fold, for example. */ - KeyStuffed = TRUE; + // KeyTyped = FALSE; When the command that stuffed something + // was typed, behave like the stuffed command was typed. + // needed for CTRL-W CTRL-] to open a fold, for example. + KeyStuffed = true; } if (typebuf.tb_no_abbr_cnt == 0) typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */ diff --git a/src/nvim/version.c b/src/nvim/version.c index 8015d7520d..11ae3f11b6 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -939,7 +939,7 @@ static const int included_patches[] = { 167, // 166, 165, - // 164, + 164, // 163 NA // 162 NA // 161 NA From 52517321d1859c31fef14aa75d784615693fcecb Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 8 Oct 2017 20:23:11 +0200 Subject: [PATCH 43/43] test: nvim_get_hl_by_name/by_id #7082 - test all properties - test failure modes --- src/nvim/api/vim.c | 1 - src/nvim/syntax.c | 9 +-- test/functional/api/highlight_spec.lua | 77 +++++++++++++++++++++----- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index bc89ffefe6..98f4410347 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -33,7 +33,6 @@ #include "nvim/syntax.h" #include "nvim/getchar.h" #include "nvim/os/input.h" -#include "nvim/ui.h" #define LINE_BUFFER_SIZE 4096 diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index f59495f660..0224b28c2a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -7127,8 +7127,7 @@ syn_list_header(int did_header, int outlen, int id) /// Set the attribute numbers for a highlight group. /// Called after one of the attributes has changed. /// @param idx corrected highlight index -static void -set_hl_attr(int idx) +static void set_hl_attr(int idx) { attrentry_T at_en = ATTRENTRY_INIT; struct hl_group *sgp = HL_TABLE() + idx; @@ -8241,9 +8240,7 @@ RgbValue name_to_color(const uint8_t *name) return -1; } -/// Retrieves attribute description from its id -/// -/// @param attr_id attribute id +/// Gets highlight description for id `attr_id` as a map. Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) { HlAttrs attrs = HLATTRS_INIT; @@ -8256,7 +8253,7 @@ Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); if (!aep) { api_set_error(err, kErrorTypeException, - "Invalid attribute id %d", attr_id); + "Invalid attribute id: %d", attr_id); return dic; } diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index c482128a31..2297a0760f 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -6,15 +6,26 @@ local command = helpers.command local meths = helpers.meths describe('highlight api',function() - local expected_rgb = { background = Screen.colors.Yellow, - foreground = Screen.colors.Red, - special = Screen.colors.Blue, - bold = true, - } - - local expected_cterm = { background = 10, - underline = true, - } + local expected_rgb = { + background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Blue, + bold = true, + } + local expected_cterm = { + background = 10, + underline = true, + } + local expected_rgb2 = { + background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Blue, + bold = true, + italic = true, + reverse = true, + undercurl = true, + underline = true, + } before_each(function() clear() @@ -26,31 +37,67 @@ describe('highlight api',function() eq(expected_cterm, nvim("get_hl_by_id", hl_id, false)) hl_id = eval("hlID('NewHighlight')") + -- Test valid id. eq(expected_rgb, nvim("get_hl_by_id", hl_id, true)) - local expected_error = 'Invalid highlight id' - -- Assume there is no hl id 30000. + -- Test invalid id. local err, emsg = pcall(meths.get_hl_by_id, 30000, false) eq(false, err) - eq(expected_error, string.match(emsg, expected_error)) + eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*')) + + -- Test all highlight properties. + command('hi NewHighlight gui=underline,bold,undercurl,italic,reverse') + eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true)) + + -- Test nil argument. + err, emsg = pcall(meths.get_hl_by_id, { nil }, false) + eq(false, err) + eq('Wrong type for argument 1, expecting Integer', + string.match(emsg, 'Wrong.*')) + + -- Test 0 argument. + err, emsg = pcall(meths.get_hl_by_id, 0, false) + eq(false, err) + eq('Invalid highlight id: 0', + string.match(emsg, 'Invalid.*')) + + -- Test -1 argument. + err, emsg = pcall(meths.get_hl_by_id, -1, false) + eq(false, err) + eq('Invalid highlight id: -1', + string.match(emsg, 'Invalid.*')) end) it("nvim_get_hl_by_name", function() local expected_normal = { background = Screen.colors.Yellow, foreground = Screen.colors.Red } - -- Test "Normal" hl defaults. + -- Test `Normal` default values. eq({}, nvim("get_hl_by_name", 'Normal', true)) eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight', false)) eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight', true)) + -- Test `Normal` modified values. command('hi Normal guifg=red guibg=yellow') eq(expected_normal, nvim("get_hl_by_name", 'Normal', true)) - local expected_error = 'Invalid highlight name' + -- Test invalid name. local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight', false) eq(false, err) - eq(expected_error, string.match(emsg, expected_error)) + eq('Invalid highlight name: unknown_highlight', + string.match(emsg, 'Invalid.*')) + + -- Test nil argument. + err, emsg = pcall(meths.get_hl_by_name , { nil }, false) + eq(false, err) + eq('Wrong type for argument 1, expecting String', + string.match(emsg, 'Wrong.*')) + + -- Test empty string argument. + err, emsg = pcall(meths.get_hl_by_name , '', false) + eq(false, err) + eq('Invalid highlight name: ', + string.match(emsg, 'Invalid.*')) end) end)