aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/README.md269
-rw-r--r--test/functional/api/highlight_spec.lua103
-rw-r--r--test/functional/api/server_requests_spec.lua79
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua13
-rw-r--r--test/functional/core/exit_spec.lua61
-rw-r--r--test/functional/core/path_spec.lua56
-rw-r--r--test/functional/core/quickfix_spec.lua31
-rw-r--r--test/functional/core/startup_spec.lua96
-rw-r--r--test/functional/eval/input_spec.lua19
-rw-r--r--test/functional/eval/json_functions_spec.lua7
-rw-r--r--test/functional/eval/server_spec.lua38
-rw-r--r--test/functional/eval/special_vars_spec.lua7
-rw-r--r--test/functional/ex_cmds/ctrl_c_spec.lua2
-rw-r--r--test/functional/ex_cmds/menu_spec.lua250
-rw-r--r--test/functional/ex_cmds/mkview_spec.lua67
-rw-r--r--test/functional/ex_cmds/quickfix_commands_spec.lua28
-rw-r--r--test/functional/fixtures/api_level_3.mpackbin0 -> 19501 bytes
-rw-r--r--test/functional/legacy/003_cindent_spec.lua34
-rw-r--r--test/functional/lua/utility_functions_spec.lua108
-rw-r--r--test/functional/options/tabstop_spec.lua23
-rw-r--r--test/functional/plugin/health_spec.lua82
-rw-r--r--test/functional/provider/ruby_spec.lua2
-rw-r--r--test/functional/shada/compatibility_spec.lua29
-rw-r--r--test/functional/shada/merging_spec.lua187
-rw-r--r--test/functional/terminal/cursor_spec.lua17
-rw-r--r--test/functional/terminal/mouse_spec.lua28
-rw-r--r--test/functional/terminal/scrollback_spec.lua4
-rw-r--r--test/functional/terminal/tui_spec.lua2
-rw-r--r--test/functional/terminal/window_spec.lua64
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua91
-rw-r--r--test/functional/ui/bufhl_spec.lua31
-rw-r--r--test/functional/ui/cmdline_spec.lua525
-rw-r--r--test/functional/ui/inccommand_spec.lua898
-rw-r--r--test/functional/ui/screen_basic_spec.lua6
-rw-r--r--test/functional/ui/tabline_spec.lua57
-rw-r--r--test/functional/ui/wildmode_spec.lua97
-rw-r--r--test/functional/viml/completion_spec.lua2
-rw-r--r--test/unit/path_spec.lua134
38 files changed, 3119 insertions, 428 deletions
diff --git a/test/README.md b/test/README.md
index 01db5960cd..010a2c9c12 100644
--- a/test/README.md
+++ b/test/README.md
@@ -1,31 +1,262 @@
-# Tests
+Tests
+=====
-Tests are run by `/cmake/RunTests.cmake` file, using busted.
+Tests are run by `/cmake/RunTests.cmake` file, using `busted`.
For some failures, `.nvimlog` (or `$NVIM_LOG_FILE`) may provide insight.
-## Directory structure
+---
-Directories with tests: `/test/benchmark` for benchmarks, `/test/functional` for
-functional tests, `/test/unit` for unit tests. `/test/config` contains `*.in`
-files (currently a single one) which are transformed into `*.lua` files using
-`configure_file` CMake command: this is for acessing CMake variables in lua
-tests. `/test/includes` contains include files for use by luajit `ffi.cdef`
-C definitions parser: normally used to make macros not accessible via this
-mechanism accessible the other way.
+- [Running tests](#running-tests)
+- [Unit tests](#unit-tests)
+- [Lint](#lint)
+- [Environment variables](#environment-variables)
-Files `/test/*/preload.lua` contain modules which will be preloaded by busted,
-via `--helper` option. `/test/**/helpers.lua` contain various “library”
-functions, (intended to be) used by a number of tests and not just a single one.
+---
-`/test/*/**/*_spec.lua` are files containing actual tests. Files that do not end
-with a `_spec.lua` are libraries like `/test/**/helpers.lua`, except that they
-have some common topic.
+Running tests
+-------------
-Tests inside `/test/unit` and `/test/functional` are normally divided into
-groups by the semantic component they are testing.
+Neovim uses third-party tooling to execute tests. So be sure, from the
+repository directory, to build the tools before testing:
-## Environment variables
+ make cmake
+
+## Executing Tests
+
+To run all _non-legacy_ (unit + functional) tests:
+
+ make test
+
+To run only _unit_ tests:
+
+ make unittest
+
+To run only _functional_ tests:
+
+ make functionaltest
+
+---
+
+## Filter Tests
+
+### Filter by name
+
+Another filter method is by setting a pattern of test name to `TEST_FILTER`.
+
+``` lua
+it('foo api',function()
+ ...
+end)
+it('bar api',function()
+ ...
+end)
+```
+
+To run only test with filter name:
+
+ TEST_TAG='foo.*api' make functionaltest
+
+### Filter by file
+
+To run a *specific* unit test:
+
+ TEST_FILE=test/unit/foo.lua make unittest
+
+To run a *specific* functional test:
+
+ TEST_FILE=test/functional/foo.lua make functionaltest
+
+To *repeat* a test many times:
+
+ .deps/usr/bin/busted --filter 'foo' --repeat 1000 test/functional/ui/foo_spec.lua
+
+### Filter by tag
+
+Tests can be "tagged" by adding `#` before a token in the test description.
+
+``` lua
+it('#foo bar baz', function()
+ ...
+end)
+it('#foo another test', function()
+ ...
+end)
+```
+
+To run only the tagged tests:
+
+ TEST_TAG=foo make functionaltest
+
+**NOTES**:
+* Tags are mainly used for testing issues (ex: `#1234`), so use the following
+ method.
+* `TEST_FILE` is not a pattern string like `TEST_TAG` or `TEST_FILTER`. The
+ given value to `TEST_FILE` must be a path to an existing file.
+* Both `TEST_TAG` and `TEST_FILTER` filter tests by the strings from either
+ `it()` or `describe()` functions.
+
+---
+
+### Legacy
+
+To run all legacy (Vim) integration tests:
+
+ make oldtest
+
+To run a *single* legacy test, run `make` with `TEST_FILE=test_name.res`. E.g.
+to run `test_syntax.vim`:
+
+ TEST_FILE=test_syntax.res make oldtest
+
+- The `.res` extension (instead of `.vim`) is required.
+- Specify only the test file name, not the full path.
+
+### Functional tests
+
+`$GDB` can be set to [run tests under
+gdbserver](https://github.com/neovim/neovim/pull/1527). If `$VALGRIND` is also
+set, it will add the `--vgdb=yes` option to valgrind instead of
+starting gdbserver directly.
+
+Unit tests
+----------
+
+Tests are broadly divided into *unit tests*
+([test/unit](https://github.com/neovim/neovim/tree/master/test/unit) directory)
+and *functional tests*
+([test/functional](https://github.com/neovim/neovim/tree/master/test/functional)
+directory). Use any of the existing tests as a template to start writing new
+tests.
+
+- _Unit_ testing is achieved by compiling the tests as a shared library which is
+ loaded and called by LuaJit [FFI](http://luajit.org/ext_ffi.html).
+- _Functional_ tests are driven by RPC, so they do not require LuaJit (as
+ opposed to Lua).
+
+You can learn the [key concepts of Lua in 15
+minutes](http://learnxinyminutes.com/docs/lua/).
+
+## Guidelines for writing tests
+
+- Consider [BDD](http://en.wikipedia.org/wiki/Behavior-driven_development)
+ guidelines for organization and readability of tests. Describe what you're
+ testing (and the environment if applicable) and create specs that assert its
+ behavior.
+- For testing static functions or functions that have side effects visible only
+ in module-global variables, create accessors for the modified variables. For
+ example, say you are testing a function in misc1.c that modifies a static
+ variable, create a file `test/c-helpers/misc1.c` and add a function that
+ retrieves the value after the function call. Files under `test/c-helpers` will
+ only be compiled when building the test shared library.
+- Luajit needs to know about type and constant declarations used in function
+ prototypes. The
+ [helpers.lua](https://github.com/neovim/neovim/blob/master/test/unit/helpers.lua)
+ file automatically parses `types.h`, so types used in the tested functions
+ must be moved to it to avoid having to rewrite the declarations in the test
+ files (even though this is how it's currently done currently in the misc1/fs
+ modules, but contributors are encouraged to refactor the declarations).
+ - Macro constants must be rewritten as enums so they can be "visible" to the
+ tests automatically.
+- Busted supports various "output providers". The
+ **[gtest](https://github.com/Olivine-Labs/busted/pull/394) output provider**
+ shows verbose details that can be useful to diagnose hung tests. Either modify
+ the Makefile or compile with `make
+ CMAKE_EXTRA_FLAGS=-DBUSTED_OUTPUT_TYPE=gtest` to enable it.
+- **Use busted's `pending()` feature** to skip tests
+ ([example](https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18)).
+ Do not silently skip the test with `if-else`. If a functional test depends on
+ some external factor (e.g. the existence of `md5sum` on `$PATH`), *and* you
+ can't mock or fake the dependency, then skip the test via `pending()` if the
+ external factor is missing. This ensures that the *total* test-count (success
+ + fail + error + pending) is the same in all environments.
+ - *Note:* `pending()` is ignored if it is missing an argument _unless_ it is
+ [contained in an `it()`
+ block](https://github.com/neovim/neovim/blob/d21690a66e7eb5ebef18046c7a79ef898966d786/test/functional/ex_cmds/grep_spec.lua#L11).
+ Provide empty function argument if the `pending()` call is outside of
+ `it()`
+ ([example](https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18)).
+- Use `make testlint` for using the shipped luacheck program ([supported by
+ syntastic](https://github.com/scrooloose/syntastic/blob/d6b96c079be137c83009827b543a83aa113cc011/doc/syntastic-checkers.txt#L3546))
+ to lint all tests.
+
+### Where tests go
+
+- _Unit tests_
+ ([test/unit](https://github.com/neovim/neovim/tree/master/test/unit)) should
+ match 1-to-1 with the structure of `src/nvim/`, because they are testing
+ functions directly. E.g. unit-tests for `src/nvim/undo.c` should live in
+ `test/unit/undo_spec.lua`.
+- _Functional tests_
+ ([test/functional](https://github.com/neovim/neovim/tree/master/test/functional))
+ are higher-level (plugins and user input) than unit tests; they are organized
+ by concept.
+ - Try to find an existing `test/functional/*/*_spec.lua` group that makes
+ sense, before creating a new one.
+
+## Checklist for migrating legacy tests
+
+**Note:** Only "old style" (`src/testdir/*.in`) legacy tests should be
+converted. Please _do not_ convert "new style" Vim tests (`src/testdir/*.vim`).
+The "new style" Vim tests are faster than the old ones, and converting them
+takes time and effort better spent elsewhere.
+
+- Remove the test from the Makefile (`src/nvim/testdir/Makefile`).
+- Remove the associated `test.in`, `test.out`, and `test.ok` files from
+ `src/nvim/testdir/`.
+- Make sure the lua test ends in `_spec.lua`.
+- Make sure the test count increases accordingly in the build log.
+- Make sure the new test contains the same control characters (`^]`, ...) as the
+ old test.
+ - Instead of the actual control characters, use an equivalent textual
+ representation (e.g. `<esc>` instead of `^]`). The
+ `scripts/legacy2luatest.pl` script does some of these conversions
+ automatically.
+
+## Tips
+
+- Really long `source([=[...]=])` blocks may break syntax highlighting. Try
+ `:syntax sync fromstart` to fix it.
+
+
+Lint
+----
+
+`make lint` (and `make testlint`) runs [luacheck](https://github.com/mpeterv/luacheck)
+on the test code.
+
+If a luacheck warning must be ignored, specify the warning code. Example:
+
+ -- luacheck: ignore 621
+
+http://luacheck.readthedocs.io/en/stable/warnings.html
+
+Ignore the smallest applicable scope (e.g. inside a function, not at the top of
+the file).
+
+Layout
+------
+
+- `/test/benchmark` : benchmarks
+- `/test/functional` : functional tests
+- `/test/unit` : unit tests
+- `/test/config` : contains `*.in` files which are transformed into `*.lua`
+ files using `configure_file` CMake command: this is for acessing CMake
+ variables in lua tests.
+- `/test/includes` : include-files for use by luajit `ffi.cdef` C definitions
+ parser: normally used to make macros not accessible via this mechanism
+ accessible the other way.
+- `/test/*/preload.lua` : modules preloaded by busted `--helper` option
+- `/test/**/helpers.lua` : common utility functions for test code
+- `/test/*/**/*_spec.lua` : actual tests. Files that do not end with
+ `_spec.lua` are libraries like `/test/**/helpers.lua`, except that they have
+ some common topic.
+
+Tests in `/test/unit` and `/test/functional` are normally divided into groups
+by the semantic component they are testing.
+
+Environment variables
+---------------------
Test behaviour is affected by environment variables. Currently supported
(Functional, Unit, Benchmarks) (when Defined; when set to _1_; when defined,
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
new file mode 100644
index 0000000000..2297a0760f
--- /dev/null
+++ b/test/functional/api/highlight_spec.lua
@@ -0,0 +1,103 @@
+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 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_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()
+ command("hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold")
+ end)
+
+ it("nvim_get_hl_by_id", function()
+ local hl_id = eval("hlID('NewHighlight')")
+ 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))
+
+ -- Test invalid id.
+ local err, emsg = pcall(meths.get_hl_by_id, 30000, false)
+ eq(false, err)
+ 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` 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))
+
+ -- Test invalid name.
+ local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight', false)
+ eq(false, err)
+ 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)
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 9f245d913b..a2a198ca83 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -109,7 +109,28 @@ describe('server -> client', function()
end)
describe('requests and notifications interleaved', function()
- -- This tests that the following scenario won't happen:
+ it('does not delay notifications during pending request', function()
+ local received = false
+ local function on_setup()
+ eq("retval", funcs.rpcrequest(cid, "doit"))
+ stop()
+ end
+ local function on_request(method)
+ if method == "doit" then
+ funcs.rpcnotify(cid, "headsup")
+ eq(true,received)
+ return "retval"
+ end
+ end
+ local function on_notification(method)
+ if method == "headsup" then
+ received = true
+ end
+ end
+ run(on_request, on_notification, on_setup)
+ end)
+
+ -- This tests the following scenario:
--
-- server->client [request ] (1)
-- client->server [request ] (2) triggered by (1)
@@ -124,36 +145,38 @@ describe('server -> client', function()
-- only deals with one server->client request at a time. (In other words,
-- the client cannot send a response to a request that is not at the top
-- of nvim's request stack).
- --
- -- But above scenario shoudn't happen by the way notifications are dealt in
- -- Nvim: they are only sent after there are no pending server->client
- -- request(the request stack fully unwinds). So (3) is only sent after the
- -- client returns (6).
- it('works', function()
- local expected = 300
- local notified = 0
+ pending('will close connection if not properly synchronized', function()
local function on_setup()
eq('notified!', eval('rpcrequest('..cid..', "notify")'))
end
local function on_request(method)
- eq('notify', method)
- eq(1, eval('rpcnotify('..cid..', "notification")'))
- return 'notified!'
+ if method == "notify" then
+ eq(1, eval('rpcnotify('..cid..', "notification")'))
+ return 'notified!'
+ elseif method == "nested" then
+ -- do some busywork, so the first request will return
+ -- before this one
+ for _ = 1, 5 do
+ eq(2, eval("1+1"))
+ end
+ eq(1, eval('rpcnotify('..cid..', "nested_done")'))
+ return 'done!'
+ end
end
local function on_notification(method)
- eq('notification', method)
- if notified == expected then
- stop()
- return
+ if method == "notification" then
+ eq('done!', eval('rpcrequest('..cid..', "nested")'))
+ elseif method == "nested_done" then
+ -- this should never have been sent
+ ok(false)
end
- notified = notified + 1
- eq('notified!', eval('rpcrequest('..cid..', "notify")'))
end
run(on_request, on_notification, on_setup)
- eq(expected, notified)
+ -- ignore disconnect failure, otherwise detected by after_each
+ clear()
end)
end)
@@ -281,14 +304,30 @@ describe('server -> client', function()
connect_test(server, 'pipe', address)
end)
- it('via ip address', function()
+ it('via ipv4 address', function()
local server = spawn(nvim_argv)
set_session(server)
local address = funcs.serverstart("127.0.0.1:")
+ if #address == 0 then
+ pending('no ipv4 stack', function() end)
+ return
+ end
eq('127.0.0.1:', string.sub(address,1,10))
connect_test(server, 'tcp', address)
end)
+ it('via ipv6 address', function()
+ local server = spawn(nvim_argv)
+ set_session(server)
+ local address = funcs.serverstart('::1:')
+ if #address == 0 then
+ pending('no ipv6 stack', function() end)
+ return
+ end
+ eq('::1:', string.sub(address,1,4))
+ connect_test(server, 'tcp', address)
+ end)
+
it('via hostname', function()
local server = spawn(nvim_argv)
set_session(server)
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index f66fbf7c94..a3ea3b568f 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -100,7 +100,7 @@ describe('clipboard', function()
^ |
~ |
~ |
- clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
end)
@@ -112,7 +112,7 @@ describe('clipboard', function()
feed_command('redir @+> | bogus_cmd | redir END')
screen:expect([[
~ |
- clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
E492: Not an editor command: bogus_cmd | redir END |
Press ENTER or type command to continue^ |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
@@ -132,7 +132,7 @@ describe('clipboard', function()
^ |
~ |
~ |
- clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
end)
@@ -392,6 +392,13 @@ describe('clipboard', function()
eq('---', eval('getreg("*")'))
end)
+ it('works in the cmdline window', function()
+ feed('q:itext<esc>yy')
+ eq({{'text', ''}, 'V'}, eval("g:test_clip['*']"))
+ command("let g:test_clip['*'] = [['star'], 'c']")
+ feed('p')
+ eq('textstar', meths.get_current_line())
+ end)
end)
describe('clipboard=unnamedplus', function()
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
index 3fb39f3e78..188a6a2c11 100644
--- a/test/functional/core/exit_spec.lua
+++ b/test/functional/core/exit_spec.lua
@@ -2,8 +2,12 @@ local helpers = require('test.functional.helpers')(after_each)
local command = helpers.command
local eval = helpers.eval
-local eq, neq = helpers.eq, helpers.neq
+local eq = helpers.eq
local run = helpers.run
+local funcs = helpers.funcs
+local nvim_prog = helpers.nvim_prog
+local redir_exec = helpers.redir_exec
+local wait = helpers.wait
describe('v:exiting', function()
local cid
@@ -29,18 +33,53 @@ describe('v:exiting', function()
end
run(on_request, nil, on_setup)
end)
+end)
- it('is non-zero after :cquit', function()
- local function on_setup()
- command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
- command('autocmd VimLeave * call rpcrequest('..cid..', "")')
- command('cquit')
- end
- local function on_request()
- neq(0, eval('v:exiting'))
- return ''
+describe(':cquit', function()
+ local function test_cq(cmdline, exit_code, redir_msg)
+ if redir_msg then
+ eq('\n' .. redir_msg, redir_exec(cmdline))
+ wait()
+ eq(2, eval("1+1")) -- Still alive?
+ else
+ funcs.system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline})
+ eq(exit_code, eval('v:shell_error'))
end
- run(on_request, nil, on_setup)
+ end
+
+ before_each(function()
+ helpers.clear()
+ end)
+
+ it('exits with non-zero after :cquit', function()
+ test_cq('cquit', 1, nil)
end)
+ it('exits with non-zero after :cquit 123', function()
+ test_cq('cquit 123', 123, nil)
+ end)
+
+ it('exits with non-zero after :123 cquit', function()
+ test_cq('123 cquit', 123, nil)
+ end)
+
+ it('exits with 0 after :cquit 0', function()
+ test_cq('cquit 0', 0, nil)
+ end)
+
+ it('exits with 0 after :0 cquit', function()
+ test_cq('0 cquit', 0, nil)
+ end)
+
+ it('exits with redir msg for multiple exit codes after :cquit 1 2', function()
+ test_cq('cquit 1 2', nil, 'E488: Trailing characters: cquit 1 2')
+ end)
+
+ it('exits with redir msg for non-number exit code after :cquit X', function()
+ test_cq('cquit X', nil, 'E488: Trailing characters: cquit X')
+ end)
+
+ it('exits with redir msg for negative exit code after :cquit -1', function()
+ test_cq('cquit -1', nil, 'E488: Trailing characters: cquit -1')
+ end)
end)
diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua
new file mode 100644
index 0000000000..669bc99136
--- /dev/null
+++ b/test/functional/core/path_spec.lua
@@ -0,0 +1,56 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local command = helpers.command
+local iswin = helpers.iswin
+
+describe('path collapse', function()
+ local targetdir
+ local expected_path
+
+ local function join_path(...)
+ local pathsep = (iswin() and '\\' or '/')
+ return table.concat({...}, pathsep)
+ end
+
+ before_each(function()
+ targetdir = join_path('test', 'functional', 'fixtures')
+ clear()
+ command('edit '..join_path(targetdir, 'tty-test.c'))
+ expected_path = eval('expand("%:p")')
+ end)
+
+ it('with /./ segment #7117', function()
+ command('edit '..join_path(targetdir, '.', 'tty-test.c'))
+ eq(expected_path, eval('expand("%:p")'))
+ end)
+
+ it('with ./ prefix #7117', function()
+ command('edit '..join_path('.', targetdir, 'tty-test.c'))
+ eq(expected_path, eval('expand("%:p")'))
+ end)
+
+ it('with ./ prefix, after directory change #7117', function()
+ command('edit '..join_path('.', targetdir, 'tty-test.c'))
+ command('cd test')
+ eq(expected_path, eval('expand("%:p")'))
+ end)
+
+ it('with /../ segment #7117', function()
+ command('edit '..join_path(targetdir, '..', 'fixtures', 'tty-test.c'))
+ eq(expected_path, eval('expand("%:p")'))
+ end)
+
+ it('with ../ and different starting directory #7117', function()
+ command('cd test')
+ command('edit '..join_path('..', targetdir, 'tty-test.c'))
+ eq(expected_path, eval('expand("%:p")'))
+ end)
+
+ it('with ./../ and different starting directory #7117', function()
+ command('cd test')
+ command('edit '..join_path('.', '..', targetdir, 'tty-test.c'))
+ eq(expected_path, eval('expand("%:p")'))
+ end)
+end)
diff --git a/test/functional/core/quickfix_spec.lua b/test/functional/core/quickfix_spec.lua
deleted file mode 100644
index 00afebbb35..0000000000
--- a/test/functional/core/quickfix_spec.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-describe('quickfix functionality', function()
- before_each(function()
- helpers.clear()
- end)
- it('Location list correctly updated when buffer modified', function()
- helpers.source([[
- new
- setl bt=nofile
- let lines = ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
- call append(0, lines)
- new
- setl bt=nofile
- call append(0, lines)
- let qf_item = {
- \ 'lnum': 4,
- \ 'text': "This is the error line.",
- \ }
- let qf_item['bufnr'] = bufnr('%')
- call setloclist(0, [qf_item])
- wincmd p
- let qf_item['bufnr'] = bufnr('%')
- call setloclist(0, [qf_item])
- 1del _
- call append(0, ['New line 1', 'New line 2', 'New line 3'])
- silent ll
- ]])
- helpers.eq({0, 6, 1, 0, 1}, helpers.funcs.getcurpos())
- end)
-end)
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
new file mode 100644
index 0000000000..ae7f949e52
--- /dev/null
+++ b/test/functional/core/startup_spec.lua
@@ -0,0 +1,96 @@
+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 funcs = helpers.funcs
+local nvim_prog = helpers.nvim_prog
+local nvim_set = helpers.nvim_set
+local read_file = helpers.read_file
+local retry = helpers.retry
+local iswin = helpers.iswin
+
+describe('startup', function()
+ before_each(function()
+ clear()
+ end)
+ after_each(function()
+ os.remove('Xtest_startup_ttyout')
+ end)
+
+ it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function()
+ -- system() puts a pipe at both ends.
+ local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
+ '--cmd', nvim_set,
+ '-c', [[echo has('ttyin') has('ttyout')]],
+ '+q' })
+ eq('0 0', out)
+ end)
+ it('with --embed: has("ttyin")==0 has("ttyout")==0', function()
+ local screen = Screen.new(25, 3)
+ -- Remote UI connected by --embed.
+ screen:attach()
+ command([[echo has('ttyin') has('ttyout')]])
+ screen:expect([[
+ ^ |
+ ~ |
+ 0 0 |
+ ]])
+ end)
+ it('in a TTY: has("ttyin")==1 has("ttyout")==1', function()
+ local screen = Screen.new(25, 3)
+ screen:attach()
+ if iswin() then
+ command([[set shellcmdflag=/s\ /c shellxquote=\"]])
+ end
+ -- Running in :terminal
+ command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]]
+ ..nvim_set..[[\" ]]
+ ..[[-c \"echo has('ttyin') has('ttyout')\""]]
+ ..[[, shellescape(v:progpath))]])
+ screen:expect([[
+ ^ |
+ 1 1 |
+ |
+ ]])
+ end)
+ it('output to pipe: has("ttyin")==1 has("ttyout")==0', function()
+ local screen = Screen.new(25, 5)
+ screen:attach()
+ if iswin() then
+ command([[set shellcmdflag=/s\ /c shellxquote=\"]])
+ end
+ -- Running in :terminal
+ command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]]
+ ..nvim_set..[[\" ]]
+ ..[[-c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]]
+ ..[[-c q | cat -v"]] -- Output to a pipe.
+ ..[[, shellescape(v:progpath))]])
+ retry(nil, 3000, function()
+ screen:sleep(1)
+ eq('1\n0\n', -- stdin is a TTY, stdout is a pipe
+ read_file('Xtest_startup_ttyout'))
+ end)
+ end)
+ it('input from pipe: has("ttyin")==0 has("ttyout")==1', function()
+ local screen = Screen.new(25, 5)
+ screen:attach()
+ if iswin() then
+ command([[set shellcmdflag=/s\ /c shellxquote=\"]])
+ end
+ -- Running in :terminal
+ command([[exe printf("terminal echo foo | ]] -- Input from a pipe.
+ ..[[%s -u NONE -i NONE --cmd \"]]
+ ..nvim_set..[[\" ]]
+ ..[[-c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]]
+ ..[[-c q -- -"]]
+ ..[[, shellescape(v:progpath))]])
+ retry(nil, 3000, function()
+ screen:sleep(1)
+ eq('0\n1\n', -- stdin is a pipe, stdout is a TTY
+ read_file('Xtest_startup_ttyout'))
+ end)
+ end)
+end)
+
diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua
index 5ae23e17d0..1e6b107c60 100644
--- a/test/functional/eval/input_spec.lua
+++ b/test/functional/eval/input_spec.lua
@@ -239,6 +239,25 @@ describe('input()', function()
{RBP1:(}{RBP2:()}{RBP1:)}^ |
]])
end)
+ it('is not hidden by :silent', function()
+ feed([[:silent call input('Foo: ')<CR>]])
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ Foo: ^ |
+ |
+ ]])
+ feed('Bar')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ Foo: Bar^ |
+ |
+ ]])
+ feed('<CR>')
+ end)
end)
describe('inputdialog()', function()
it('works with multiline prompts', function()
diff --git a/test/functional/eval/json_functions_spec.lua b/test/functional/eval/json_functions_spec.lua
index 4d34cde849..8dcaea806e 100644
--- a/test/functional/eval/json_functions_spec.lua
+++ b/test/functional/eval/json_functions_spec.lua
@@ -776,4 +776,11 @@ describe('json_encode() function', function()
it('can dump NULL dictionary', function()
eq('{}', eval('json_encode(v:_null_dict)'))
end)
+
+ it('fails to parse NULL strings and lists', function()
+ eq('Vim(call):E474: Attempt to decode a blank string',
+ exc_exec('call json_decode($XXX_UNEXISTENT_VAR_XXX)'))
+ eq('Vim(call):E474: Attempt to decode a blank string',
+ exc_exec('call json_decode(v:_null_list)'))
+ end)
end)
diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua
index 115114c3c3..393616838e 100644
--- a/test/functional/eval/server_spec.lua
+++ b/test/functional/eval/server_spec.lua
@@ -63,23 +63,33 @@ describe('serverstart(), serverstop()', function()
eq({}, funcs.serverlist())
local s = funcs.serverstart('127.0.0.1:0') -- assign random port
- assert(string.match(s, '127.0.0.1:%d+'))
- eq(s, funcs.serverlist()[1])
- clear_serverlist()
+ if #s > 0 then
+ assert(string.match(s, '127.0.0.1:%d+'))
+ eq(s, funcs.serverlist()[1])
+ clear_serverlist()
+ end
s = funcs.serverstart('127.0.0.1:') -- assign random port
- assert(string.match(s, '127.0.0.1:%d+'))
- eq(s, funcs.serverlist()[1])
- clear_serverlist()
+ if #s > 0 then
+ assert(string.match(s, '127.0.0.1:%d+'))
+ eq(s, funcs.serverlist()[1])
+ clear_serverlist()
+ end
- funcs.serverstart('127.0.0.1:12345')
- funcs.serverstart('127.0.0.1:12345') -- exists already; ignore
- funcs.serverstart('::1:12345')
- funcs.serverstart('::1:12345') -- exists already; ignore
- local expected = {
- '127.0.0.1:12345',
- '::1:12345',
- }
+ local expected = {}
+ local v4 = '127.0.0.1:12345'
+ s = funcs.serverstart(v4)
+ if #s > 0 then
+ table.insert(expected, v4)
+ funcs.serverstart(v4) -- exists already; ignore
+ end
+
+ local v6 = '::1:12345'
+ s = funcs.serverstart(v6)
+ if #s > 0 then
+ table.insert(expected, v6)
+ funcs.serverstart(v6) -- exists already; ignore
+ end
eq(expected, funcs.serverlist())
clear_serverlist()
diff --git a/test/functional/eval/special_vars_spec.lua b/test/functional/eval/special_vars_spec.lua
index 3d9358447e..b5773a5529 100644
--- a/test/functional/eval/special_vars_spec.lua
+++ b/test/functional/eval/special_vars_spec.lua
@@ -168,4 +168,11 @@ describe('Special values', function()
'Expected True but got v:null',
}, meths.get_vvar('errors'))
end)
+
+ describe('compat', function()
+ it('v:count is distinct from count', function()
+ command('let count = []') -- v:count is readonly
+ eq(1, eval('count is# g:["count"]'))
+ end)
+ end)
end)
diff --git a/test/functional/ex_cmds/ctrl_c_spec.lua b/test/functional/ex_cmds/ctrl_c_spec.lua
index 091a008814..8f76099f79 100644
--- a/test/functional/ex_cmds/ctrl_c_spec.lua
+++ b/test/functional/ex_cmds/ctrl_c_spec.lua
@@ -47,7 +47,7 @@ describe("CTRL-C (mapped)", function()
end
-- The test is time-sensitive. Try different sleep values.
- local ms_values = {1, 10, 100, 1000, 10000}
+ local ms_values = {100, 1000, 10000}
for i, ms in ipairs(ms_values) do
if i < #ms_values then
local status, _ = pcall(test_ctrl_c, ms)
diff --git a/test/functional/ex_cmds/menu_spec.lua b/test/functional/ex_cmds/menu_spec.lua
index 55da8da8dc..2c0535acda 100644
--- a/test/functional/ex_cmds/menu_spec.lua
+++ b/test/functional/ex_cmds/menu_spec.lua
@@ -107,7 +107,7 @@ describe('menu_get', function()
sid = 1,
noremap = 1,
enabled = 1,
- rhs = "inormal\27",
+ rhs = "inormal<Esc>",
silent = 0
},
v = {
@@ -242,7 +242,7 @@ describe('menu_get', function()
sid = 1,
noremap = 1,
enabled = 1,
- rhs = "\18\"",
+ rhs = "<C-R>\"",
silent = 0
},
n = {
@@ -379,5 +379,251 @@ describe('menu_get', function()
}
eq(expected, m)
end)
+end)
+
+describe('menu_get', function()
+
+ before_each(function()
+ clear()
+ end)
+
+ it('returns <keycode> representation of special keys', function()
+ command('nnoremenu &Test.Test inormal<ESC>')
+ command('inoremenu &Test.Test2 <Tab><Esc>')
+ command('vnoremenu &Test.Test3 yA<C-R>0<Tab>xyz<Esc>')
+ command('inoremenu &Test.Test4 <c-r>*')
+ command('inoremenu &Test.Test5 <c-R>+')
+ command('nnoremenu &Test.Test6 <Nop>')
+ command('nnoremenu &Test.Test7 <NOP>')
+ command('nnoremenu &Test.Test8 <NoP>')
+ command('nnoremenu &Test.Test9 ""')
+
+ local m = funcs.menu_get("");
+ local expected = {
+ {
+ shortcut = "T",
+ hidden = 0,
+ submenus = {
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "inormal<Esc>",
+ silent = 0
+ }
+ },
+ name = "Test",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ i = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "<Tab><Esc>",
+ silent = 0
+ }
+ },
+ name = "Test2",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ s = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "yA<C-R>0<Tab>xyz<Esc>",
+ silent = 0
+ },
+ v = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "yA<C-R>0<Tab>xyz<Esc>",
+ silent = 0
+ }
+ },
+ name = "Test3",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ i = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "<C-R>*",
+ silent = 0
+ }
+ },
+ name = "Test4",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ i = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "<C-R>+",
+ silent = 0
+ }
+ },
+ name = "Test5",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "",
+ silent = 0
+ }
+ },
+ name = "Test6",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "",
+ silent = 0
+ }
+ },
+ name = "Test7",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "",
+ silent = 0
+ }
+ },
+ name = "Test8",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "\"\"",
+ silent = 0
+ }
+ },
+ name = "Test9",
+ hidden = 0
+ }
+ },
+ priority = 500,
+ name = "Test"
+ }
+ }
+
+ eq(m, expected)
+ end)
+
+ it('works with right-aligned text and spaces', function()
+ command('nnoremenu &Test<Tab>Y.Test<Tab>X\\ x inormal<Alt-j>')
+ command('nnoremenu &Test\\ 1.Test\\ 2 Wargl')
+ command('nnoremenu &Test4.Test<Tab>3 i space<Esc>')
+
+ local m = funcs.menu_get("");
+ local expected = {
+ {
+ shortcut = "T",
+ hidden = 0,
+ actext = "Y",
+ submenus = {
+ {
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "inormal<Alt-j>",
+ silent = 0
+ }
+ },
+ hidden = 0,
+ actext = "X x",
+ priority = 500,
+ name = "Test"
+ }
+ },
+ priority = 500,
+ name = "Test"
+ },
+ {
+ shortcut = "T",
+ hidden = 0,
+ submenus = {
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "Wargl",
+ silent = 0
+ }
+ },
+ name = "Test 2",
+ hidden = 0
+ }
+ },
+ priority = 500,
+ name = "Test 1"
+ },
+ {
+ shortcut = "T",
+ hidden = 0,
+ submenus = {
+ {
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "i space<Esc>",
+ silent = 0
+ }
+ },
+ hidden = 0,
+ actext = "3",
+ priority = 500,
+ name = "Test"
+ }
+ },
+ priority = 500,
+ name = "Test4"
+ }
+ }
+ eq(m, expected)
+ end)
end)
diff --git a/test/functional/ex_cmds/mkview_spec.lua b/test/functional/ex_cmds/mkview_spec.lua
new file mode 100644
index 0000000000..97a49dbbd5
--- /dev/null
+++ b/test/functional/ex_cmds/mkview_spec.lua
@@ -0,0 +1,67 @@
+local lfs = require('lfs')
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local command = helpers.command
+local get_pathsep = helpers.get_pathsep
+local eq = helpers.eq
+local funcs = helpers.funcs
+local rmdir = helpers.rmdir
+
+local file_prefix = 'Xtest-functional-ex_cmds-mkview_spec'
+
+describe(':mkview', function()
+ local tmp_file_base = file_prefix .. '-tmpfile'
+ local local_dir = file_prefix .. '.d'
+ local view_dir = file_prefix .. '.view.d'
+
+ before_each(function()
+ clear()
+ lfs.mkdir(view_dir)
+ lfs.mkdir(local_dir)
+ end)
+
+ after_each(function()
+ -- Remove any views created in the view directory
+ rmdir(view_dir)
+ lfs.rmdir(local_dir)
+ end)
+
+ it('viewoption curdir restores local current directory', function()
+ local cwd_dir = funcs.getcwd()
+ local set_view_dir_command = 'set viewdir=' .. cwd_dir ..
+ get_pathsep() .. view_dir
+
+ -- By default the local current directory should save
+ command(set_view_dir_command)
+ command('edit ' .. tmp_file_base .. '1')
+ command('lcd ' .. local_dir)
+ command('mkview')
+
+ -- Create a new instance of Nvim to remove the 'lcd'
+ clear()
+
+ -- Disable saving the local current directory for the second view
+ command(set_view_dir_command)
+ command('set viewoptions-=curdir')
+ command('edit ' .. tmp_file_base .. '2')
+ command('lcd ' .. local_dir)
+ command('mkview')
+
+ -- Create a new instance of Nvim to test saved 'lcd' option
+ clear()
+ command(set_view_dir_command)
+
+ -- Load the view without a saved local current directory
+ command('edit ' .. tmp_file_base .. '2')
+ command('loadview')
+ -- The view's current directory should not have changed
+ eq(cwd_dir, funcs.getcwd())
+ -- Load the view with a saved local current directory
+ command('edit ' .. tmp_file_base .. '1')
+ command('loadview')
+ -- The view's local directory should have been saved
+ eq(cwd_dir .. get_pathsep() .. local_dir, funcs.getcwd())
+ end)
+
+end)
diff --git a/test/functional/ex_cmds/quickfix_commands_spec.lua b/test/functional/ex_cmds/quickfix_commands_spec.lua
index 5ab34db3fb..bf10f80401 100644
--- a/test/functional/ex_cmds/quickfix_commands_spec.lua
+++ b/test/functional/ex_cmds/quickfix_commands_spec.lua
@@ -7,6 +7,7 @@ local command = helpers.command
local exc_exec = helpers.exc_exec
local write_file = helpers.write_file
local curbufmeths = helpers.curbufmeths
+local source = helpers.source
local file_base = 'Xtest-functional-ex_cmds-quickfix_commands'
@@ -81,3 +82,30 @@ for _, c in ipairs({'l', 'c'}) do
end)
end)
end
+
+describe('quickfix', function()
+ it('location-list update on buffer modification', function()
+ source([[
+ new
+ setl bt=nofile
+ let lines = ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
+ call append(0, lines)
+ new
+ setl bt=nofile
+ call append(0, lines)
+ let qf_item = {
+ \ 'lnum': 4,
+ \ 'text': "This is the error line.",
+ \ }
+ let qf_item['bufnr'] = bufnr('%')
+ call setloclist(0, [qf_item])
+ wincmd p
+ let qf_item['bufnr'] = bufnr('%')
+ call setloclist(0, [qf_item])
+ 1del _
+ call append(0, ['New line 1', 'New line 2', 'New line 3'])
+ silent ll
+ ]])
+ eq({0, 6, 1, 0, 1}, funcs.getcurpos())
+ end)
+end)
diff --git a/test/functional/fixtures/api_level_3.mpack b/test/functional/fixtures/api_level_3.mpack
new file mode 100644
index 0000000000..ef36b99c8c
--- /dev/null
+++ b/test/functional/fixtures/api_level_3.mpack
Binary files differ
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<cr>')
+
+ expect([=[
+ /* start of define */
+ {
+ }
+ #define AAA \
+ BBB\
+ CCC
+
+ #define CNT \
+ 1 + \
+ 2 + \
+ 4
+ /* end of define */]=])
+ end)
end)
diff --git a/test/functional/lua/utility_functions_spec.lua b/test/functional/lua/utility_functions_spec.lua
new file mode 100644
index 0000000000..d5756e134d
--- /dev/null
+++ b/test/functional/lua/utility_functions_spec.lua
@@ -0,0 +1,108 @@
+-- Test suite for testing interactions with API bindings
+local helpers = require('test.functional.helpers')(after_each)
+
+local funcs = helpers.funcs
+local clear = helpers.clear
+local eq = helpers.eq
+
+before_each(clear)
+
+describe('vim.stricmp', function()
+ -- İ: `tolower("İ")` is `i` which has length 1 while `İ` itself has
+ -- length 2 (in bytes).
+ -- Ⱥ: `tolower("Ⱥ")` is `ⱥ` which has length 2 while `Ⱥ` itself has
+ -- length 3 (in bytes).
+ --
+ -- Note: 'i' !=? 'İ' and 'ⱥ' !=? 'Ⱥ' on some systems.
+ -- Note: Built-in Nvim comparison (on systems lacking `strcasecmp`) works
+ -- only on ASCII characters.
+ it('works', function()
+ eq(0, funcs.luaeval('vim.stricmp("a", "A")'))
+ eq(0, funcs.luaeval('vim.stricmp("A", "a")'))
+ eq(0, funcs.luaeval('vim.stricmp("a", "a")'))
+ eq(0, funcs.luaeval('vim.stricmp("A", "A")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("", "")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0", "\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0", "\\0\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0a")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0A")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0a")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("a\\0", "A\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("A\\0", "a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("a\\0", "a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("A\\0", "A\\0")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("\\0a", "\\0A")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A", "\\0a")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0a", "\\0a")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A", "\\0A")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0A\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0A\\0")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("a", "B")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A", "b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("a", "b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A", "B")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("", "\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0", "\\0\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0", "\\0\\0\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0B")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0b")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("a\\0", "B\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A\\0", "b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("a\\0", "b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A\\0", "B\\0")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a", "\\0B")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A", "\\0b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a", "\\0b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A", "\\0B")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0B\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0B\\0")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("c", "B")'))
+ eq(1, funcs.luaeval('vim.stricmp("C", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("c", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("C", "B")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("\\0", "")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0", "\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0\\0", "\\0\\0\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0C", "\\0\\0\\0b")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0B")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0b")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "B\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "B\\0")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "B")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "B")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("\\0c", "\\0B")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C", "\\0b")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0c", "\\0b")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C", "\\0B")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("\\0c\\0", "\\0B\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0c\\0", "\\0b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")'))
+ end)
+end)
diff --git a/test/functional/options/tabstop_spec.lua b/test/functional/options/tabstop_spec.lua
new file mode 100644
index 0000000000..dc3ba38438
--- /dev/null
+++ b/test/functional/options/tabstop_spec.lua
@@ -0,0 +1,23 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local feed = helpers.feed
+local eq = helpers.eq
+local eval = helpers.eval
+
+describe("'tabstop' option", function()
+ before_each(function()
+ clear()
+ end)
+
+ -- NOTE: Setting 'tabstop' to a big number reproduces crash #2838.
+ -- Disallowing big 'tabstop' would not fix #2838, only hide it.
+ it("tabstop=<big-number> does not crash #2838", function()
+ -- Insert a <Tab> character for 'tabstop' to work with.
+ feed('i<Tab><Esc>')
+ -- Set 'tabstop' to a very high value.
+ -- Use feed(), not command(), to provoke crash.
+ feed(':set tabstop=3000000000<CR>')
+ eq(2, eval("1+1")) -- Still alive?
+ end)
+end)
diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua
index 3739540b09..8ee0f258d0 100644
--- a/test/functional/plugin/health_spec.lua
+++ b/test/functional/plugin/health_spec.lua
@@ -1,7 +1,37 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local plugin_helpers = require('test.functional.plugin.helpers')
+local clear = helpers.clear
+local curbuf_contents = helpers.curbuf_contents
local command = helpers.command
+local eq = helpers.eq
+
+describe(':checkhealth', function()
+ it("detects invalid $VIMRUNTIME", function()
+ clear({
+ env={ VIMRUNTIME='bogus', },
+ })
+ local status, err = pcall(command, 'checkhealth')
+ eq(false, status)
+ eq('Invalid $VIMRUNTIME: bogus', string.match(err, 'Invalid.*'))
+ end)
+ it("detects invalid 'runtimepath'", function()
+ clear()
+ command('set runtimepath=bogus')
+ local status, err = pcall(command, 'checkhealth')
+ eq(false, status)
+ eq("Invalid 'runtimepath'", string.match(err, 'Invalid.*'))
+ end)
+ it("detects invalid $VIM", function()
+ clear()
+ -- Do this after startup, otherwise it just breaks $VIMRUNTIME.
+ command("let $VIM='zub'")
+ command("checkhealth nvim")
+ eq("ERROR: $VIM is invalid: zub",
+ string.match(curbuf_contents(), "ERROR: $VIM .* zub"))
+ end)
+end)
describe('health.vim', function()
before_each(function()
@@ -13,7 +43,7 @@ describe('health.vim', function()
command("set runtimepath+=test/functional/fixtures")
end)
- it("reports", function()
+ it("health#report_*()", function()
helpers.source([[
let g:health_report = execute([
\ "call health#report_start('Check Bar')",
@@ -30,41 +60,41 @@ describe('health.vim', function()
## Check Bar
- - SUCCESS: Bar status
- - SUCCESS: Other Bar status
+ - OK: Bar status
+ - OK: Other Bar status
- WARNING: Zub
## Baz
- WARNING: Zim
- - SUGGESTIONS:
+ - ADVICE:
- suggestion 1
- suggestion 2]]),
result)
end)
- describe(":CheckHealth", function()
+ describe(":checkhealth", function()
it("concatenates multiple reports", function()
- command("CheckHealth success1 success2")
+ command("checkhealth success1 success2")
helpers.expect([[
health#success1#check
========================================================================
## report 1
- - SUCCESS: everything is fine
+ - OK: everything is fine
## report 2
- - SUCCESS: nothing to see here
+ - OK: nothing to see here
health#success2#check
========================================================================
## another 1
- - SUCCESS: ok
+ - OK: ok
]])
end)
it("gracefully handles broken healthcheck", function()
- command("CheckHealth broken")
+ command("checkhealth broken")
helpers.expect([[
health#broken#check
@@ -75,8 +105,38 @@ describe('health.vim', function()
]])
end)
+ it("highlights OK, ERROR", function()
+ local screen = Screen.new(72, 10)
+ screen:attach()
+ screen:set_default_attr_ids({
+ Ok = { foreground = Screen.colors.Grey3, background = 6291200 },
+ Error = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
+ })
+ screen:set_default_attr_ignore({
+ Heading = { bold=true, foreground=Screen.colors.Magenta },
+ Heading2 = { foreground = Screen.colors.SlateBlue },
+ Bar = { foreground=Screen.colors.Purple },
+ Bullet = { bold=true, foreground=Screen.colors.Brown },
+ })
+ command("checkhealth foo success1")
+ command("1tabclose")
+ command("set laststatus=0")
+ screen:expect([[
+ ^ |
+ health#foo#check |
+ ========================================================================|
+ - {Error:ERROR:} No healthcheck found for "foo" plugin. |
+ |
+ health#success1#check |
+ ========================================================================|
+ ## report 1 |
+ - {Ok:OK:} everything is fine |
+ |
+ ]])
+ end)
+
it("gracefully handles invalid healthcheck", function()
- command("CheckHealth non_existent_healthcheck")
+ command("checkhealth non_existent_healthcheck")
helpers.expect([[
health#non_existent_healthcheck#check
diff --git a/test/functional/provider/ruby_spec.lua b/test/functional/provider/ruby_spec.lua
index 9f5ef3b3fc..c70f90da1c 100644
--- a/test/functional/provider/ruby_spec.lua
+++ b/test/functional/provider/ruby_spec.lua
@@ -16,7 +16,7 @@ do
clear()
if missing_provider('ruby') then
pending(
- "Cannot find the neovim RubyGem. Try :CheckHealth",
+ "Cannot find the neovim RubyGem. Try :checkhealth",
function() end)
return
end
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 <C-a> 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
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index d49f1bfc23..d942723d02 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -50,8 +50,8 @@ describe('terminal cursor', function()
it('is positioned correctly when unfocused', function()
screen:expect([[
{7: 1 }tty ready |
- {7: 2 }{2:^ } |
- {7: 3 } |
+ {7: 2 }^rows: 6, cols: 46 |
+ {7: 3 }{2: } |
{7: 4 } |
{7: 5 } |
{7: 6 } |
@@ -60,12 +60,21 @@ describe('terminal cursor', function()
end)
it('is positioned correctly when focused', function()
+ screen:expect([[
+ {7: 1 }tty ready |
+ {7: 2 }^rows: 6, cols: 46 |
+ {7: 3 }{2: } |
+ {7: 4 } |
+ {7: 5 } |
+ {7: 6 } |
+ :set number |
+ ]])
feed('i')
helpers.wait()
screen:expect([[
{7: 1 }tty ready |
- {7: 2 }{1: } |
- {7: 3 } |
+ {7: 2 }rows: 6, cols: 46 |
+ {7: 3 }{1: } |
{7: 4 } |
{7: 5 } |
{7: 6 } |
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index 29c62d7be7..5e5558ee0a 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -101,7 +101,7 @@ describe('terminal mouse', function()
line28 |line28 |
line29 |line29 |
line30 |line30 |
- rows: 5, cols: 25 |rows: 5, cols: 25 |
+ rows: 5, cols: 24 |rows: 5, cols: 24 |
{2:^ } |{2: } |
========== ========== |
:vsp |
@@ -111,7 +111,7 @@ describe('terminal mouse', function()
{7: 1 }^ |line28 |
{4:~ }|line29 |
{4:~ }|line30 |
- {4:~ }|rows: 5, cols: 25 |
+ {4:~ }|rows: 5, cols: 24 |
{4:~ }|{2: } |
========== ========== |
:enew | set number |
@@ -121,16 +121,16 @@ describe('terminal mouse', function()
{7: 27 }line |line28 |
{7: 28 }line |line29 |
{7: 29 }line |line30 |
- {7: 30 }line |rows: 5, cols: 25 |
+ {7: 30 }line |rows: 5, cols: 24 |
{7: 31 }^ |{2: } |
========== ========== |
|
]])
feed('<c-w>li')
screen:expect([[
- {7: 27 }line |line29 |
- {7: 28 }line |line30 |
- {7: 29 }line |rows: 5, cols: 25 |
+ {7: 27 }line |line28 |
+ {7: 28 }line |line29 |
+ {7: 29 }line |line30 |
{7: 30 }line |rows: 5, cols: 24 |
{7: 31 } |{1: } |
========== ========== |
@@ -140,8 +140,8 @@ describe('terminal mouse', function()
thelpers.enable_mouse()
thelpers.feed_data('mouse enabled\n')
screen:expect([[
- {7: 27 }line |line30 |
- {7: 28 }line |rows: 5, cols: 25 |
+ {7: 27 }line |line29 |
+ {7: 28 }line |line30 |
{7: 29 }line |rows: 5, cols: 24 |
{7: 30 }line |mouse enabled |
{7: 31 } |{1: } |
@@ -153,8 +153,8 @@ describe('terminal mouse', function()
it('wont lose focus if another window is scrolled', function()
feed('<ScrollWheelUp><0,0><ScrollWheelUp><0,0>')
screen:expect([[
- {7: 21 }line |line30 |
- {7: 22 }line |rows: 5, cols: 25 |
+ {7: 21 }line |line29 |
+ {7: 22 }line |line30 |
{7: 23 }line |rows: 5, cols: 24 |
{7: 24 }line |mouse enabled |
{7: 25 }line |{1: } |
@@ -163,8 +163,8 @@ describe('terminal mouse', function()
]])
feed('<S-ScrollWheelDown><0,0>')
screen:expect([[
- {7: 26 }line |line30 |
- {7: 27 }line |rows: 5, cols: 25 |
+ {7: 26 }line |line29 |
+ {7: 27 }line |line30 |
{7: 28 }line |rows: 5, cols: 24 |
{7: 29 }line |mouse enabled |
{7: 30 }line |{1: } |
@@ -176,8 +176,8 @@ describe('terminal mouse', function()
it('will lose focus if another window is clicked', function()
feed('<LeftMouse><5,1>')
screen:expect([[
- {7: 27 }line |line30 |
- {7: 28 }l^ine |rows: 5, cols: 25 |
+ {7: 27 }line |line29 |
+ {7: 28 }l^ine |line30 |
{7: 29 }line |rows: 5, cols: 24 |
{7: 30 }line |mouse enabled |
{7: 31 } |{2: } |
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index af9b414311..c665e64a80 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -462,10 +462,10 @@ describe("'scrollback' option", function()
screen:detach()
end)
- it('defaults to 1000 in terminal buffers', function()
+ it('defaults to 10000 in terminal buffers', function()
set_fake_shell()
command('terminal')
- eq(1000, curbufmeths.get_option('scrollback'))
+ eq(10000, curbufmeths.get_option('scrollback'))
end)
it('error if set to invalid value', function()
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index d36eb46e54..777ef65d9e 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -380,7 +380,7 @@ describe("tui 't_Co' (terminal colors)", function()
-- TODO: Revisit this after jobstart/termopen accept `env` dict.
screen = thelpers.screen_setup(0, string.format(
[=[['sh', '-c', 'LANG=C TERM=%s %s %s -u NONE -i NONE --cmd "silent set noswapfile noshowcmd noruler"']]=],
- term,
+ term or "",
(colorterm ~= nil and "COLORTERM="..colorterm or ""),
helpers.nvim_prog))
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 0f705cfe40..842a81872e 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local wait = helpers.wait
+local iswin = helpers.iswin
describe('terminal window', function()
local screen
@@ -11,9 +12,62 @@ describe('terminal window', function()
screen = thelpers.screen_setup()
end)
- describe('with colorcolumn set', function()
+ describe("with 'number'", function()
+ it('wraps text', function()
+ feed([[<C-\><C-N>]])
+ feed([[:set numberwidth=1 number<CR>i]])
+ screen:expect([[
+ {7:1 }tty ready |
+ {7:2 }rows: 6, cols: 48 |
+ {7:3 }{1: } |
+ {7:4 } |
+ {7:5 } |
+ {7:6 } |
+ {3:-- TERMINAL --} |
+ ]])
+ thelpers.feed_data({'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'})
+ screen:expect([[
+ {7:1 }tty ready |
+ {7:2 }rows: 6, cols: 48 |
+ {7:3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV|
+ {7:4 }WXYZ{1: } |
+ {7:5 } |
+ {7:6 } |
+ {3:-- TERMINAL --} |
+ ]])
+
+ if iswin() then
+ return -- win: :terminal resize is unreliable #7007
+ end
+
+ -- numberwidth=9
+ feed([[<C-\><C-N>]])
+ feed([[:set numberwidth=9 number<CR>i]])
+ screen:expect([[
+ {7: 1 }tty ready |
+ {7: 2 }rows: 6, cols: 48 |
+ {7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
+ {7: 4 }WXYZrows: 6, cols: 41 |
+ {7: 5 }{1: } |
+ {7: 6 } |
+ {3:-- TERMINAL --} |
+ ]])
+ thelpers.feed_data({' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'})
+ screen:expect([[
+ {7: 1 }tty ready |
+ {7: 2 }rows: 6, cols: 48 |
+ {7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
+ {7: 4 }WXYZrows: 6, cols: 41 |
+ {7: 5 } abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN|
+ {7: 6 }OPQRSTUVWXYZ{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+ end)
+
+ describe("with 'colorcolumn'", function()
before_each(function()
- feed('<c-\\><c-n>')
+ feed([[<C-\><C-N>]])
screen:expect([[
tty ready |
{2:^ } |
@@ -23,7 +77,7 @@ describe('terminal window', function()
|
|
]])
- feed(':set colorcolumn=20<cr>i')
+ feed(':set colorcolumn=20<CR>i')
end)
it('wont show the color column', function()
@@ -41,7 +95,7 @@ describe('terminal window', function()
describe('with fold set', function()
before_each(function()
- feed('<c-\\><c-n>:set foldenable foldmethod=manual<cr>i')
+ feed([[<C-\><C-N>:set foldenable foldmethod=manual<CR>i]])
thelpers.feed_data({'line1', 'line2', 'line3', 'line4', ''})
screen:expect([[
tty ready |
@@ -55,7 +109,7 @@ describe('terminal window', function()
end)
it('wont show any folds', function()
- feed('<c-\\><c-n>ggvGzf')
+ feed([[<C-\><C-N>ggvGzf]])
wait()
screen:expect([[
^tty ready |
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index c5199f620e..714c2476ce 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -3,6 +3,9 @@ local thelpers = require('test.functional.terminal.helpers')
local clear = helpers.clear
local feed, nvim = helpers.feed, helpers.nvim
local feed_command = helpers.feed_command
+local command = helpers.command
+local eq = helpers.eq
+local eval = helpers.eval
describe('terminal', function()
local screen
@@ -22,72 +25,66 @@ describe('terminal', function()
screen:detach()
end)
- it('resets its size when entering terminal window', function()
+ it('next to a closing window', function()
+ command('split')
+ command('terminal')
+ command('vsplit foo')
+ eq(3, eval("winnr('$')"))
+ feed('ZQ') -- Close split, should not crash. #7538
+ eq(2, eval("1+1")) -- Still alive?
+ end)
+
+ it('does not change size on WinEnter', function()
if helpers.pending_win32(pending) then return end
feed('<c-\\><c-n>')
feed_command('2split')
screen:expect([[
- rows: 2, cols: 50 |
- {2:^ } |
- ========== |
- rows: 2, cols: 50 |
- {2: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- ========== |
- :2split |
- ]])
- feed_command('wincmd p')
- screen:expect([[
tty ready |
- rows: 2, cols: 50 |
+ ^rows: 5, cols: 50 |
========== |
tty ready |
- rows: 2, cols: 50 |
rows: 5, cols: 50 |
{2: } |
- ^ |
+ |
+ |
========== |
- :wincmd p |
+ :2split |
]])
feed_command('wincmd p')
screen:expect([[
- rows: 2, cols: 50 |
- {2:^ } |
+ tty ready |
+ rows: 5, cols: 50 |
========== |
- rows: 2, cols: 50 |
+ tty ready |
+ ^rows: 5, cols: 50 |
{2: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ |
+ |
========== |
:wincmd p |
]])
end)
- describe('when the screen is resized', function()
- it('will forward a resize request to the program', function()
- feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom.
- screen:try_resize(screen._width - 3, screen._height - 2)
- screen:expect([[
- tty ready |
- rows: 7, cols: 47 |
- {2: } |
- |
- |
- |
- |
- :^ |
- ]])
- screen:try_resize(screen._width - 6, screen._height - 3)
- screen:expect([[
- tty ready |
- rows: 7, cols: 47 |
- rows: 4, cols: 41 |
- {2: } |
- :^ |
- ]])
- end)
+ it('forwards resize request to the program', function()
+ feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom.
+ screen:try_resize(screen._width - 3, screen._height - 2)
+ screen:expect([[
+ tty ready |
+ rows: 7, cols: 47 |
+ {2: } |
+ |
+ |
+ |
+ |
+ :^ |
+ ]])
+ screen:try_resize(screen._width - 6, screen._height - 3)
+ screen:expect([[
+ tty ready |
+ rows: 7, cols: 47 |
+ rows: 4, cols: 41 |
+ {2: } |
+ :^ |
+ ]])
end)
end)
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua
index e1e11203e0..2143c01139 100644
--- a/test/functional/ui/bufhl_spec.lua
+++ b/test/functional/ui/bufhl_spec.lua
@@ -24,7 +24,8 @@ describe('Buffer highlighting', function()
[6] = {foreground = Screen.colors.DarkCyan}, -- Identifier
[7] = {bold = true},
[8] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue},
- [9] = {foreground = Screen.colors.SlateBlue, underline = true}
+ [9] = {foreground = Screen.colors.SlateBlue, underline = true},
+ [10] = {foreground = Screen.colors.Red}
})
curbuf = request('nvim_get_current_buf')
end)
@@ -255,4 +256,32 @@ describe('Buffer highlighting', function()
|
]])
end)
+
+ it('works with new syntax groups', function()
+ insert([[
+ fancy code in a new fancy language]])
+ add_hl(-1, "FancyLangItem", 0, 0, 5)
+ screen:expect([[
+ fancy code in a new fancy languag^e |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+
+ command('hi FancyLangItem guifg=red')
+ screen:expect([[
+ {10:fancy} code in a new fancy languag^e |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end)
end)
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
new file mode 100644
index 0000000000..0f8302b036
--- /dev/null
+++ b/test/functional/ui/cmdline_spec.lua
@@ -0,0 +1,525 @@
+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
+
+ before_each(function()
+ clear()
+ cmdline, block = {}, nil
+ screen = Screen.new(25, 5)
+ screen:attach({rgb=true, ext_cmdline=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
+ 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([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq(1, last_level)
+ eq({{
+ content = { { {}, "" } },
+ firstc = ":",
+ indent = 0,
+ pos = 0,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('sign')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "sign" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<Left>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "sign" } },
+ firstc = ":",
+ indent = 0,
+ pos = 3,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<bs>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "sin" } },
+ firstc = ":",
+ indent = 0,
+ pos = 2,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<Esc>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+ end)
+
+ it("works with input()", function()
+ feed(':call input("input", "default")<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "default" } },
+ firstc = "",
+ indent = 0,
+ pos = 7,
+ prompt = "input"
+ }}, cmdline)
+ end)
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+
+ end)
+
+ it("works with special chars and nested cmdline", function()
+ feed(':xx<c-r>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "xx" } },
+ firstc = ":",
+ indent = 0,
+ pos = 2,
+ prompt = "",
+ special = {'"', true},
+ }}, cmdline)
+ end)
+
+ feed('=')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], 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([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], 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([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq(expectation, cmdline)
+ end)
+
+
+ feed('<cr>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "xx3" } },
+ firstc = ":",
+ indent = 0,
+ pos = 3,
+ prompt = "",
+ }}, cmdline)
+ end)
+
+ feed('<esc>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+ end)
+
+ it("works with function definitions", function()
+ feed(':function Foo()<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "" } },
+ firstc = ":",
+ indent = 2,
+ pos = 0,
+ prompt = "",
+ }}, cmdline)
+ eq({{{{}, 'function Foo()'}}}, block)
+ end)
+
+ feed('line1<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{{{}, 'function Foo()'}},
+ {{{}, ' line1'}}}, block)
+ end)
+
+ block = {}
+ command("redraw!")
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq({{{{}, 'function Foo()'}},
+ {{{}, ' line1'}}}, block)
+ end)
+
+
+ feed('endfunction<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq(nil, block)
+ end)
+ end)
+
+ it("works with cmdline window", function()
+ feed(':make')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "make" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<c-f>')
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+
+ -- nested cmdline
+ feed(':yank')
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({nil, {
+ content = { { {}, "yank" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ cmdline = {}
+ command("redraw!")
+ screen:expect([[
+ |
+ [No Name] |
+ :make |
+ [Command Line] |
+ ^ |
+ ]], nil, nil, function()
+ eq({nil, {
+ content = { { {}, "yank" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed("<c-c>")
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+
+ feed("<c-c>")
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "make" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ cmdline = {}
+ command("redraw!")
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], 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([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], 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)
+end)
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index c8fa2888d1..53fd17c309 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -21,6 +21,42 @@ local default_text = [[
two lines
]]
+local multiline_text = [[
+ 1 2 3
+ A B C
+ 4 5 6
+ X Y Z
+ 7 8 9
+]]
+
+local multimatch_text = [[
+ a bdc eae a fgl lzia r
+ x
+]]
+
+local multibyte_text = [[
+ £ ¥ ѫѫ PEPPERS
+£ ¥ ѫfѫ
+ a£ ѫ¥KOL
+£ ¥ libm
+£ ¥
+]]
+
+local long_multiline_text = [[
+ 1 2 3
+ A B C
+ 4 5 6
+ X Y Z
+ 7 8 9
+ K L M
+ a b c
+ d e f
+ q r s
+ x y z
+ £ m n
+ t œ ¥
+]]
+
local function common_setup(screen, inccommand, text)
if screen then
command("syntax on")
@@ -682,14 +718,14 @@ describe(":substitute, inccommand=split", function()
feed(":%s/tw")
screen:expect([[
Inc substitution on |
- two lines |
+ {12:tw}o lines |
|
{15:~ }|
{15:~ }|
{11:[No Name] }|
- |2| two lines |
- |4| two lines |
- |
+ |2| {12:tw}o lines |
+ |4| {12:tw}o lines |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -701,18 +737,37 @@ describe(":substitute, inccommand=split", function()
eq(0, eval("&modified"))
end)
+ it("shows preview when cmd modifiers are present", function()
+ -- one modifier
+ feed(':keeppatterns %s/tw/to')
+ screen:expect([[{12:to}o lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- multiple modifiers
+ feed(':keeppatterns silent %s/tw/to')
+ screen:expect([[{12:to}o lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- non-modifier prefix
+ feed(':silent tabedit %s/tw/to')
+ screen:expect([[two lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ end)
+
it('shows split window when typing the pattern', function()
feed(":%s/tw")
screen:expect([[
Inc substitution on |
- two lines |
+ {12:tw}o lines |
|
{15:~ }|
{15:~ }|
{11:[No Name] [+] }|
- |2| two lines |
- |4| two lines |
- |
+ |2| {12:tw}o lines |
+ |4| {12:tw}o lines |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -733,7 +788,7 @@ describe(":substitute, inccommand=split", function()
{11:[No Name] [+] }|
|2| o lines |
|4| o lines |
- |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -745,14 +800,14 @@ describe(":substitute, inccommand=split", function()
feed("x")
screen:expect([[
Inc substitution on |
- xo lines |
+ {12:x}o lines |
|
{15:~ }|
{15:~ }|
{11:[No Name] [+] }|
|2| {12:x}o lines |
|4| {12:x}o lines |
- |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -771,7 +826,7 @@ describe(":substitute, inccommand=split", function()
{11:[No Name] [+] }|
|2| o lines |
|4| o lines |
- |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -786,14 +841,14 @@ describe(":substitute, inccommand=split", function()
feed(":%s/tw/XX")
screen:expect([[
Inc substitution on |
- XXo lines |
+ {12:XX}o lines |
|
{15:~ }|
{15:~ }|
{11:[No Name] [+] }|
|2| {12:XX}o lines |
|4| {12:XX}o lines |
- |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -809,7 +864,7 @@ describe(":substitute, inccommand=split", function()
screen:sleep(1)
screen:expect([[
Inc substitution on |
- two lines |
+ {12:tw}o lines |
Inc substitution on |
two lines |
|
@@ -853,14 +908,14 @@ describe(":substitute, inccommand=split", function()
-- 'cursorline' is NOT active during preview.
screen:expect([[
Inc substitution on |
- {9:tw}o lines |
+ {12:tw}o lines |
Inc substitution on |
- {9:tw}o lines |
+ {12:tw}o lines |
|
{11:[No Name] [+] }|
- |2| {9:tw}o lines |
- |4| {9:tw}o lines |
- |
+ |2| {12:tw}o lines |
+ |4| {12:tw}o lines |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -875,14 +930,14 @@ describe(":substitute, inccommand=split", function()
feed('M M M<esc>')
feed(':%s/M/123/g')
screen:expect([[
- 123 123 123 |
+ {12:123} {12:123} {12:123} |
Inc substitution on |
two lines |
Inc substitution on |
two lines |
{11:[No Name] [+] }|
|1| {12:123} {12:123} {12:123} |
- |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -893,6 +948,28 @@ describe(":substitute, inccommand=split", function()
]])
end)
+ it("highlights nothing when there's no match", function()
+ feed('gg')
+ feed(':%s/Inx')
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ Inc substitution on |
+ two lines |
+ |
+ {11:[No Name] [+] }|
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/Inx^ |
+ ]])
+ end)
+
it('previews correctly when previewhight is small', function()
feed_command('set cwh=3')
feed_command('set hls')
@@ -900,15 +977,15 @@ describe(":substitute, inccommand=split", function()
insert(string.rep('abc abc abc\n', 20))
feed(':%s/abc/MMM/g')
screen:expect([[
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
- MMM MMM MMM |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
+ {12:MMM} {12:MMM} {12:MMM} |
{11:[No Name] [+] }|
| 1| {12:MMM} {12:MMM} {12:MMM} |
| 2| {12:MMM} {12:MMM} {12:MMM} |
@@ -950,9 +1027,9 @@ describe(":substitute, inccommand=split", function()
screen:expect([[
BBo lines |
Inc substitution on |
- Xo lines |
+ {12:X}o lines |
Inc substitution on |
- Xo lines |
+ {12:X}o lines |
{11:[No Name] [+] }|
|1001| {12:X}o lines |
|1003| {12:X}o lines |
@@ -1050,15 +1127,15 @@ describe(":substitute, inccommand=split", function()
feed(":1,2s/t/X")
screen:expect([[
- Inc subsXitution on |
- Xwo lines |
+ Inc subs{12:X}itution on |
+ {12:X}wo lines |
Inc substitution on |
two lines |
|
{11:[No Name] [+] }|
|1| Inc subs{12:X}itution on |
|2| {12:X}wo lines |
- |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -1115,7 +1192,7 @@ describe("inccommand=nosplit", function()
two lines |
Inc substitution on |
two lines |
- Line *.X |
+ Line *.{12:X} |
{15:~ }|
{15:~ }|
{15:~ }|
@@ -1123,7 +1200,6 @@ describe("inccommand=nosplit", function()
:%smagic/3.*/X^ |
]])
-
feed([[<C-\><C-N>]]) -- cancel
feed(":%snomagic/3.*/X") -- start :snomagic command
screen:expect([[
@@ -1131,7 +1207,7 @@ describe("inccommand=nosplit", function()
two lines |
Inc substitution on |
two lines |
- Line *.X here |
+ Line *.{12:X} here |
{15:~ }|
{15:~ }|
{15:~ }|
@@ -1140,15 +1216,57 @@ describe("inccommand=nosplit", function()
]])
end)
+ it("shows preview when cmd modifiers are present", function()
+ -- one modifier
+ feed(':keeppatterns %s/tw/to')
+ screen:expect([[{12:to}o lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- multiple modifiers
+ feed(':keeppatterns silent %s/tw/to')
+ screen:expect([[{12:to}o lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- non-modifier prefix
+ feed(':silent tabedit %s/tw/to')
+ screen:expect([[two lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ end)
+
+ it("does not show window after toggling :set inccommand", function()
+ feed(":%s/tw/OKOK")
+ feed("<Esc>")
+ command("set icm=split")
+ feed(":%s/tw/OKOK")
+ feed("<Esc>")
+ command("set icm=nosplit")
+ feed(":%s/tw/OKOK")
+ wait()
+ screen:expect([[
+ Inc substitution on |
+ {12:OKOK}o lines |
+ Inc substitution on |
+ {12:OKOK}o lines |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/tw/OKOK^ |
+ ]])
+ end)
+
it('never shows preview buffer', function()
feed_command("set hlsearch")
feed(":%s/tw")
screen:expect([[
Inc substitution on |
- {9:tw}o lines |
+ {12:tw}o lines |
Inc substitution on |
- {9:tw}o lines |
+ {12:tw}o lines |
|
{15:~ }|
{15:~ }|
@@ -1160,9 +1278,9 @@ describe("inccommand=nosplit", function()
feed("/BM")
screen:expect([[
Inc substitution on |
- BMo lines |
+ {12:BM}o lines |
Inc substitution on |
- BMo lines |
+ {12:BM}o lines |
|
{15:~ }|
{15:~ }|
@@ -1174,9 +1292,9 @@ describe("inccommand=nosplit", function()
feed("/")
screen:expect([[
Inc substitution on |
- BMo lines |
+ {12:BM}o lines |
Inc substitution on |
- BMo lines |
+ {12:BM}o lines |
|
{15:~ }|
{15:~ }|
@@ -1207,8 +1325,8 @@ describe("inccommand=nosplit", function()
feed(":1,2s/t/X")
screen:expect([[
- Inc subsXitution on |
- Xwo lines |
+ Inc subs{12:X}itution on |
+ {12:X}wo lines |
Inc substitution on |
two lines |
|
@@ -1525,7 +1643,7 @@ describe("'inccommand' split windows", function()
feed(":%s/tw")
screen:expect([[
Inc substitution on {10:|}Inc substitution on|
- two lines {10:|}two lines |
+ {12:tw}o lines {10:|}{12:tw}o lines |
{10:|} |
{15:~ }{10:|}{15:~ }|
{15:~ }{10:|}{15:~ }|
@@ -1540,13 +1658,13 @@ describe("'inccommand' split windows", function()
{15:~ }{10:|}{15:~ }|
{11:[No Name] [+] }{10:|}{15:~ }|
Inc substitution on {10:|}{15:~ }|
- two lines {10:|}{15:~ }|
+ {12:tw}o lines {10:|}{15:~ }|
{10:|}{15:~ }|
{15:~ }{10:|}{15:~ }|
{15:~ }{10:|}{15:~ }|
{10:[No Name] [+] [No Name] [+] }|
- |2| two lines |
- |
+ |2| {12:tw}o lines |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -1564,7 +1682,7 @@ describe("'inccommand' split windows", function()
feed(":%s/tw")
screen:expect([[
Inc substitution on {10:|}Inc substitution on|
- two lines {10:|}two lines |
+ {12:tw}o lines {10:|}{12:tw}o lines |
{10:|} |
{15:~ }{10:|}{15:~ }|
{15:~ }{10:|}{15:~ }|
@@ -1579,13 +1697,13 @@ describe("'inccommand' split windows", function()
{15:~ }{10:|}{15:~ }|
{11:[No Name] [+] }{10:[No Name] [+] }|
Inc substitution on |
- two lines |
+ {12:tw}o lines |
|
{15:~ }|
{15:~ }|
{10:[No Name] [+] }|
- |2| two lines |
- |
+ |2| {12:tw}o lines |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -1614,7 +1732,7 @@ describe("'inccommand' split windows", function()
screen:expect([[
Inc substitution on |
- two lines |
+ {12:tw}o lines |
|
{15:~ }|
{15:~ }|
@@ -1634,8 +1752,8 @@ describe("'inccommand' split windows", function()
{15:~ }|
{15:~ }|
{11:[No Name] [+] }|
- |2| two lines |
- |
+ |2| {12:tw}o lines |
+ {15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
@@ -1673,4 +1791,668 @@ describe("'inccommand' with 'gdefault'", function()
expect("A\nA")
eq({mode='n', blocking=false}, nvim("get_mode"))
end)
+
+ it("does not crash on zero-width matches #7485", function()
+ common_setup(nil, "split", default_text)
+ command("set gdefault")
+ feed("gg")
+ feed("Vj")
+ feed(":s/\\%V")
+ eq({mode='c', blocking=false}, nvim("get_mode"))
+ feed("<Esc>")
+ eq({mode='n', blocking=false}, nvim("get_mode"))
+ end)
+
+ it("removes highlights after abort for a zero-width match", function()
+ local screen = Screen.new(30,5)
+ common_setup(screen, "nosplit", default_text)
+ command("set gdefault")
+
+ feed(":%s/\\%1c/a/")
+ screen:expect([[
+ {12:a}Inc substitution on |
+ {12:a}two lines |
+ {12:a} |
+ {15:~ }|
+ :%s/\%1c/a/^ |
+ ]])
+
+ feed("<Esc>")
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ ^ |
+ {15:~ }|
+ |
+ ]])
+ end)
+
+end)
+
+describe(":substitute", function()
+ local screen = Screen.new(30,15)
+
+ before_each(function()
+ clear()
+ end)
+
+ it(", inccommand=split, highlights multiline substitutions", function()
+ common_setup(screen, "split", multiline_text)
+ feed("gg")
+
+ feed(":%s/2\\_.*X")
+ screen:expect([[
+ 1 {12:2 3} |
+ {12:A B C} |
+ {12:4 5 6} |
+ {12:X} Y Z |
+ 7 8 9 |
+ {11:[No Name] [+] }|
+ |1| 1 {12:2 3} |
+ |2|{12: A B C} |
+ |3|{12: 4 5 6} |
+ |4|{12: X} Y Z |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/2\_.*X^ |
+ ]])
+
+ feed("/MMM")
+ screen:expect([[
+ 1 {12:MMM} Y Z |
+ 7 8 9 |
+ |
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |1| 1 {12:MMM} Y Z |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/2\_.*X/MMM^ |
+ ]])
+
+ feed("\\rK\\rLLL")
+ screen:expect([[
+ 1 {12:MMM} |
+ {12:K} |
+ {12:LLL} Y Z |
+ 7 8 9 |
+ |
+ {11:[No Name] [+] }|
+ |1| 1 {12:MMM} |
+ |2|{12: K} |
+ |3|{12: LLL} Y Z |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/2\_.*X/MMM\rK\rLLL^ |
+ ]])
+ end)
+
+ it(", inccommand=nosplit, highlights multiline substitutions", function()
+ common_setup(screen, "nosplit", multiline_text)
+ feed("gg")
+
+ feed(":%s/2\\_.*X/MMM")
+ screen:expect([[
+ 1 {12:MMM} Y Z |
+ 7 8 9 |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/2\_.*X/MMM^ |
+ ]])
+
+ feed("\\rK\\rLLL")
+ screen:expect([[
+ 1 {12:MMM} |
+ {12:K} |
+ {12:LLL} Y Z |
+ 7 8 9 |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/2\_.*X/MMM\rK\rLLL^ |
+ ]])
+ end)
+
+ it(", inccommand=split, highlights multiple matches on a line", function()
+ common_setup(screen, "split", multimatch_text)
+ command("set gdefault")
+ feed("gg")
+
+ feed(":%s/a/XLK")
+ screen:expect([[
+ {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r|
+ x |
+ |
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |1| {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:X}|
+ {12:LK} r |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/a/XLK^ |
+ ]])
+ end)
+
+ it(", inccommand=nosplit, highlights multiple matches on a line", function()
+ common_setup(screen, "nosplit", multimatch_text)
+ command("set gdefault")
+ feed("gg")
+
+ feed(":%s/a/XLK")
+ screen:expect([[
+ {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r|
+ x |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/a/XLK^ |
+ ]])
+ end)
+
+ it(", inccommand=split, with \\zs", function()
+ common_setup(screen, "split", multiline_text)
+ feed("gg")
+
+ feed(":%s/[0-9]\\n\\zs[A-Z]/OKO")
+ screen:expect([[
+ 1 2 3 |
+ {12:OKO} B C |
+ 4 5 6 |
+ {12:OKO} Y Z |
+ 7 8 9 |
+ {11:[No Name] [+] }|
+ |1| 1 2 3 |
+ |2| {12:OKO} B C |
+ |3| 4 5 6 |
+ |4| {12:OKO} Y Z |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/[0-9]\n\zs[A-Z]/OKO^ |
+ ]])
+ end)
+
+ it(", inccommand=nosplit, with \\zs", function()
+ common_setup(screen, "nosplit", multiline_text)
+ feed("gg")
+
+ feed(":%s/[0-9]\\n\\zs[A-Z]/OKO")
+ screen:expect([[
+ 1 2 3 |
+ {12:OKO} B C |
+ 4 5 6 |
+ {12:OKO} Y Z |
+ 7 8 9 |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/[0-9]\n\zs[A-Z]/OKO^ |
+ ]])
+ end)
+
+ it(", inccommand=split, substitutions of different length",
+ function()
+ common_setup(screen, "split", "T T123 T2T TTT T090804\nx")
+
+ feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g")
+ screen:expect([[
+ T {12:123123} {12:22}T TTT {12:090804090804} |
+ x |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |1| T {12:123123} {12:22}T TTT {12:090804090}|
+ {12:804} |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/T\([0-9]\+\)/\1\1/g^ |
+ ]])
+ end)
+
+ it(", inccommand=nosplit, substitutions of different length", function()
+ common_setup(screen, "nosplit", "T T123 T2T TTT T090804\nx")
+
+ feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g")
+ screen:expect([[
+ T {12:123123} {12:22}T TTT {12:090804090804} |
+ x |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/T\([0-9]\+\)/\1\1/g^ |
+ ]])
+ end)
+
+ it(", inccommand=split, contraction of lines", function()
+ local text = [[
+ T T123 T T123 T2T TT T23423424
+ x
+ afa Q
+ adf la;lkd R
+ alx
+ ]]
+
+ common_setup(screen, "split", text)
+ feed(":%s/[QR]\\n")
+ screen:expect([[
+ afa {12:Q} |
+ adf la;lkd {12:R} |
+ alx |
+ |
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |3| afa {12:Q} |
+ |4|{12: }adf la;lkd {12:R} |
+ |5|{12: }alx |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/[QR]\n^ |
+ ]])
+
+ feed("/KKK")
+ screen:expect([[
+ x |
+ afa {12:KKK}adf la;lkd {12:KKK}alx |
+ |
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |3| afa {12:KKK}adf la;lkd {12:KKK}alx |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/[QR]\n/KKK^ |
+ ]])
+ end)
+
+ it(", inccommand=nosplit, contraction of lines", function()
+ local text = [[
+ T T123 T T123 T2T TT T23423424
+ x
+ afa Q
+ adf la;lkd R
+ alx
+ ]]
+
+ common_setup(screen, "nosplit", text)
+ feed(":%s/[QR]\\n/KKK")
+ screen:expect([[
+ T T123 T T123 T2T TT T23423424|
+ x |
+ afa {12:KKK}adf la;lkd {12:KKK}alx |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/[QR]\n/KKK^ |
+ ]])
+ end)
+
+ it(", inccommand=split, multibyte text", function()
+ common_setup(screen, "split", multibyte_text)
+ feed(":%s/£.*ѫ/X¥¥")
+ screen:expect([[
+ {12:X¥¥} |
+ a{12:X¥¥}¥KOL |
+ £ ¥ libm |
+ £ ¥ |
+ |
+ {11:[No Name] [+] }|
+ |1| {12:X¥¥} PEPPERS |
+ |2| {12:X¥¥} |
+ |3| a{12:X¥¥}¥KOL |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/£.*ѫ/X¥¥^ |
+ ]])
+
+ feed("\\ra££ ¥")
+ screen:expect([[
+ {12:a££ ¥} |
+ a{12:X¥¥} |
+ {12:a££ ¥}¥KOL |
+ £ ¥ libm |
+ £ ¥ |
+ {11:[No Name] [+] }|
+ |1| {12:X¥¥} |
+ |2|{12: a££ ¥} PEPPERS |
+ |3| {12:X¥¥} |
+ |4|{12: a££ ¥} |
+ |5| a{12:X¥¥} |
+ |6|{12: a££ ¥}¥KOL |
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/£.*ѫ/X¥¥\ra££ ¥^ |
+ ]])
+ end)
+
+ it(", inccommand=nosplit, multibyte text", function()
+ common_setup(screen, "nosplit", multibyte_text)
+ feed(":%s/£.*ѫ/X¥¥")
+ screen:expect([[
+ {12:X¥¥} PEPPERS |
+ {12:X¥¥} |
+ a{12:X¥¥}¥KOL |
+ £ ¥ libm |
+ £ ¥ |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/£.*ѫ/X¥¥^ |
+ ]])
+
+ feed("\\ra££ ¥")
+ screen:expect([[
+ {12:X¥¥} |
+ {12:a££ ¥} PEPPERS |
+ {12:X¥¥} |
+ {12:a££ ¥} |
+ a{12:X¥¥} |
+ {12:a££ ¥}¥KOL |
+ £ ¥ libm |
+ £ ¥ |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :%s/£.*ѫ/X¥¥\ra££ ¥^ |
+ ]])
+ end)
+
+ it(", inccommand=split, small cmdwinheight", function()
+ common_setup(screen, "split", long_multiline_text)
+ command("set cmdwinheight=2")
+
+ feed(":%s/[a-z]")
+ screen:expect([[
+ X Y Z |
+ 7 8 9 |
+ K L M |
+ {12:a} b c |
+ {12:d} e f |
+ {12:q} r s |
+ {12:x} y z |
+ £ {12:m} n |
+ {12:t} œ ¥ |
+ |
+ {11:[No Name] [+] }|
+ | 7| {12:a} b c |
+ | 8| {12:d} e f |
+ {10:[Preview] }|
+ :%s/[a-z]^ |
+ ]])
+
+ feed("/JLKR £")
+ screen:expect([[
+ X Y Z |
+ 7 8 9 |
+ K L M |
+ {12:JLKR £} b c |
+ {12:JLKR £} e f |
+ {12:JLKR £} r s |
+ {12:JLKR £} y z |
+ £ {12:JLKR £} n |
+ {12:JLKR £} œ ¥ |
+ |
+ {11:[No Name] [+] }|
+ | 7| {12:JLKR £} b c |
+ | 8| {12:JLKR £} e f |
+ {10:[Preview] }|
+ :%s/[a-z]/JLKR £^ |
+ ]])
+
+ feed("\\rѫ ab \\rXXXX")
+ screen:expect([[
+ 7 8 9 |
+ K L M |
+ {12:JLKR £} |
+ {12:ѫ ab } |
+ {12:XXXX} b c |
+ {12:JLKR £} |
+ {12:ѫ ab } |
+ {12:XXXX} e f |
+ {12:JLKR £} |
+ {11:[No Name] [+] }|
+ | 7| {12:JLKR £} |
+ | 8|{12: ѫ ab } |
+ {10:[Preview] }|
+ :%s/[a-z]/JLKR £\rѫ ab \rXXX|
+ X^ |
+ ]])
+ end)
+
+ it(", inccommand=split, large cmdwinheight", function()
+ common_setup(screen, "split", long_multiline_text)
+ command("set cmdwinheight=11")
+
+ feed(":%s/. .$")
+ screen:expect([[
+ t {12:œ ¥} |
+ {11:[No Name] [+] }|
+ | 1| 1 {12:2 3} |
+ | 2| A {12:B C} |
+ | 3| 4 {12:5 6} |
+ | 4| X {12:Y Z} |
+ | 5| 7 {12:8 9} |
+ | 6| K {12:L M} |
+ | 7| a {12:b c} |
+ | 8| d {12:e f} |
+ | 9| q {12:r s} |
+ |10| x {12:y z} |
+ |11| £ {12:m n} |
+ {10:[Preview] }|
+ :%s/. .$^ |
+ ]])
+
+ feed("/ YYY")
+ screen:expect([[
+ t {12: YYY} |
+ {11:[No Name] [+] }|
+ | 1| 1 {12: YYY} |
+ | 2| A {12: YYY} |
+ | 3| 4 {12: YYY} |
+ | 4| X {12: YYY} |
+ | 5| 7 {12: YYY} |
+ | 6| K {12: YYY} |
+ | 7| a {12: YYY} |
+ | 8| d {12: YYY} |
+ | 9| q {12: YYY} |
+ |10| x {12: YYY} |
+ |11| £ {12: YYY} |
+ {10:[Preview] }|
+ :%s/. .$/ YYY^ |
+ ]])
+
+ feed("\\r KKK")
+ screen:expect([[
+ a {12: YYY} |
+ {11:[No Name] [+] }|
+ | 1| 1 {12: YYY} |
+ | 2|{12: KKK} |
+ | 3| A {12: YYY} |
+ | 4|{12: KKK} |
+ | 5| 4 {12: YYY} |
+ | 6|{12: KKK} |
+ | 7| X {12: YYY} |
+ | 8|{12: KKK} |
+ | 9| 7 {12: YYY} |
+ |10|{12: KKK} |
+ |11| K {12: YYY} |
+ {10:[Preview] }|
+ :%s/. .$/ YYY\r KKK^ |
+ ]])
+ end)
+
+ it(", inccommand=split, lookaround", function()
+ common_setup(screen, "split", "something\neverything\nsomeone")
+ feed([[:%s/\(some\)\@<lt>=thing/one/]])
+ screen:expect([[
+ some{12:one} |
+ everything |
+ someone |
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |1| some{12:one} |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/\(some\)\@<=thing/one/^ |
+ ]])
+
+ feed("<C-c>")
+ wait()
+ feed([[:%s/\(some\)\@<lt>!thing/one/]])
+ screen:expect([[
+ something |
+ every{12:one} |
+ someone |
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |2| every{12:one} |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/\(some\)\@<!thing/one/^ |
+ ]])
+
+ feed([[<C-c>]])
+ wait()
+ feed([[:%s/some\(thing\)\@=/every/]])
+ screen:expect([[
+ {12:every}thing |
+ everything |
+ someone |
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |1| {12:every}thing |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/some\(thing\)\@=/every/^ |
+ ]])
+
+ feed([[<C-c>]])
+ wait()
+ feed([[:%s/some\(thing\)\@!/every/]])
+ screen:expect([[
+ everything |
+ {12:every}one |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |3| {12:every}one |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/some\(thing\)\@!/every/^ |
+ ]])
+ end)
end)
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index bfcdc7f652..b31d9cb32f 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
@@ -119,9 +120,10 @@ describe('Screen', function()
end)
it('has correct default title with named file', function()
- local expected = 'myfile (/mydir) - NVIM'
+ local expected = (iswin() and 'myfile (C:\\mydir) - NVIM'
+ or 'myfile (/mydir) - NVIM')
command('set title')
- command('file /mydir/myfile')
+ command(iswin() and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
screen:expect(function()
eq(expected, screen.title)
end)
diff --git a/test/functional/ui/tabline_spec.lua b/test/functional/ui/tabline_spec.lua
index 56331a33b5..e8271de0bf 100644
--- a/test/functional/ui/tabline_spec.lua
+++ b/test/functional/ui/tabline_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, command, eq = helpers.clear, helpers.command, helpers.eq
-describe('ui/tabline', function()
+describe('ui/ext_tabline', function()
local screen
local event_tabs, event_curtab
@@ -21,37 +21,34 @@ describe('ui/tabline', function()
screen:detach()
end)
- describe('externalized', function()
- it('publishes UI events', function()
- command("tabedit another-tab")
+ it('publishes UI events', function()
+ command("tabedit another-tab")
- local expected_tabs = {
- {tab = { id = 1 }, name = '[No Name]'},
- {tab = { id = 2 }, name = 'another-tab'},
- }
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- |
- ]], nil, nil, function()
- eq({ id = 2 }, event_curtab)
- eq(expected_tabs, event_tabs)
- end)
-
- command("tabNext")
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- |
- ]], nil, nil, function()
- eq({ id = 1 }, event_curtab)
- eq(expected_tabs, event_tabs)
- end)
+ local expected_tabs = {
+ {tab = { id = 1 }, name = '[No Name]'},
+ {tab = { id = 2 }, name = 'another-tab'},
+ }
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({ id = 2 }, event_curtab)
+ eq(expected_tabs, event_tabs)
+ end)
+ command("tabNext")
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({ id = 1 }, event_curtab)
+ eq(expected_tabs, event_tabs)
end)
end)
end)
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index 41a751c284..042969357e 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -179,3 +179,100 @@ describe('command line completion', function()
]])
end)
end)
+
+describe('ui/ext_wildmenu', function()
+ local screen
+ local items, selected = nil, nil
+
+ before_each(function()
+ clear()
+ screen = Screen.new(25, 5)
+ screen:attach({rgb=true, ext_wildmenu=true})
+ screen:set_on_event_handler(function(name, data)
+ if name == "wildmenu_show" then
+ items = data[1]
+ elseif name == "wildmenu_select" then
+ selected = data[1]
+ elseif name == "wildmenu_hide" then
+ items, selected = nil, nil
+ end
+ end)
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it('works with :sign <tab>', function()
+ local expected = {
+ 'define',
+ 'jump',
+ 'list',
+ 'place',
+ 'undefine',
+ 'unplace',
+ }
+
+ command('set wildmode=full')
+ command('set wildmenu')
+ feed(':sign <tab>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ :sign define^ |
+ ]], nil, nil, function()
+ eq(expected, items)
+ eq(0, selected)
+ end)
+
+ feed('<tab>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ :sign jump^ |
+ ]], nil, nil, function()
+ eq(expected, items)
+ eq(1, selected)
+ end)
+
+ feed('<left><left>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ :sign ^ |
+ ]], nil, nil, function()
+ eq(expected, items)
+ eq(-1, selected)
+ end)
+
+ feed('<right>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ :sign define^ |
+ ]], nil, nil, function()
+ eq(expected, items)
+ eq(0, selected)
+ end)
+
+ feed('a')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ :sign definea^ |
+ ]], nil, nil, function()
+ eq(nil, items)
+ eq(nil, selected)
+ end)
+ end)
+end)
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 0e5278345c..b70ef724b7 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -868,7 +868,7 @@ describe('completion', function()
end)
end)
-describe('ui/externalized/popupmenu', function()
+describe('ui/ext_popupmenu', function()
local screen
local items, selected, anchor
before_each(function()
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index a9cba7df84..ed597eaed7 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -366,120 +366,156 @@ describe('path.c', function()
end)
describe('vim_FullName', function()
- local function vim_FullName(filename, buf, len, force)
- filename = to_cstr(filename)
- return cimp.vim_FullName(filename, buf, len, force)
+ local function vim_FullName(filename, buflen, do_expand)
+ local buf = cstr(buflen, '')
+ local result = cimp.vim_FullName(to_cstr(filename), buf, buflen, do_expand)
+ return buf, result
end
- before_each(function()
- -- Create empty string buffer which will contain the resulting path.
- length = (string.len(lfs.currentdir())) + 33
- buffer = cstr(length, '')
- end)
+ local function get_buf_len(s, t)
+ return math.max(string.len(s), string.len(t)) + 1
+ end
itp('fails if given filename is NULL', function()
- local force_expansion = 1
- local result = cimp.vim_FullName(NULL, buffer, length, force_expansion)
+ local do_expand = 1
+ local buflen = 10
+ local buf = cstr(buflen, '')
+ local result = cimp.vim_FullName(NULL, buf, buflen, do_expand)
eq(FAIL, result)
end)
itp('fails safely if given length is wrong #5737', function()
- local force_expansion = 1
local filename = 'foo/bar/bazzzzzzz/buz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/a'
local too_short_len = 8
local buf = cstr(too_short_len, '')
- local result = cimp.vim_FullName(filename, buf, too_short_len, force_expansion)
+ local do_expand = 1
+ local result = cimp.vim_FullName(filename, buf, too_short_len, do_expand)
local expected = string.sub(filename, 1, (too_short_len - 1))
- eq(expected, (ffi.string(buf)))
+ eq(expected, ffi.string(buf))
eq(FAIL, result)
end)
itp('uses the filename if the filename is a URL', function()
- local force_expansion = 1
local filename = 'http://www.neovim.org'
- local result = vim_FullName(filename, buffer, length, force_expansion)
- eq(filename, (ffi.string(buffer)))
+ local buflen = string.len(filename) + 1
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(filename, ffi.string(buf))
eq(OK, result)
end)
itp('fails and uses filename if given filename contains non-existing directory', function()
- local force_expansion = 1
local filename = 'non_existing_dir/test.file'
- local result = vim_FullName(filename, buffer, length, force_expansion)
- eq(filename, (ffi.string(buffer)))
+ local buflen = string.len(filename) + 1
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(filename, ffi.string(buf))
eq(FAIL, result)
end)
itp('concatenates filename if it does not contain a slash', function()
- local force_expansion = 1
- local result = vim_FullName('test.file', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/test.file'
- eq(expected, (ffi.string(buffer)))
+ local filename = 'test.file'
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(expected, ffi.string(buf))
eq(OK, result)
end)
itp('concatenates directory name if it does not contain a slash', function()
- local force_expansion = 1
- local result = vim_FullName('..', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/..'
- eq(expected, (ffi.string(buffer)))
+ local filename = '..'
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(expected, ffi.string(buf))
eq(OK, result)
end)
- -- Is it possible for every developer to enter '..' directory while running
- -- the unit tests? Which other directory would be better?
itp('enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', function()
- local force_expansion = 1
- local result = vim_FullName('../test.file', buffer, length, force_expansion)
local old_dir = lfs.currentdir()
lfs.chdir('..')
local expected = lfs.currentdir() .. '/test.file'
lfs.chdir(old_dir)
- eq(expected, (ffi.string(buffer)))
+ local filename = '../test.file'
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(expected, ffi.string(buf))
eq(OK, result)
end)
itp('just copies the path if it is already absolute and force=0', function()
- local force_expansion = 0
local absolute_path = '/absolute/path'
- local result = vim_FullName(absolute_path, buffer, length, force_expansion)
- eq(absolute_path, (ffi.string(buffer)))
+ local buflen = string.len(absolute_path) + 1
+ local do_expand = 0
+ local buf, result = vim_FullName(absolute_path, buflen, do_expand)
+ eq(absolute_path, ffi.string(buf))
eq(OK, result)
end)
itp('fails and uses filename when the path is relative to HOME', function()
eq(false, cimp.os_isdir('~')) -- sanity check: no literal "~" directory.
- local force_expansion = 1
local absolute_path = '~/home.file'
- local result = vim_FullName(absolute_path, buffer, length, force_expansion)
- eq(absolute_path, (ffi.string(buffer)))
+ local buflen = string.len(absolute_path) + 1
+ local do_expand = 1
+ local buf, result = vim_FullName(absolute_path, buflen, do_expand)
+ eq(absolute_path, ffi.string(buf))
eq(FAIL, result)
end)
itp('works with some "normal" relative path with directories', function()
- local force_expansion = 1
- local result = vim_FullName('unit-test-directory/test.file', buffer, length, force_expansion)
+ local expected = lfs.currentdir() .. '/unit-test-directory/test.file'
+ local filename = 'unit-test-directory/test.file'
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(expected, ffi.string(buf))
eq(OK, result)
- eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
end)
itp('does not modify the given filename', function()
- local force_expansion = 1
+ local expected = lfs.currentdir() .. '/unit-test-directory/test.file'
local filename = to_cstr('unit-test-directory/test.file')
- -- Don't use the wrapper here but pass a cstring directly to the c
- -- function.
- local result = cimp.vim_FullName(filename, buffer, length, force_expansion)
- eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
- eq('unit-test-directory/test.file', (ffi.string(filename)))
+ local buflen = string.len(expected) + 1
+ local buf = cstr(buflen, '')
+ local do_expand = 1
+ -- Don't use the wrapper but pass a cstring directly to the c function.
+ eq('unit-test-directory/test.file', ffi.string(filename))
+ local result = cimp.vim_FullName(filename, buf, buflen, do_expand)
+ eq(expected, ffi.string(buf))
eq(OK, result)
end)
itp('works with directories that have one path component', function()
- local force_expansion = 1
- local filename = to_cstr('/tmp')
- local result = cimp.vim_FullName(filename, buffer, length, force_expansion)
- eq('/tmp', ffi.string(buffer))
+ local filename = '/tmp'
+ local expected = filename
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq('/tmp', ffi.string(buf))
+ eq(OK, result)
+ end)
+
+ itp('expands "./" to the current directory #7117', function()
+ local expected = lfs.currentdir() .. '/unit-test-directory/test.file'
+ local filename = './unit-test-directory/test.file'
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
+ eq(OK, result)
+ eq(expected, ffi.string(buf))
+ end)
+
+ itp('collapses "foo/../foo" to "foo" #7117', function()
+ local expected = lfs.currentdir() .. '/unit-test-directory/test.file'
+ local filename = 'unit-test-directory/../unit-test-directory/test.file'
+ local buflen = get_buf_len(expected, filename)
+ local do_expand = 1
+ local buf, result = vim_FullName(filename, buflen, do_expand)
eq(OK, result)
+ eq(expected, ffi.string(buf))
end)
end)