diff options
Diffstat (limited to 'test/functional/ui/cmdline_spec.lua')
| -rw-r--r-- | test/functional/ui/cmdline_spec.lua | 681 | 
1 files changed, 681 insertions, 0 deletions
| diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua new file mode 100644 index 0000000000..f8680678ef --- /dev/null +++ b/test/functional/ui/cmdline_spec.lua @@ -0,0 +1,681 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') +local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq +local source = helpers.source +local ok = helpers.ok +local command = helpers.command + +describe('external cmdline', function() +  local screen +  local last_level = 0 +  local cmdline = {} +  local block = nil +  local wild_items = nil +  local wild_selected = nil + +  before_each(function() +    clear() +    cmdline, block = {}, nil +    screen = Screen.new(25, 5) +    screen:attach({rgb=true, ext_cmdline=true}) +    screen:set_default_attr_ids({ +      [1] = {bold = true, foreground = Screen.colors.Blue1}, +      [2] = {reverse = true}, +      [3] = {bold = true, reverse = true}, +    }) +    screen:set_on_event_handler(function(name, data) +      if name == "cmdline_show" then +        local content, pos, firstc, prompt, indent, level = unpack(data) +        ok(level > 0) +        cmdline[level] = {content=content, pos=pos, firstc=firstc, +                          prompt=prompt, indent=indent} +        last_level = level +      elseif name == "cmdline_hide" then +        local level = data[1] +        cmdline[level] = nil +      elseif name == "cmdline_special_char" then +        local char, shift, level = unpack(data) +        cmdline[level].special = {char, shift} +      elseif name == "cmdline_pos" then +        local pos, level = unpack(data) +        cmdline[level].pos = pos +      elseif name == "cmdline_block_show" then +        block = data[1] +      elseif name == "cmdline_block_append" then +        block[#block+1] = data[1] +      elseif name == "cmdline_block_hide" then +        block = nil +      elseif name == "wildmenu_show" then +        wild_items = data[1] +      elseif name == "wildmenu_select" then +        wild_selected = data[1] +      elseif name == "wildmenu_hide" then +        wild_items, wild_selected = nil, nil +      end +    end) +  end) + +  after_each(function() +    screen:detach() +  end) + +  local function expect_cmdline(level, expected) +    local attr_ids = screen._default_attr_ids +    local attr_ignore = screen._default_attr_ignore +    local actual = '' +    for _, chunk in ipairs(cmdline[level] and cmdline[level].content or {}) do +      local attrs, text = chunk[1], chunk[2] +      if screen:_equal_attrs(attrs, {}) then +        actual = actual..text +      else +        local attr_id = screen:_get_attr_id(attr_ids, attr_ignore, attrs) +        actual =  actual..'{' .. attr_id .. ':' .. text .. '}' +      end +    end +    eq(expected, actual) +  end + +  it('works', function() +    feed(':') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq(1, last_level) +      eq({{ +        content = { { {}, "" } }, +        firstc = ":", +        indent = 0, +        pos = 0, +        prompt = "" +      }}, cmdline) +    end) + +    feed('sign') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign" } }, +        firstc = ":", +        indent = 0, +        pos = 4, +        prompt = "" +      }}, cmdline) +    end) + +    feed('<Left>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign" } }, +        firstc = ":", +        indent = 0, +        pos = 3, +        prompt = "" +      }}, cmdline) +    end) + +    feed('<bs>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sin" } }, +        firstc = ":", +        indent = 0, +        pos = 2, +        prompt = "" +      }}, cmdline) +    end) + +    feed('<Esc>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({}, cmdline) +    end) +  end) + +  it("works with input()", function() +    feed(':call input("input", "default")<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "default" } }, +        firstc = "", +        indent = 0, +        pos = 7, +        prompt = "input" +      }}, cmdline) +    end) +    feed('<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({}, cmdline) +    end) + +  end) + +  it("works with special chars and nested cmdline", function() +    feed(':xx<c-r>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "xx" } }, +        firstc = ":", +        indent = 0, +        pos = 2, +        prompt = "", +        special = {'"', true}, +      }}, cmdline) +    end) + +    feed('=') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "xx" } }, +        firstc = ":", +        indent = 0, +        pos = 2, +        prompt = "", +        special = {'"', true}, +      },{ +        content = { { {}, "" } }, +        firstc = "=", +        indent = 0, +        pos = 0, +        prompt = "", +      }}, cmdline) +    end) + +    feed('1+2') +    local expectation = {{ +        content = { { {}, "xx" } }, +        firstc = ":", +        indent = 0, +        pos = 2, +        prompt = "", +        special = {'"', true}, +      },{ +        content = { +          { {}, "1" }, +          { {}, "+" }, +          { {}, "2" }, +        }, +        firstc = "=", +        indent = 0, +        pos = 3, +        prompt = "", +      }} +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq(expectation, cmdline) +    end) + +    -- erase information, so we check if it is retransmitted +    cmdline = {} +    command("redraw!") +    -- redraw! forgets cursor position. Be OK with that, as UI should indicate +    -- focus is at external cmdline anyway. +    screen:expect([[ +                               | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +      ^                         | +    ]], nil, nil, function() +      eq(expectation, cmdline) +    end) + + +    feed('<cr>') +    screen:expect([[ +                               | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +      ^                         | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "xx3" } }, +        firstc = ":", +        indent = 0, +        pos = 3, +        prompt = "", +      }}, cmdline) +    end) + +    feed('<esc>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({}, cmdline) +    end) +  end) + +  it("works with function definitions", function() +    feed(':function Foo()<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "" } }, +        firstc = ":", +        indent = 2, +        pos = 0, +        prompt = "", +      }}, cmdline) +      eq({ { { {}, 'function Foo()'} } }, block) +    end) + +    feed('line1<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({ { { {}, 'function Foo()'} }, +           { { {}, '  line1'} } }, block) +    end) + +    block = {} +    command("redraw!") +    screen:expect([[ +                               | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +      ^                         | +    ]], nil, nil, function() +      eq({ { { {}, 'function Foo()'} }, +           { { {}, '  line1'} } }, block) +    end) + +    feed('endfunction<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq(nil, block) +    end) + +    -- Try once more, to check buffer is reinitialized. #8007 +    feed(':function Bar()<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "" } }, +        firstc = ":", +        indent = 2, +        pos = 0, +        prompt = "", +      }}, cmdline) +      eq({ { { {}, 'function Bar()'} } }, block) +    end) + +    feed('endfunction<cr>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq(nil, block) +    end) +  end) + +  it("works with cmdline window", function() +    feed(':make') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "make" } }, +        firstc = ":", +        indent = 0, +        pos = 4, +        prompt = "" +      }}, cmdline) +    end) + +    feed('<c-f>') +    screen:expect([[ +                               | +      {2:[No Name]                }| +      {1::}make^                    | +      {3:[Command Line]           }| +                               | +    ]], nil, nil, function() +      eq({}, cmdline) +    end) + +    -- nested cmdline +    feed(':yank') +    screen:expect([[ +                               | +      {2:[No Name]                }| +      {1::}make^                    | +      {3:[Command Line]           }| +                               | +    ]], nil, nil, function() +      eq({nil, { +        content = { { {}, "yank" } }, +        firstc = ":", +        indent = 0, +        pos = 4, +        prompt = "" +      }}, cmdline) +    end) + +    cmdline = {} +    command("redraw!") +    screen:expect([[ +                               | +      {2:[No Name]                }| +      {1::}make                    | +      {3:[Command Line]           }| +      ^                         | +    ]], nil, nil, function() +      eq({nil, { +        content = { { {}, "yank" } }, +        firstc = ":", +        indent = 0, +        pos = 4, +        prompt = "" +      }}, cmdline) +    end) + +    feed("<c-c>") +    screen:expect([[ +                               | +      {2:[No Name]                }| +      {1::}make^                    | +      {3:[Command Line]           }| +                               | +    ]], nil, nil, function() +      eq({}, cmdline) +    end) + +    feed("<c-c>") +    screen:expect([[ +                               | +      {2:[No Name]                }| +      {1::}make^                    | +      {3:[Command Line]           }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "make" } }, +        firstc = ":", +        indent = 0, +        pos = 4, +        prompt = "" +      }}, cmdline) +    end) + +    cmdline = {} +    command("redraw!") +    screen:expect([[ +                               | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +      ^                         | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "make" } }, +        firstc = ":", +        indent = 0, +        pos = 4, +        prompt = "" +      }}, cmdline) +    end) +  end) + +  it('works with inputsecret()', function() +    feed(":call inputsecret('secret:')<cr>abc123") +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "******" } }, +        firstc = "", +        indent = 0, +        pos = 6, +        prompt = "secret:" +      }}, cmdline) +    end) +  end) + +  it('works with highlighted cmdline', function() +    source([[ +      highlight RBP1 guibg=Red +      highlight RBP2 guibg=Yellow +      highlight RBP3 guibg=Green +      highlight RBP4 guibg=Blue +      let g:NUM_LVLS = 4 +      function RainBowParens(cmdline) +        let ret = [] +        let i = 0 +        let lvl = 0 +        while i < len(a:cmdline) +          if a:cmdline[i] is# '(' +            call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) +            let lvl += 1 +          elseif a:cmdline[i] is# ')' +            let lvl -= 1 +            call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) +          endif +          let i += 1 +        endwhile +        return ret +      endfunction +      map <f5>  :let x = input({'prompt':'>','highlight':'RainBowParens'})<cr> +      "map <f5>  :let x = input({'prompt':'>'})<cr> +    ]]) +    screen:set_default_attr_ids({ +      RBP1={background = Screen.colors.Red}, +      RBP2={background = Screen.colors.Yellow}, +      RBP3={background = Screen.colors.Green}, +      RBP4={background = Screen.colors.Blue}, +      EOB={bold = true, foreground = Screen.colors.Blue1}, +      ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red}, +      SK={foreground = Screen.colors.Blue}, +      PE={bold = true, foreground = Screen.colors.SeaGreen4} +    }) +    feed('<f5>(a(b)a)') +    screen:expect([[ +      ^                         | +      {EOB:~                        }| +      {EOB:~                        }| +      {EOB:~                        }| +                               | +    ]], nil, nil, function() +      expect_cmdline(1, '{RBP1:(}a{RBP2:(}b{RBP2:)}a{RBP1:)}') +    end) +  end) + +  it('works together with ext_wildmenu', function() +    local expected = { +      'define', +      'jump', +      'list', +      'place', +      'undefine', +      'unplace', +    } + +    command('set wildmode=full') +    command('set wildmenu') +    screen:set_option('ext_wildmenu', true) +    feed(':sign <tab>') + +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign define"} }, +        firstc = ":", +        indent = 0, +        pos = 11, +        prompt = "" +      }}, cmdline) +      eq(expected, wild_items) +      eq(0, wild_selected) +    end) + +    feed('<tab>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign jump"} }, +        firstc = ":", +        indent = 0, +        pos = 9, +        prompt = "" +      }}, cmdline) +      eq(expected, wild_items) +      eq(1, wild_selected) +    end) + +    feed('<left><left>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign "} }, +        firstc = ":", +        indent = 0, +        pos = 5, +        prompt = "" +      }}, cmdline) +      eq(expected, wild_items) +      eq(-1, wild_selected) +    end) + +    feed('<right>') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign define"} }, +        firstc = ":", +        indent = 0, +        pos = 11, +        prompt = "" +      }}, cmdline) +      eq(expected, wild_items) +      eq(0, wild_selected) +    end) + +    feed('a') +    screen:expect([[ +      ^                         | +      {1:~                        }| +      {1:~                        }| +      {1:~                        }| +                               | +    ]], nil, nil, function() +      eq({{ +        content = { { {}, "sign definea"} }, +        firstc = ":", +        indent = 0, +        pos = 12, +        prompt = "" +      }}, cmdline) +      eq(nil, wild_items) +      eq(nil, wild_selected) +    end) +  end) +end) | 
