aboutsummaryrefslogtreecommitdiff
path: root/test/functional/legacy/search_spec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/legacy/search_spec.lua')
-rw-r--r--test/functional/legacy/search_spec.lua474
1 files changed, 474 insertions, 0 deletions
diff --git a/test/functional/legacy/search_spec.lua b/test/functional/legacy/search_spec.lua
new file mode 100644
index 0000000000..5f71861821
--- /dev/null
+++ b/test/functional/legacy/search_spec.lua
@@ -0,0 +1,474 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local eval = helpers.eval
+local feed = helpers.feed
+local funcs = helpers.funcs
+
+describe('search cmdline', function()
+ local screen
+
+ before_each(function()
+ clear()
+ command('set nohlsearch')
+ screen = Screen.new(20, 3)
+ screen:attach()
+ screen:set_default_attr_ids({
+ inc = {reverse = true}
+ })
+ end)
+
+ local function tenlines()
+ funcs.setline(1, {
+ ' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there',
+ ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'
+ })
+ command('1')
+ end
+
+ it('history can be navigated with <C-N>/<C-P>', function()
+ tenlines()
+ command('set noincsearch')
+ feed('/foobar<CR>')
+ feed('/the<CR>')
+ eq('the', eval('@/'))
+ feed('/thes<C-P><C-P><CR>')
+ eq('foobar', eval('@/'))
+ end)
+
+ describe('can traverse matches', function()
+ before_each(tenlines)
+ local function forwarditer(wrapscan)
+ command('set incsearch '..wrapscan)
+ feed('/the')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 2 these |
+ 3 {inc:the} |
+ /the^ |
+ ]])
+ eq({0, 0, 0, 0}, funcs.getpos('"'))
+ feed('<C-G>')
+ screen:expect([[
+ 3 the |
+ 4 {inc:the}ir |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 4 their |
+ 5 {inc:the}re |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 5 there |
+ 6 {inc:the}ir |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 6 their |
+ 7 {inc:the} |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 7 the |
+ 8 {inc:the}m |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 8 them |
+ 9 {inc:the}se |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ if wrapscan == 'wrapscan' then
+ screen:expect([[
+ 2 {inc:the}se |
+ 3 the |
+ /the^ |
+ ]])
+ else
+ screen:expect([[
+ 8 them |
+ 9 {inc:the}se |
+ /the^ |
+ ]])
+ feed('<CR>')
+ eq({0, 0, 0, 0}, funcs.getpos('"'))
+ end
+ end
+
+ local function backiter(wrapscan)
+ command('set incsearch '..wrapscan)
+ command('$')
+
+ feed('?the')
+ screen:expect([[
+ 9 {inc:the}se |
+ 10 foobar |
+ ?the^ |
+ ]])
+ if wrapscan == 'wrapscan' then
+ feed('<C-G>')
+ screen:expect([[
+ 2 {inc:the}se |
+ 3 the |
+ ?the^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ 2 ^these |
+ 3 the |
+ ?the |
+ ]])
+ else
+ feed('<C-G>')
+ screen:expect([[
+ 9 {inc:the}se |
+ 10 foobar |
+ ?the^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ 9 ^these |
+ 10 foobar |
+ ?the |
+ ]])
+ end
+ command('$')
+ feed('?the')
+ screen:expect([[
+ 9 {inc:the}se |
+ 10 foobar |
+ ?the^ |
+ ]])
+ feed('<C-T>')
+ screen:expect([[
+ 8 {inc:the}m |
+ 9 these |
+ ?the^ |
+ ]])
+ for i = 1, 6 do
+ feed('<C-T>')
+ -- Avoid sleep just before expect, otherwise expect will take the full
+ -- timeout
+ if i ~= 6 then
+ screen:sleep(1)
+ end
+ end
+ screen:expect([[
+ 2 {inc:the}se |
+ 3 the |
+ ?the^ |
+ ]])
+ feed('<C-T>')
+ if wrapscan == 'wrapscan' then
+ screen:expect([[
+ 9 {inc:the}se |
+ 10 foobar |
+ ?the^ |
+ ]])
+ else
+ screen:expect([[
+ 2 {inc:the}se |
+ 3 the |
+ ?the^ |
+ ]])
+ end
+ end
+
+ it("using <C-G> and 'nowrapscan'", function()
+ forwarditer('nowrapscan')
+ end)
+
+ it("using <C-G> and 'wrapscan'", function()
+ forwarditer('wrapscan')
+ end)
+
+ it("using <C-T> and 'nowrapscan'", function()
+ backiter('nowrapscan')
+ end)
+
+ it("using <C-T> and 'wrapscan'", function()
+ backiter('wrapscan')
+ end)
+ end)
+
+ it('expands pattern with <C-L>', function()
+ tenlines()
+ command('set incsearch wrapscan')
+
+ feed('/the')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+ feed('<C-L>')
+ screen:expect([[
+ 1 |
+ 2 {inc:thes}e |
+ /thes^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 9 {inc:thes}e |
+ 10 foobar |
+ /thes^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 2 {inc:thes}e |
+ 3 the |
+ /thes^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ 2 ^these |
+ 3 the |
+ /thes |
+ ]])
+
+ command('1')
+ command('set nowrapscan')
+ feed('/the')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+ feed('<C-L>')
+ screen:expect([[
+ 1 |
+ 2 {inc:thes}e |
+ /thes^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 9 {inc:thes}e |
+ 10 foobar |
+ /thes^ |
+ ]])
+ feed('<C-G><CR>')
+ screen:expect([[
+ 9 ^these |
+ 10 foobar |
+ /thes |
+ ]])
+ end)
+
+ it('reduces pattern with <BS> and keeps cursor position', function()
+ tenlines()
+ command('set incsearch wrapscan')
+
+ -- First match
+ feed('/thei')
+ screen:expect([[
+ 4 {inc:thei}r |
+ 5 there |
+ /thei^ |
+ ]])
+ -- Match from initial cursor position when modifying search
+ feed('<BS>')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+ -- New text advances to next match
+ feed('s')
+ screen:expect([[
+ 1 |
+ 2 {inc:thes}e |
+ /thes^ |
+ ]])
+ -- Stay on this match when deleting a character
+ feed('<BS>')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+ -- Advance to previous match
+ feed('<C-T>')
+ screen:expect([[
+ 9 {inc:the}se |
+ 10 foobar |
+ /the^ |
+ ]])
+ -- Extend search to include next character
+ feed('<C-L>')
+ screen:expect([[
+ 9 {inc:thes}e |
+ 10 foobar |
+ /thes^ |
+ ]])
+ -- Deleting all characters resets the cursor position
+ feed('<BS><BS><BS><BS>')
+ screen:expect([[
+ 1 |
+ 2 these |
+ /^ |
+ ]])
+ feed('the')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+ feed('\\>')
+ screen:expect([[
+ 2 these |
+ 3 {inc:the} |
+ /the\>^ |
+ ]])
+ end)
+
+ it('can traverse matches in the same line with <C-G>/<C-T>', function()
+ funcs.setline(1, { ' 1', ' 2 these', ' 3 the theother' })
+ command('1')
+ command('set incsearch')
+
+ -- First match
+ feed('/the')
+ screen:expect([[
+ 1 |
+ 2 {inc:the}se |
+ /the^ |
+ ]])
+
+ -- Next match, different line
+ feed('<C-G>')
+ screen:expect([[
+ 2 these |
+ 3 {inc:the} theother |
+ /the^ |
+ ]])
+
+ -- Next match, same line
+ feed('<C-G>')
+ screen:expect([[
+ 2 these |
+ 3 the {inc:the}other |
+ /the^ |
+ ]])
+ feed('<C-G>')
+ screen:expect([[
+ 2 these |
+ 3 the theo{inc:the}r |
+ /the^ |
+ ]])
+
+ -- Previous match, same line
+ feed('<C-T>')
+ screen:expect([[
+ 2 these |
+ 3 the {inc:the}other |
+ /the^ |
+ ]])
+ feed('<C-T>')
+ screen:expect([[
+ 2 these |
+ 3 {inc:the} theother |
+ /the^ |
+ ]])
+
+ -- Previous match, different line
+ feed('<C-T>')
+ screen:expect([[
+ 2 {inc:the}se |
+ 3 the theother |
+ /the^ |
+ ]])
+ end)
+
+ it('keeps the view after deleting a char from the search', function()
+ screen:detach()
+ screen = Screen.new(20, 6)
+ screen:attach()
+ screen:set_default_attr_ids({
+ inc = {reverse = true}
+ })
+ screen:set_default_attr_ignore({
+ {bold=true, reverse=true}, {bold=true, foreground=Screen.colors.Blue1}
+ })
+ tenlines()
+
+ feed('/foo')
+ screen:expect([[
+ 6 their |
+ 7 the |
+ 8 them |
+ 9 these |
+ 10 {inc:foo}bar |
+ /foo^ |
+ ]])
+ feed('<BS>')
+ screen:expect([[
+ 6 their |
+ 7 the |
+ 8 them |
+ 9 these |
+ 10 {inc:fo}obar |
+ /fo^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ 6 their |
+ 7 the |
+ 8 them |
+ 9 these |
+ 10 ^foobar |
+ /fo |
+ ]])
+ eq({lnum = 10, leftcol = 0, col = 4, topfill = 0, topline = 6,
+ coladd = 0, skipcol = 0, curswant = 4},
+ funcs.winsaveview())
+ end)
+
+ it('restores original view after failed search', function()
+ screen:detach()
+ screen = Screen.new(40, 3)
+ screen:attach()
+ screen:set_default_attr_ids({
+ inc = {reverse = true},
+ err = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
+ more = { bold = true, foreground = Screen.colors.SeaGreen4 },
+ })
+ tenlines()
+ feed('0')
+ feed('/foo')
+ screen:expect([[
+ 9 these |
+ 10 {inc:foo}bar |
+ /foo^ |
+ ]])
+ feed('<C-W>')
+ screen:expect([[
+ 1 |
+ 2 these |
+ /^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ / |
+ {err:E35: No previous regular expression} |
+ {more:Press ENTER or type command to continue}^ |
+ ]])
+ feed('<CR>')
+ eq({lnum = 1, leftcol = 0, col = 0, topfill = 0, topline = 1,
+ coladd = 0, skipcol = 0, curswant = 0},
+ funcs.winsaveview())
+ end)
+end)