local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, command = helpers.clear, helpers.feed, helpers.command local source = helpers.source describe('Signs', function() local screen before_each(function() clear() screen = Screen.new() screen:attach() screen:set_default_attr_ids( { [0] = {bold=true, foreground=255}, [1] = {background = Screen.colors.Yellow}, [2] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey}, [3] = {background = Screen.colors.Gray90}, [4] = {bold = true, reverse = true}, [5] = {reverse = true}, [6] = {foreground = Screen.colors.Brown}, [7] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, [8] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, [9] = {bold = true, foreground = Screen.colors.Magenta}, [10] = {foreground = Screen.colors.Blue1}, [11] = {bold = true, foreground = Screen.colors.SeaGreen4}, } ) end) describe(':sign place', function() it('allows signs with combining characters', function() feed('iab') command('sign define piet1 text=𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄ texthl=Search') command('sign define piet2 text=𠜎̀́̂̃̄̅ texthl=Search') command('sign place 1 line=1 name=piet1 buffer=1') command('sign place 2 line=2 name=piet2 buffer=1') screen:expect([[ {1:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}a | {1:𠜎̀́̂̃̄̅}b | {2: }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('shadows previously placed signs', function() feed('iabc') command('sign define piet text=>> texthl=Search') command('sign define pietx text=>! texthl=Search') command('sign place 1 line=1 name=piet buffer=1') command('sign place 2 line=3 name=piet buffer=1') command('sign place 3 line=1 name=pietx buffer=1') screen:expect([[ {1:>!}a | {2: }b | {1:>>}c | {2: }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('allows signs with no text', function() feed('iab') command('sign define piet1 text= texthl=Search') command('sign place 1 line=1 name=piet1 buffer=1') screen:expect([[ a | b | ^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('can be called right after :split', function() feed('iabcgg') -- This used to cause a crash due to :sign using a special redraw -- (not updating nvim's specific highlight data structures) -- without proper redraw first, as split just flags for redraw later. source([[ set cursorline sign define piet text=>> texthl=Search split sign place 3 line=2 name=piet buffer=1 ]]) screen:expect([[ {2: }{3:^a }| {1:>>}b | {2: }c | {2: } | {0:~ }| {0:~ }| {4:[No Name] [+] }| {2: }{3:a }| {1:>>}b | {2: }c | {2: } | {0:~ }| {5:[No Name] [+] }| | ]]) end) it('can combine text, linehl and numhl', function() feed('iabc') command('set number') command('sign define piet text=>> texthl=Search') command('sign define pietx linehl=ErrorMsg') command('sign define pietxx numhl=Folded') command('sign place 1 line=1 name=piet buffer=1') command('sign place 2 line=2 name=pietx buffer=1') command('sign place 3 line=3 name=pietxx buffer=1') command('sign place 4 line=4 name=piet buffer=1') command('sign place 5 line=4 name=pietx buffer=1') command('sign place 6 line=4 name=pietxx buffer=1') screen:expect([[ {1:>>}{6: 1 }a | {2: }{6: 2 }{8:b }| {2: }{7: 3 }c | {1:>>}{7: 4 }{8:^ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('higlights the cursorline sign with culhl', function() feed('iabc') command('sign define piet text=>> texthl=Search culhl=ErrorMsg') command('sign place 1 line=1 name=piet buffer=1') command('sign place 2 line=2 name=piet buffer=1') command('sign place 3 line=3 name=piet buffer=1') command('set cursorline') screen:expect([[ {1:>>}a | {1:>>}b | {8:>>}{3:^c }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) feed('k') screen:expect([[ {1:>>}a | {8:>>}{3:^b }| {1:>>}c | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) command('set nocursorline') screen:expect([[ {1:>>}a | {1:>>}^b | {1:>>}c | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) command('set cursorline cursorlineopt=line') screen:expect([[ {1:>>}a | {1:>>}{3:^b }| {1:>>}c | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) command('set cursorlineopt=number') screen:expect([[ {1:>>}a | {8:>>}^b | {1:>>}c | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('multiple signs #9295', function() feed('iabc') command('set number') command('set signcolumn=yes:2') command('sign define pietSearch text=>> texthl=Search') command('sign define pietError text=XX texthl=Error') command('sign define pietWarn text=WW texthl=Warning') command('sign place 1 line=1 name=pietSearch buffer=1') command('sign place 2 line=1 name=pietError buffer=1') -- Line 2 helps checking that signs in the same line are ordered by Id. command('sign place 4 line=2 name=pietSearch buffer=1') command('sign place 3 line=2 name=pietError buffer=1') -- Line 3 checks that with a limit over the maximum number -- of signs, the ones with the highest Ids are being picked, -- and presented by their sorted Id order. command('sign place 4 line=3 name=pietSearch buffer=1') command('sign place 5 line=3 name=pietWarn buffer=1') command('sign place 3 line=3 name=pietError buffer=1') screen:expect([[ {1:>>}{8:XX}{6: 1 }a | {8:XX}{1:>>}{6: 2 }b | {1:>>}WW{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- With the default setting, we get the sign with the top id. command('set signcolumn=yes:1') screen:expect([[ {8:XX}{6: 1 }a | {1:>>}{6: 2 }b | WW{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- "auto:3" accommodates all the signs we defined so far. command('set signcolumn=auto:3') screen:expect([[ {1:>>}{8:XX}{2: }{6: 1 }a | {8:XX}{1:>>}{2: }{6: 2 }b | {8:XX}{1:>>}WW{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- Check "yes:9". command('set signcolumn=yes:9') screen:expect([[ {1:>>}{8:XX}{2: }{6: 1 }a | {8:XX}{1:>>}{2: }{6: 2 }b | {8:XX}{1:>>}WW{2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- Check "auto:N" larger than the maximum number of signs defined in -- a single line (same result as "auto:3"). command('set signcolumn=auto:4') screen:expect{grid=[[ {1:>>}{8:XX}{2: }{6: 1 }a | {8:XX}{1:>>}{2: }{6: 2 }b | {8:XX}{1:>>}WW{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]} -- line deletion deletes signs. command('2d') screen:expect([[ {1:>>}{8:XX}{2: }{6: 1 }a | {8:XX}{1:>>}WW{6: 2 }^c | {2: }{6: 3 } | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('auto-resize sign column with minimum size (#13783)', function() feed('iabc') command('set number') -- sign column should always accommodate at the minimum size command('set signcolumn=auto:1-3') screen:expect([[ {2: }{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- should support up to 8 signs at minimum command('set signcolumn=auto:8-9') screen:expect([[ {2: }{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- should keep the same sign size when signs are not exceeding -- the minimum command('set signcolumn=auto:2-5') command('sign define pietSearch text=>> texthl=Search') command('sign place 1 line=1 name=pietSearch buffer=1') screen:expect([[ {1:>>}{2: }{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- should resize itself when signs are exceeding minimum but -- not over the maximum command('sign place 2 line=1 name=pietSearch buffer=1') command('sign place 3 line=1 name=pietSearch buffer=1') command('sign place 4 line=1 name=pietSearch buffer=1') screen:expect([[ {1:>>>>>>>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- should keep the column at maximum size when signs are -- exceeding the maximum command('sign place 5 line=1 name=pietSearch buffer=1') command('sign place 6 line=1 name=pietSearch buffer=1') command('sign place 7 line=1 name=pietSearch buffer=1') command('sign place 8 line=1 name=pietSearch buffer=1') screen:expect([[ {1:>>>>>>>>>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('ignores signs with no icon and text when calculating the signcolumn width', function() feed('iabc') command('set number') command('set signcolumn=auto:2') command('sign define pietSearch text=>> texthl=Search') command('sign define pietError text= texthl=Error') command('sign place 2 line=1 name=pietError buffer=1') -- no signcolumn with only empty sign screen:expect([[ {6: 1 }a | {6: 2 }b | {6: 3 }c | {6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) -- single column with 1 sign with text and one sign without command('sign place 1 line=1 name=pietSearch buffer=1') screen:expect([[ {1:>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('shows the line number when signcolumn=number but no marks on a line have text', function() feed('iabc') command('set number signcolumn=number') command('sign define pietSearch text=>> texthl=Search numhl=Error') command('sign define pietError text= texthl=Search numhl=Error') command('sign place 1 line=1 name=pietSearch buffer=1') command('sign place 2 line=2 name=pietError buffer=1') -- no signcolumn, line number for "a" is Search, for "b" is Error, for "c" is LineNr screen:expect([[ {1: >> }a | {8: 2 }b | {6: 3 }c | {6: 4 }^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) it('can have 32bit sign IDs', function() command('sign define piet text=>> texthl=Search') command('sign place 100000 line=1 name=piet buffer=1') feed(':sign place') screen:expect([[ {1:>>} | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {4: }| :sign place | {9:--- Signs ---} | {10:Signs for [NULL]:} | line=1 id=100000 name=piet priority=10 | | {11:Press ENTER or type command to continue}^ | ]]) feed('') screen:expect([[ {1:>>}^ | {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| {0:~ }| | ]]) end) end) end)