This release represents ~4000 commits since v0.4.4, the previous non-maintenance release. Highlights include builtin support for LSP, new APIs for extended marks (with byte resolution tracking of changes) and buffer decorations, as well as vast improvements to lua as a plugin and configuration language. Experimental support for tree-sitter as a syntax engine is also included, building on the new core APIs for byte tracking and decorations. FEATURES: New API functions: nvim_exec: execute multiline vim script blocks nvim_get_hl_id_by_name: Gets a highight definition by name nvim_exec_lua: new name for nvim_execute_lua nvim_notify: Notify the user with a message nvim_get_runtime_file: Find files in runtime directories nvim_get_all_options_info: Get option information for all options nvim_get_option_info: Get option information for one option nvim_echo: Echo a message with highlights nvim_open_term: Open a virtual terminal in a buffer nvim_chan_send: send data to a channel. (like chansend() but supports lua strings) nvim_set_decoration_provider: callback driven decoration API for a namespace nvim_buf_set_text: Set/replace a character range in a buffer nvim_buf_delete: Delete the buffer. |:bwipeout| nvim_buf_get_extmark_by_id: Returns position for a given extmark id. nvim_buf_get_extmarks: get extmarks in traversal order. nvim_buf_set_extmark: Creates or updates an extmark. nvim_buf_del_extmark: Removes an extmark. nvim_buf_call: call a function with buffer as temporary current buffer nvim_win_hide: Closes the window and hide the buffer it contains |:hide| nvim_win_call: Calls a function with window as temporary current window. New UI events: redraw.screenshot redraw.win_viewport Lua:767cd8b17#12235 startup: add init.lua as an alternative user config687eb0b39#14686 feat(startup): Source runtime/plugin/**/*.lua at startup #14686 runtime: allow lua in various runtime search paths such as syntax/ ftdetect/ indent/ ftplugin/ compiler/ colors/43956dea5#13479 lua: Add vim.opt and fix scopes of vim.o1407899c3#12268 lua: Add buffer, window and tab accessorsbe662fe5clua: vim.wait implementation2b663c061#14213 viml: embed Lua syntax highlighting901dd79f6feat: add completion to ':lua' 82688973 lua: complete methods in metatables342148525runtime: propagate lua parsing errors while using "require"aaca2c1c4#13276 feat(lua): improve error message to make it actionablec60c7375fstartup: handle autoload and lua packages during startup3ccdbc570#12536 lua: add vim.register_keystroke_callback971a191c4lua: Add ability to pass lua functions directly to vimL91e41c857#12401 lua: add vim.highlight.rangef2894bffb#12279 lua: Add highlight.on_yankae5bd0454#11969 lua: add tbl_deep_extendea4127e9alua: metatable for empty dict valuedab40f43bAdd v:lua.func() vimL syntax for calling lua678a51b1dLua: vim.validate()474d0bcbflua: vim.rpcrequest, vim.rpcnotify, vim.NIL8ee7c94a9lua: add vim.fn.{func} for direct access to vimL functiond0d38fc36#11442 Lua: vim.env, vim.{g,v,w,bo,wo} Tree-sitter: Note: tree-sitter is considered experimental for 0.5. There's remaining bugs for buffer parsing, as well as known performance issues for large files and injected (nested) languages.e93342629#10124 Tree-sitter API for lua440695c29tree-sitter: implement query functionality and highlighting prototype8bea39f37feat(treesitter): allow injections to be configured through directives929f19414feat(treesitter): add offset predicate for language injectioncd75d3289#14200 feat: treesitter checkhealth1a631026afeat(treesitter): add language treed3f544002treesitter: runtime queries3c5141d2c#13008 treesitter: add string parser9437327d5treesitter: use new on_bytes interfacee4b5efa51treesitter: use decoration provider APId6209a7b8fix: Add a test and it is so pretty836c31032feat(ts): bump tree-sitter to v0.20.0 LSP client:00dc12c5d#11336 lua LSP client: initial implementationd5aaad14e#11430 Followup improvements to LSPee7ac469c#11578 LSP: Use async completion for omnifunc.070bd3ea2#11604 LSP: shrink API, improve docs25afa10f9#11669 Merge 'LSP: differentiate diagnostic underline by severity'e956ea767#11777 LSP: show diagnostic in qf/loclistdd8b29cfe#11838 LSP: set InitializeParams.rootPath value0c5d2ffeb#11837 Merge 'LSP: fixes, improve test visibility'ca8699378#11638 LSP: implement documentHighlight220a2b05cLSP/references: Add context to locations returned by serverccb038dc6LSP/completion: add textEdit supportda6f38ab3#12313 LSP: Add workspace.applyEdit client capabilitiesf559e5249#11607 LSP: Add textDocument/codeAction support0d83a1c43#12638 LSP: Feature/add workspace foldersfd507e278#13641 LSP: window/showMessageRequeste467d2939LSP: Move workspace/configuration handler from nvim-lspconfig to core2bdd553c9feat(lsp): Add codelens support UI:f8134f2fdscreen.c: remove fold_line special casec146eddc8experimental support for per-window color schemesa1508c9f6nvim__screenshot (dump TUI state to file)08fe10010terminal: enable pass through indexed colors to TUI in rgb mode5a8569942tests/ui: make screen.lua use "linegrid" representation internally8fe19d9d8screen: make ui_compositor aware of the intended size of a float54ce1010eextmark: add new flexible "decorations" abstraction4781333a7decorations: allow virt_text overlay at any columnbdebe8516decorations: use extmark column adjustments for buffer highlights7b488314ddecorations: Allow highlights beyond end of line hl_eol425bc438adecorations: add additional styling of virt_text overlaysedb5864a2floats: z-index243820ebdfloats: add borders (MS-DOS MODE)5b6edc852feat(float): add rounded borders preset4a36ec6da#14310 float: add "solid" border style vim patches: around ~1000 vim patches and runtime updates got merged. Hooray! Changes include improvements to quickfix, prompt buffers, incsearch, display of search counts, and much much more. various features and changes:858c05613#12809 Support for :perl, :perlfile, :perldo and perleval()bc86f76c0api/buffer: add "on_bytes" callback to nvim_buf_attach19b623708jobstart now supports env/clear_envef7c6b972Support specifying "env" option for termopen()7c4f34966#13287 switch from travis to github actions24db59ca8feat: implement BufModified autocmdb83d8223fimplement Scroll autocommand8caf84130Lower "closed by the client" message level to INFO7de276b87bump libvterm to 0.1.4097ec71bd#14096 aarch64/linux: fix build by updating LuaJITbd5f0e969#12531 support autoread using tui focus tracking8a1276005#12382 Add v:event.visual during `TextYankPost`802f8429dapi(nvim_open_win): add "noautocmd" option FIXES:21444552cBugFix(clipboard): Fix block paste not working properly01493e799#14413 api: fix nvim_exec() silencing behaviour9699f3be1fix(doc): Add '/site' to stdpath('data') example in `:help 'rtp'`581b2bcdescreen: fix problem with p_cheae4b1e5cluaref: fix leaks for global luarefs409b2711ffix: segfault when pasting in term with empty buffercf6c23fb0#14273 fix plenty of errors discovered by clang21035cff9#14500 fix plenty of errors discovered by coveritybca19138b#13987 tui: fix possibility of evaluating uninitialized variables9f2335937fix_cursor: do not change line number when edit will not impact cursor row33f92fe02fix(pty): Always use $TERM from the job's env dict6249059d4checkhealth: fix terminfo problems on Windows397be5d38#12811 UI: fix cursor not displayed after hiding and un-hiding87afc9031screen.c: fix an issue with wrap and foldsb419e39a2screen.c: fix last character on foldtext2ea312769#13688 screen.c: fix display of signcolumn=auto in diffsc2d288e29Fix screen terminal family issues314b222c2#14127 Fix click on foldcolumn with vsplite65d0e53bvim.fn: throw error when trying to use API function
Tests
Tests are broadly divided into unit tests (test/unit), functional tests (test/functional), and old tests (src/nvim/testdir/).
- Unit testing is achieved by compiling the tests as a shared library which is loaded and called by LuaJit FFI.
- 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. Use any existing test as a template to start writing new tests.
Tests are run by /cmake/RunTests.cmake file, using busted (a Lua test-runner).
For some failures, .nvimlog (or $NVIM_LOG_FILE) may provide insight.
Depending on the presence of binaries (e.g., xclip) some tests will be
ignored. You must compile with libintl to prevent E319: The command is not available in this version errors.
Layout
/test/benchmark: benchmarks/test/functional: functional tests/test/unit: unit tests/test/config: contains*.infiles which are transformed into*.luafiles usingconfigure_fileCMake command: this is for acessing CMake variables in lua tests./test/includes: include-files for use by luajitffi.cdefC definitions parser: normally used to make macros not accessible via this mechanism accessible the other way./test/*/preload.lua: modules preloaded by busted--helperoption/test/**/helpers.lua: common utility functions for test code/test/*/**/*_spec.lua: actual tests. Files that do not end with_spec.luaare libraries like/test/**/helpers.lua, except that they have some common topic./src/nvim/testdir: old tests (from Vim)
Running tests
Executing Tests
To run all tests (except "old" tests):
make test
To run only unit tests:
make unittest
To run only functional tests:
make functionaltest
Legacy tests
To run all legacy Vim tests:
make oldtest
To run a single legacy test file you can use either:
make oldtest TEST_FILE=test_syntax.vim
or:
make src/nvim/testdir/test_syntax.vim
- Specify only the test file name, not the full path.
Debugging tests
-
You can set
$GDBto run tests under gdbserver. And if$VALGRINDis set it will pass--vgdb=yesto valgrind instead of starting gdbserver directly. -
Hanging tests often happen due to unexpected
:h press-enterprompts. The default screen width is 50 columns. Commands that try to print lines longer than 50 columns in the command-line, e.g.:edit very...long...path, will trigger the prompt. In this case, a shorter path or:silent editshould be used. -
If you can't figure out what is going on, try to visualize the screen. Put this at the beginning of your test:
local Screen = require('test.functional.ui.screen') local screen = Screen.new() screen:attach()Afterwards, put
screen:snapshot_util()at any position in your test. See the comment at the top oftest/functional/ui/screen.luafor more.
Filtering Tests
Filter by name
Another filter method is by setting a pattern of test name to TEST_FILTER.
it('foo api',function()
...
end)
it('bar api',function()
...
end)
To run only test with filter name:
TEST_FILTER='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:
BUSTED_ARGS="--repeat=100 --no-keep-going" TEST_FILE=test/functional/foo_spec.lua make functionaltest
Filter by tag
Tests can be "tagged" by adding # before a token in the test description.
it('#foo bar baz', function()
...
end)
it('#foo another test', function()
...
end)
To run only the tagged tests:
TEST_TAG=foo make functionaltest
NOTE:
TEST_FILEis not a pattern string likeTEST_TAGorTEST_FILTER. The given value toTEST_FILEmust be a path to an existing file.- Both
TEST_TAGandTEST_FILTERfilter tests by the string descriptions found init()anddescribe().
Writing tests
Guidelines
- Luajit needs to know about type and constant declarations used in function
prototypes. The
helpers.lua
file automatically parses
types.h, so types used in the tested functions could be moved to it to avoid having to rewrite the declarations in the test files.#defineconstants must be rewrittenconstorenumso they can be "visible" to the tests.
- Use pending() to skip tests
(example).
Do not silently skip the test with
if-else. If a functional test depends on some external factor (e.g. the existence ofmd5sumon$PATH), and you can't mock or fake the dependency, then skip the test viapending()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 anit()block. Provide empty function argument if thepending()call is outside ofit()(example).
- Note:
- Really long
source([=[...]=])blocks may break Vim's Lua syntax highlighting. Try:syntax sync fromstartto fix it.
Where tests go
Tests in /test/unit and /test/functional are divided into groups
by the semantic component they are testing.
- Unit tests
(test/unit) should
match 1-to-1 with the structure of
src/nvim/, because they are testing functions directly. E.g. unit-tests forsrc/nvim/undo.cshould live intest/unit/undo_spec.lua. - Functional tests
(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.luagroup that makes sense, before creating a new one.
- Try to find an existing
Lint
make lint (and make lualint) runs 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).
Configuration
Test behaviour is affected by environment variables. Currently supported (Functional, Unit, Benchmarks) (when Defined; when set to 1; when defined, treated as Integer; when defined, treated as String; when defined, treated as Number; !must be defined to function properly):
-
BUSTED_ARGS(F) (U): arguments forwarded tobusted. -
GDB(F) (D): makes nvim instances to be run undergdbserver. It will be accessible onlocalhost:7777: usegdb build/bin/nvim, typetarget remote :7777inside. -
GDBSERVER_PORT(F) (I): overrides port used forGDB. -
VALGRIND(F) (D): makes nvim instances to be run undervalgrind. Log files are namedvalgrind-%p.login this case. Note that non-empty valgrind log may fail tests. Valgrind arguments may be seen in/test/functional/helpers.lua. May be used in conjunction withGDB. -
VALGRIND_LOG(F) (S): overrides valgrind log file name used forVALGRIND. -
TEST_SKIP_FRAGILE(F) (D): makes test suite skip some fragile tests. -
NVIM_PROG,NVIM_PRG(F) (S): override path to Neovim executable (default tobuild/bin/nvim). -
CC(U) (S): specifies which C compiler to use to preprocess files. Currently only compilers with gcc-compatible arguments are supported. -
NVIM_TEST_MAIN_CDEFS(U) (1): makesffi.cdefrun in main process. This raises a possibility of bugs due to conflicts in header definitions, despite the counters, but greatly speeds up unit tests by not requiringffi.cdefto do parsing of big strings with C definitions. -
NVIM_TEST_PRINT_I(U) (1): makescimportprint preprocessed, but not yet filtered throughformatcheaders. Used to debugformatc. Printing is done with the line numbers. -
NVIM_TEST_PRINT_CDEF(U) (1): makescimportprint final lines which will be then passed toffi.cdef. Used to debug errorsffi.cdefhappens to throw sometimes. -
NVIM_TEST_PRINT_SYSCALLS(U) (1): makes it print to stderr when syscall wrappers are called and what they returned. Used to debug code which makes unit tests be executed in separate processes. -
NVIM_TEST_RUN_FAILING_TESTS(U) (1): makesitprun tests which are known to fail (marked by setting third argument totrue). -
LOG_DIR(FU) (S!): specifies where to seek for valgrind and ASAN log files. -
NVIM_TEST_CORE_*(FU) (S): a set of environment variables which specify where to search for core files. Are supposed to be defined all at once. -
NVIM_TEST_CORE_GLOB_DIRECTORY(FU) (S): directory where core files are located. May be.. This directory is then recursively searched for core files. Note: this variable must be defined for any of the following to have any effect. -
NVIM_TEST_CORE_GLOB_RE(FU) (S): regular expression which must be matched by core files. E.g./core[^/]*$. May be absent, in which case any file is considered to be matched. -
NVIM_TEST_CORE_EXC_RE(FU) (S): regular expression which excludes certain directories from searching for core files inside. E.g. use^/%.deps$to not search inside/.deps. If absent, nothing is excluded. -
NVIM_TEST_CORE_DB_CMD(FU) (S): command to get backtrace out of the debugger. E.g.gdb -n -batch -ex "thread apply all bt full" "$_NVIM_TEST_APP" -c "$_NVIM_TEST_CORE". Defaults to the example command. This debug command may use environment variables_NVIM_TEST_APP(path to application which is being debugged: normally either nvim or luajit) and_NVIM_TEST_CORE(core file to get backtrace from). -
NVIM_TEST_CORE_RANDOM_SKIP(FU) (D): makescheck_coresnot check cores after approximately 90% of the tests. Should be used when finding cores is too hard for some reason. Normally (on OS X or whenNVIM_TEST_CORE_GLOB_DIRECTORYis defined and this variable is not) cores are checked for after each test. -
NVIM_TEST_RUN_TESTTEST(U) (1): allows runningtest/unit/testtest_spec.luaused to check how testing infrastructure works. -
NVIM_TEST_TRACE_LEVEL(U) (N): specifies unit tests tracing level:0disables tracing (the fastest, but you get no data if tests crash and there no core dump was generated),1leaves only C function calls and returns in the trace (faster than recording everything),2records all function calls, returns and executed Lua source lines.
-
NVIM_TEST_TRACE_ON_ERROR(U) (1): makes unit tests yield trace on error in addition to regular error message. -
NVIM_TEST_MAXTRACE(U) (N): specifies maximum number of trace lines to keep. Default is 1024.