diff options
73 files changed, 738 insertions, 279 deletions
diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md index 7de7a3470b..ac66e0a816 100644 --- a/.github/workflows/notes.md +++ b/.github/workflows/notes.md @@ -36,7 +36,7 @@ Note: On Windows "Server" you may need to [install vcruntime140.dll](https://lea ### Linux (x86_64) -glibc 2.35 or newer is required. Or you may try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases). +If your system does not have the [required glibc version](https://neovim.io/doc/user/support.html#supported-platforms), try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases). #### AppImage diff --git a/MAINTAIN.md b/MAINTAIN.md index eb58664ed2..13e2c5e772 100644 --- a/MAINTAIN.md +++ b/MAINTAIN.md @@ -241,4 +241,4 @@ See also -------- * https://github.com/neovim/neovim/issues/862 -* https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt +* https://github.com/git/git/blob/master/Documentation/howto/maintain-git.adoc diff --git a/cmake.deps/deps.txt b/cmake.deps/deps.txt index 38fd4fd996..cf555cb54b 100644 --- a/cmake.deps/deps.txt +++ b/cmake.deps/deps.txt @@ -34,8 +34,8 @@ LIBICONV_SHA256 8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313 UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/v2.10.0.tar.gz UTF8PROC_SHA256 6f4f1b639daa6dca9f80bc5db1233e9cbaa31a67790887106160b33ef743f136 -TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.23.2.tar.gz -TREESITTER_C_SHA256 d8b9c1b2ffb6a42caf9bc76e07c52507d4e60b17175ed9beb0e779be8db1200c +TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.23.4.tar.gz +TREESITTER_C_SHA256 b66c5043e26d84e5f17a059af71b157bcf202221069ed220aa1696d7d1d28a7a TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.2.0.tar.gz TREESITTER_LUA_SHA256 6c41227cd0a59047b19d31f0031d4d901f08bfd78d6fc7f55c89e5b8374c794e TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.4.0.tar.gz diff --git a/contrib/zsh-completion.zsh b/contrib/zsh-completion.zsh new file mode 100644 index 0000000000..73fc7045ec --- /dev/null +++ b/contrib/zsh-completion.zsh @@ -0,0 +1,36 @@ +#compdef nvim + +# zsh completions for 'nvim' +# automatically generated with http://github.com/RobSis/zsh-completion-generator +local arguments + +arguments=( + '*--cmd[execute <cmd> before any config]:command' + '*-c[Execute <cmd> after config and first file]:command' + '-l[Execute Lua <script> (with optional args)]:script:_files -g "*.lua"' # TODO: remaining args are passed to <script> and not opened by nvim for edit + '-S[source <session> after loading the first file]::session:_files' + '-s[read Normal mode commands from <scriptin>]:file:_files' + '-u[use this config file]:config' + '-d[diff mode]' + {-es,-Es}'[silent (batch) mode]' + '(- *)'{-h,--help}'[print this help message]' + '-i[use this shada file]:shada:_files -g "*.shada"' + '-n[no swap file, use memory only]' + '-o-[open N windows (default: one per file)]::N' + '-O-[open N vertical windows (default: one per file)]::N' + '-p-[open N tab pages (default: one per file)]::N' + '-R[read-only (view) mode]' + '(- *)'{-v,--version}'[print version information]' + '-V[verbose \[level\]\[file\]]' + '(- *)--api-info[write msgpack-encoded API metadata to stdout]' + '--clean["Factory defaults" (skip user config and plugins, shada)]' + '--embed[use stdin/stdout as a msgpack-rpc channel]' + '--headless[dont start a user interface]' + '--listen[serve RPC API from this address]:address' + '--remote[\[-subcommand\] Execute commands remotely on a server]' + '--server[connect to this Nvim server]:address' + '--startuptime[write startup timing messages to <file>]:file:_files' + '*:filename:_files' +) + +_arguments -s $arguments diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index a714034e50..e096231724 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -2924,8 +2924,7 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) 'nowrap', otherwise the same as "trunc". • ephemeral : for use with |nvim_set_decoration_provider()| callbacks. The mark will only be used for the current - redraw cycle, and not be permantently stored in the - buffer. + redraw cycle, and not be permanently stored in the buffer. • right_gravity : boolean that indicates the direction the extmark will be shifted in when new text is inserted (true for right, false for left). Defaults to true. diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 9214b33519..2ba464e80c 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -6462,7 +6462,7 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* Parameters: ~ • {list} (`any[]`) • {str} (`string`) - • {dict} (`string?`) + • {dict} (`table?`) Return: ~ (`any`) @@ -6492,7 +6492,7 @@ matchfuzzypos({list}, {str} [, {dict}]) *matchfuzzypos()* Parameters: ~ • {list} (`any[]`) • {str} (`string`) - • {dict} (`string?`) + • {dict} (`table?`) Return: ~ (`any`) diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 68258fedb4..21f35637e6 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -42,7 +42,7 @@ LSP • *vim.lsp.util.jump_to_location* Use |vim.lsp.util.show_document()| with `{focus=true}` instead. • *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| instead. -• *vim.lsp.buf.completion* Use |vim.lsp.completion.trigger()| instead. +• *vim.lsp.buf.completion* Use |vim.lsp.completion.get()| instead. • vim.lsp.buf_request_all The `error` key has been renamed to `err` inside the result parameter of the handler. • *vim.lsp.with()* Pass configuration to equivalent diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index bbc1d1de2c..2b891bde1b 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -122,7 +122,7 @@ with |vim.notify()|: >lua -- Users can configure the handler vim.diagnostic.config({ ["my/notify"] = { - log_level = vim.log.levels.INFO + log_level = vim.log.levels.INFO, -- This handler will only receive "error" diagnostics. severity = vim.diagnostic.severity.ERROR, diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index 2e0de44e56..a68d94828b 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -615,7 +615,7 @@ with interactive `git rebase`: > :Reword " to pick this commit, but change the commit message :Squash " to squash this commit into the previous one -In addition, the following comamnd can be used to cycle between the different +In addition, the following command can be used to cycle between the different possibilities: > :Cycle " to cycle between the previous commands diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 31e6dd1ec4..51954e5449 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -1506,6 +1506,11 @@ both major engines implemented element, even if this is not in standards it will be suggested. All other elements are not placed in suggestion list. +LUA *ft-lua-omni* + +Lua |ftplugin| sets 'omnifunc' to |vim.lua_omnifunc()|. + + PHP *ft-php-omni* Completion of PHP code requires a tags file for completion of data from diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index f13a17cbef..3a2de6bc70 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -882,14 +882,23 @@ foldexpr({lnum}) *vim.lsp.foldexpr()* Provides an interface between the built-in client and a `foldexpr` function. - To use, check for the "textDocument/foldingRange" capability in an - |LspAttach| autocommand. Example: >lua + To use, set 'foldmethod' to "expr" and set the value of 'foldexpr': >lua + vim.o.foldmethod = 'expr' + vim.o.foldexpr = 'v:lua.vim.lsp.foldexpr()' +< + + Or use it only when supported by checking for the + "textDocument/foldingRange" capability in an |LspAttach| autocommand. + Example: >lua + vim.o.foldmethod = 'expr' + -- Default to treesitter folding + vim.o.foldexpr = 'v:lua.vim.treesitter.foldexpr()' + -- Prefer LSP folding if client supports it vim.api.nvim_create_autocmd('LspAttach', { callback = function(args) local client = vim.lsp.get_client_by_id(args.data.client_id) if client:supports_method('textDocument/foldingRange') then local win = vim.api.nvim_get_current_win() - vim.wo[win][0].foldmethod = 'expr' vim.wo[win][0].foldexpr = 'v:lua.vim.lsp.foldexpr()' end end, @@ -1870,7 +1879,7 @@ enable({enable}, {client_id}, {bufnr}, {opts}) • {opts} (`vim.lsp.completion.BufferOpts?`) See |vim.lsp.completion.BufferOpts|. -trigger({opts}) *vim.lsp.completion.trigger()* +get({opts}) *vim.lsp.completion.get()* Triggers LSP completion once in the current buffer. Parameters: ~ diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index a99b050195..86cfc56693 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -4288,7 +4288,7 @@ Iter:last() *Iter:last()* (`any`) See also: ~ - • Iter.rpeek + • |Iter:rpeek()| Iter:map({f}) *Iter:map()* Maps the items of an iterator pipeline to the values returned by `f`. @@ -4425,7 +4425,7 @@ Iter:rfind({f}) *Iter:rfind()* (`any`) See also: ~ - • Iter.find + • |Iter:find()| Iter:rpeek() *Iter:rpeek()* Gets the last value of a |list-iterator| without consuming it. @@ -4444,7 +4444,7 @@ Iter:rpeek() *Iter:rpeek()* (`any`) See also: ~ - • Iter.last + • |Iter:last()| Iter:rskip({n}) *Iter:rskip()* Discards `n` values from the end of a |list-iterator| pipeline. diff --git a/runtime/doc/luaref.txt b/runtime/doc/luaref.txt index cd0b648560..ffcd537d7b 100644 --- a/runtime/doc/luaref.txt +++ b/runtime/doc/luaref.txt @@ -3905,7 +3905,7 @@ package.cpath *package.cpath* variable `LUA_CPATH` (plus another default path defined in `luaconf.h`). -package.loaded *package.loaded()* +package.loaded *package.loaded* A table used by `require` to control which modules are already loaded. When you require a module `modname` and `package.loaded[modname]` is not false, `require` simply returns the value stored there. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 54a67ebb59..f7f86237f6 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -29,7 +29,8 @@ LSP • `vim.lsp.buf.document_symbol()` uses the |location-list| by default. Use `vim.lsp.buf.document_symbol({ loclist = false })` to use the |quickfix| list. - +• `vim.lsp.completion.trigger()` has been renamed to + |vim.lsp.completion.get()|. OPTIONS @@ -70,12 +71,6 @@ BUILD • Translations are turned off by default. Enable by building Nvim with the CMake flag `ENABLE_TRANSLATIONS=ON`. -DEFAULTS - -• 'number', 'relativenumber', 'signcolumn', and 'foldcolumn' are disabled in - |terminal| buffers. See |terminal-config| for an example of changing these defaults. -• 'diffopt' default includes "linematch:40". - DIAGNOSTICS • The "underline" diagnostics handler sorts diagnostics by severity when using @@ -247,6 +242,15 @@ DEFAULTS • |[[| and |]]| in Normal mode jump between shell prompts for shells which emit OSC 133 sequences ("shell integration" or "semantic prompts"). +• Options: + • 'diffopt' default includes "linematch:40". + • 'number', 'relativenumber', 'signcolumn', and 'foldcolumn' are disabled in + |terminal| buffers. |terminal-config| shows how to change these defaults. + +• Options: + • Lua |ftplugin| sets 'omnifunc' to "v:lua.vim.lua_omnifunc". + • Lua |ftplugin| sets 'foldexpr' to "v:lua.vim.treesitter.foldexpr()". + • Snippet: • `<Tab>` in Insert and Select mode maps to `vim.snippet.jump({ direction = 1 })` when a snippet is active and jumpable forwards. @@ -362,6 +366,7 @@ PERFORMANCE significantly improving |treesitter-highlight| performance. • Treesitter injection query iteration is now asynchronous, making edits in large buffers with combined injections much quicker. +• 10x reduction in blocking time when attaching an LSP to a large buffer. PLUGINS diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index e42fb4f9e4..7aca0268c6 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1528,7 +1528,7 @@ A jump table for the options with a short description can be found at |Q_op|. order. *'completeopt'* *'cot'* -'completeopt' 'cot' string (default "menu,preview") +'completeopt' 'cot' string (default "menu,popup") global or local to buffer |global-local| A comma-separated list of options for Insert mode completion |ins-completion|. The supported values are: diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt index 9895b606fd..beae7b3ae7 100644 --- a/runtime/doc/sign.txt +++ b/runtime/doc/sign.txt @@ -123,8 +123,8 @@ See |sign_define()| for the equivalent Vim script function. numhl={group} Highlighting group used for the line number on the line where - the sign is placed. Overrides |hl-LineNr|, |hl-LineNrAbove|, - |hl-LineNrBelow|, and |hl-CursorLineNr|. + the sign is placed. Combines with |hl-LineNr|, + |hl-LineNrAbove|, |hl-LineNrBelow|, and |hl-CursorLineNr|. text={text} *E239* Define the text that is displayed when there is no icon or the diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 00486a49db..2feee0a511 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -336,7 +336,7 @@ Upon loading a file, Vim finds the relevant syntax file as follows: ============================================================================== 4. Conversion to HTML *convert-to-HTML* *2html.vim* -The old to html converter has ben replaced by a Lua version and the +The old to html converter has been replaced by a Lua version and the documentation has been moved to |:TOhtml|. ============================================================================== @@ -811,6 +811,21 @@ doesn't work for you, or you don't edit Progress at all, use this in your startup vimrc: > :let filetype_w = "cweb" +CSHARP *cs.vim* *ft-cs-syntax* + +C# raw string literals may use any number of quote marks to encapsulate the +block, and raw interpolated string literals may use any number of braces to +encapsulate the interpolation, e.g. > + + $$$""""Hello {{{name}}}"""" +< +By default, Vim highlights 3-8 quote marks, and 1-8 interpolation braces. +The maximum numbers of quotes and braces recognized can configured using the +following variables: + + Variable Default ~ + g:cs_raw_string_quote_count 8 + g:cs_raw_string_interpolation_brace_count 8 DART *dart.vim* *ft-dart-syntax* diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 9bd23313e3..df79d25198 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -46,6 +46,7 @@ Defaults *defaults* *nvim-defaults* - 'commentstring' defaults to "" - 'compatible' is always disabled - 'complete' excludes "i" +- 'completeopt' defaults to "menu,popup" - 'define' defaults to "". The C ftplugin sets it to "^\\s*#\\s*define" - 'diffopt' defaults to "internal,filler,closeoff,linematch:40" - 'directory' defaults to ~/.local/state/nvim/swap// (|xdg|), auto-created diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 6dd90f7e49..89a9c7dda3 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -1272,7 +1272,7 @@ list of buffers. |unlisted-buffer| :w foobar | sp # < Also see |+cmd|. -:[N]bn[ext][!] [+cmd] [N] *:bn* *:bnext* *[b* *E87* +:[N]bn[ext][!] [+cmd] [N] *:bn* *:bnext* *]b* *E87* Go to [N]th next buffer in buffer list. [N] defaults to one. Wraps around the end of the buffer list. See |:buffer-!| for [!]. @@ -1290,7 +1290,7 @@ list of buffers. |unlisted-buffer| Wraps around the end of the buffer list. Uses 'switchbuf' Also see |+cmd|. -:[N]bN[ext][!] [+cmd] [N] *:bN* *:bNext* *:bp* *:bprevious* *]b* *E88* +:[N]bN[ext][!] [+cmd] [N] *:bN* *:bNext* *:bp* *:bprevious* *[b* *E88* :[N]bp[revious][!] [+cmd] [N] Go to [N]th previous buffer in buffer list. [N] defaults to one. Wraps around the start of the buffer list. diff --git a/runtime/ftplugin/cs.vim b/runtime/ftplugin/cs.vim index ada71315e1..d40fe43ebc 100644 --- a/runtime/ftplugin/cs.vim +++ b/runtime/ftplugin/cs.vim @@ -2,8 +2,7 @@ " Language: C# " Maintainer: Nick Jensen <nickspoon@gmail.com> " Former Maintainer: Johannes Zellner <johannes@zellner.org> -" Last Change: 2022-11-16 -" 2024 Jan 14 by Vim Project (browsefilter) +" Last Change: 2025-03-14 " License: Vim (see :h license) " Repository: https://github.com/nickspoons/vim-cs @@ -21,8 +20,11 @@ setlocal formatoptions-=t formatoptions+=croql " Set 'comments' to format dashed lists in comments. setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// +setlocal commentstring=//\ %s -let b:undo_ftplugin = 'setl com< fo<' +setlocal cinoptions=J1 + +let b:undo_ftplugin = 'setl com< fo< cino<' if exists('loaded_matchit') && !exists('b:match_words') " #if/#endif support included by default diff --git a/runtime/ftplugin/lua.lua b/runtime/ftplugin/lua.lua index 75deb6b190..e0f7e95cf6 100644 --- a/runtime/ftplugin/lua.lua +++ b/runtime/ftplugin/lua.lua @@ -1,4 +1,9 @@ -- use treesitter over syntax vim.treesitter.start() -vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '') .. '\n call v:lua.vim.treesitter.stop()' +vim.bo.omnifunc = 'v:lua.vim.lua_omnifunc' +vim.wo[0][0].foldexpr = 'v:lua.vim.treesitter.foldexpr()' + +vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '') + .. '\n call v:lua.vim.treesitter.stop()' + .. '\n setl omnifunc< foldexpr<' diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua index b890b64174..63a7bcc37d 100644 --- a/runtime/lua/vim/_meta/api.lua +++ b/runtime/lua/vim/_meta/api.lua @@ -630,8 +630,7 @@ function vim.api.nvim_buf_line_count(buffer) end --- otherwise the same as "trunc". --- - ephemeral : for use with `nvim_set_decoration_provider()` --- callbacks. The mark will only be used for the current ---- redraw cycle, and not be permantently stored in the ---- buffer. +--- redraw cycle, and not be permanently stored in the buffer. --- - right_gravity : boolean that indicates the direction --- the extmark will be shifted in when new text is inserted --- (true for right, false for left). Defaults to true. diff --git a/runtime/lua/vim/_meta/builtin_types.lua b/runtime/lua/vim/_meta/builtin_types.lua index eae76d80d7..9dd0374486 100644 --- a/runtime/lua/vim/_meta/builtin_types.lua +++ b/runtime/lua/vim/_meta/builtin_types.lua @@ -259,12 +259,12 @@ --- write. The number is the write count. The --- first write has number 1, the last one the --- "save_last" mentioned above. ---- @field save integer +--- @field save? integer --- --- Alternate entry. This is again a List of undo --- blocks. Each item may again have an "alt" --- item. ---- @field alt vim.fn.undotree.entry[] +--- @field alt? vim.fn.undotree.entry[] --- @class vim.fn.undotree.ret --- diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 59e65b0585..775dda59f7 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -1109,7 +1109,7 @@ vim.go.cia = vim.go.completeitemalign --- combination with "menu" or "menuone". --- --- @type string -vim.o.completeopt = "menu,preview" +vim.o.completeopt = "menu,popup" vim.o.cot = vim.o.completeopt vim.bo.completeopt = vim.o.completeopt vim.bo.cot = vim.bo.completeopt diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 6ffd0e9619..2b4f1a32b0 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -5868,7 +5868,7 @@ function vim.fn.matchend(expr, pat, start, count) end --- --- @param list any[] --- @param str string ---- @param dict? string +--- @param dict? table --- @return any function vim.fn.matchfuzzy(list, str, dict) end @@ -5895,7 +5895,7 @@ function vim.fn.matchfuzzy(list, str, dict) end --- --- @param list any[] --- @param str string ---- @param dict? string +--- @param dict? table --- @return any function vim.fn.matchfuzzypos(list, str, dict) end diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 1473b8dd47..2cfa97ac40 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1871,7 +1871,10 @@ local function render_virtual_lines(namespace, bufnr, diagnostics) end end - api.nvim_buf_set_extmark(bufnr, namespace, lnum, 0, { virt_lines = virt_lines }) + api.nvim_buf_set_extmark(bufnr, namespace, lnum, 0, { + virt_lines_overflow = 'scroll', + virt_lines = virt_lines, + }) end end diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index 0d42e8fed6..75cbfdef4a 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -118,7 +118,13 @@ local function filepath_to_healthcheck(path) func = 'health#' .. name .. '#check' filetype = 'v' else - local subpath = path:gsub('.*/lua/', '') + local rtp = vim + .iter(vim.api.nvim_list_runtime_paths()) + :map(vim.fs.normalize) + :find(function(rtp0) + return vim.fs.relpath(rtp0, path) + end) + local subpath = path:gsub('^' .. vim.pesc(rtp .. '/lua/'), '') if vim.fs.basename(subpath) == 'health.lua' then -- */health.lua name = vim.fs.dirname(subpath) diff --git a/runtime/lua/vim/iter.lua b/runtime/lua/vim/iter.lua index 4bbcaf16db..bdbe2be95a 100644 --- a/runtime/lua/vim/iter.lua +++ b/runtime/lua/vim/iter.lua @@ -652,7 +652,7 @@ end --- --- ``` --- ----@see Iter.find +---@see |Iter:find()| --- ---@param f any ---@return any @@ -757,7 +757,7 @@ end --- -- 4 --- ``` --- ----@see Iter.last +---@see |Iter:last()| --- ---@return any function Iter:rpeek() @@ -942,7 +942,7 @@ end --- --- ``` --- ----@see Iter.rpeek +---@see |Iter:rpeek()| --- ---@return any function Iter:last() diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 6c23c24220..bb4e1cd28f 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1365,16 +1365,26 @@ end --- Provides an interface between the built-in client and a `foldexpr` function. --- ---- To use, check for the "textDocument/foldingRange" capability in an ---- |LspAttach| autocommand. Example: +--- To use, set 'foldmethod' to "expr" and set the value of 'foldexpr': --- --- ```lua +--- vim.o.foldmethod = 'expr' +--- vim.o.foldexpr = 'v:lua.vim.lsp.foldexpr()' +--- ``` +--- +--- Or use it only when supported by checking for the "textDocument/foldingRange" +--- capability in an |LspAttach| autocommand. Example: +--- +--- ```lua +--- vim.o.foldmethod = 'expr' +--- -- Default to treesitter folding +--- vim.o.foldexpr = 'v:lua.vim.treesitter.foldexpr()' +--- -- Prefer LSP folding if client supports it --- vim.api.nvim_create_autocmd('LspAttach', { --- callback = function(args) --- local client = vim.lsp.get_client_by_id(args.data.client_id) --- if client:supports_method('textDocument/foldingRange') then --- local win = vim.api.nvim_get_current_win() ---- vim.wo[win][0].foldmethod = 'expr' --- vim.wo[win][0].foldexpr = 'v:lua.vim.lsp.foldexpr()' --- end --- end, diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 2da591e9bb..bd78f1ad50 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1152,7 +1152,7 @@ local function on_code_action_results(results, opts) return end - if not action.edit or not action.command and client:supports_method(ms.codeAction_resolve) then + if not (action.edit and action.command) and client:supports_method(ms.codeAction_resolve) then client:request(ms.codeAction_resolve, action, function(err, resolved_action) if err then -- If resolve fails, try to apply the edit/command from the original code action. diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 4064e02597..dcb7b5fa9b 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -536,7 +536,7 @@ local function on_insert_char_pre(handle) local ctx = { triggerKind = protocol.CompletionTriggerKind.TriggerForIncompleteCompletions } if debounce_ms == 0 then vim.schedule(function() - M.trigger({ ctx = ctx }) + M.get({ ctx = ctx }) end) else completion_timer = new_timer() @@ -544,7 +544,7 @@ local function on_insert_char_pre(handle) debounce_ms, 0, vim.schedule_wrap(function() - M.trigger({ ctx = ctx }) + M.get({ ctx = ctx }) end) ) end @@ -791,13 +791,13 @@ function M.enable(enable, client_id, bufnr, opts) end --- @inlinedoc ---- @class vim.lsp.completion.trigger.Opts +--- @class vim.lsp.completion.get.Opts --- @field ctx? lsp.CompletionContext Completion context. Defaults to a trigger kind of `invoked`. --- Triggers LSP completion once in the current buffer. --- ---- @param opts? vim.lsp.completion.trigger.Opts -function M.trigger(opts) +--- @param opts? vim.lsp.completion.get.Opts +function M.get(opts) opts = opts or {} local ctx = opts.ctx or { triggerKind = protocol.CompletionTriggerKind.Invoked } local bufnr = api.nvim_get_current_buf() diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index a0d1fe776b..d31d94cab7 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -278,10 +278,8 @@ function Client:encode_and_send(payload) if self.transport:is_closing() then return false end - local jsonstr = assert( - vim.json.encode(payload), - string.format("Couldn't encode payload '%s'", vim.inspect(payload)) - ) + local jsonstr = vim.json.encode(payload) + self.transport:write(format_message_with_content_length(jsonstr)) return true end diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 307a55c2a2..056cb0c73c 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1345,7 +1345,7 @@ local function close_preview_window(winnr, bufnrs) return end - local augroup = 'preview_window_' .. winnr + local augroup = 'nvim.preview_window_' .. winnr pcall(api.nvim_del_augroup_by_name, augroup) pcall(api.nvim_win_close, winnr, true) end) diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index f370cbfb4e..3aeda1586d 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -7,7 +7,8 @@ -- so this wouldn't be a separate case to consider) ---@nodoc -_G.vim = _G.vim or {} --[[@as table]] -- TODO(lewis6991): better fix for flaky luals +_G.vim = _G.vim or {} --[[@as table]] +-- TODO(lewis6991): better fix for flaky luals ---@generic T ---@param orig T diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim index 079cc668f0..ff37159f19 100644 --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -1,12 +1,14 @@ " Vim plugin for showing matching parens " Maintainer: The Vim Project <https://github.com/vim/vim> -" Last Change: 2025 Mar 08 +" Last Change: 2025 Mar 14 " Former Maintainer: Bram Moolenaar <Bram@vim.org> " Exit quickly when: " - this plugin was already loaded (or disabled) " - when 'compatible' is set -if exists("g:loaded_matchparen") || &cp +" - Vim has no support for :defer +if exists("g:loaded_matchparen") || &cp || + \ exists(":defer") != 2 finish endif let g:loaded_matchparen = 1 @@ -21,17 +23,13 @@ if !exists("g:matchparen_disable_cursor_hl") let g:matchparen_disable_cursor_hl = 0 endif -let s:has_matchaddpos = exists('*matchaddpos') - augroup matchparen " Replace all matchparen autocommands autocmd! CursorMoved,CursorMovedI,WinEnter,WinScrolled * call s:Highlight_Matching_Pair() autocmd! BufWinEnter * autocmd SafeState * ++once call s:Highlight_Matching_Pair() autocmd! WinLeave,BufLeave * call s:Remove_Matches() - if exists('##TextChanged') - autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair() - autocmd! TextChangedP * call s:Remove_Matches() - endif + autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair() + autocmd! TextChangedP * call s:Remove_Matches() augroup END " Skip the rest if it was already done. @@ -97,14 +95,9 @@ func s:Highlight_Matching_Pair() " Find the match. When it was just before the cursor move it there for a " moment. if before > 0 - let has_getcurpos = exists("*getcurpos") - if has_getcurpos - " getcurpos() is more efficient but doesn't exist before 7.4.313. - let save_cursor = getcurpos() - else - let save_cursor = winsaveview() - endif + let save_cursor = getcurpos() call cursor(c_lnum, c_col - before) + defer setpos('.', save_cursor) endif if !has("syntax") || !exists("g:syntax_on") @@ -196,30 +189,12 @@ func s:Highlight_Matching_Pair() let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline) endtry - if before > 0 - if has_getcurpos - call setpos('.', save_cursor) - else - call winrestview(save_cursor) - endif - endif - " If a match is found setup match highlighting. - if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom - if s:has_matchaddpos - if !g:matchparen_disable_cursor_hl - call add(w:matchparen_ids, matchaddpos('MatchParen', [[c_lnum, c_col - before], [m_lnum, m_col]], 10)) - else - call add(w:matchparen_ids, matchaddpos('MatchParen', [[m_lnum, m_col]], 10)) - endif + if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom + if !g:matchparen_disable_cursor_hl + call add(w:matchparen_ids, matchaddpos('MatchParen', [[c_lnum, c_col - before], [m_lnum, m_col]], 10)) else - if !g:matchparen_disable_cursor_hl - exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) . - \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/' - else - exe '3match MatchParen /\(\%' . m_lnum . 'l\%' . m_col . 'c\)/' - endif - call add(w:matchparen_ids, 3) + call add(w:matchparen_ids, matchaddpos('MatchParen', [[m_lnum, m_col]], 10)) endif let w:paren_hl_on = 1 endif diff --git a/runtime/queries/lua/injections.scm b/runtime/queries/lua/injections.scm index 4345c71ce8..a087340973 100644 --- a/runtime/queries/lua/injections.scm +++ b/runtime/queries/lua/injections.scm @@ -17,8 +17,7 @@ (string content: _ @injection.content))) (#set! injection.language "vim") - (#any-of? @_vimcmd_identifier - "vim.cmd" "vim.api.nvim_command" "vim.api.nvim_command" "vim.api.nvim_exec2")) + (#any-of? @_vimcmd_identifier "vim.cmd" "vim.api.nvim_command" "vim.api.nvim_exec2")) ((function_call name: (_) @_vimcmd_identifier diff --git a/runtime/queries/markdown/folds.scm b/runtime/queries/markdown/folds.scm index a682e20e00..2bcfd442d2 100644 --- a/runtime/queries/markdown/folds.scm +++ b/runtime/queries/markdown/folds.scm @@ -1,7 +1,12 @@ ([ (fenced_code_block) (indented_code_block) - (list) + (list_item + (list)) (section) ] @fold (#trim! @fold)) + +(section + (list) @fold + (#trim! @fold)) diff --git a/runtime/syntax/cs.vim b/runtime/syntax/cs.vim index 104470ac4b..3ae6bfca8d 100644 --- a/runtime/syntax/cs.vim +++ b/runtime/syntax/cs.vim @@ -3,7 +3,7 @@ " Maintainer: Nick Jensen <nickspoon@gmail.com> " Former Maintainers: Anduin Withers <awithers@anduin.com> " Johannes Zellner <johannes@zellner.org> -" Last Change: 2022-11-16 +" Last Change: 2025-03-14 " Filenames: *.cs " License: Vim (see :h license) " Repository: https://github.com/nickspoons/vim-cs @@ -190,6 +190,18 @@ syn match csUnicodeNumber +\\U00\x\{6}+ contained contains=csUnicodeSpecifier di syn match csUnicodeSpecifier +\\[uUx]+ contained display syn region csString matchgroup=csQuote start=+"+ end=+"\%(u8\)\=+ end=+$+ extend contains=csSpecialChar,csSpecialError,csUnicodeNumber,@Spell + +for s:i in range(3, get(g:, "cs_raw_string_quote_count", 8)) + exe 'syn region csRawString' .. s:i .. ' matchgroup=csQuote start=+\z("\{' .. s:i .. '}\)+ end=+\z1+ oneline nextgroup=csRawStringError' .. s:i + exe 'syn region csRawString' .. s:i .. ' matchgroup=csQuote start=+\z("\{' .. s:i .. '}\)\s*$+ end=+^\s*\z1+ nextgroup=csRawStringError' .. s:i .. ' contains=csRawStringError' .. s:i + exe 'syn match csRawStringError' .. s:i .. ' /\%("\{' .. s:i .. '}\)\@' .. s:i .. '<="\+/ contained' + exe 'syn match csRawStringError' .. s:i .. ' /\S.\{-}\s*"\{' .. s:i .. '}"\@!/ contained' + + exe 'hi def link csRawString' .. s:i .. ' csString' + exe 'hi def link csRawStringError' .. s:i .. ' Error' +endfor +unlet s:i + syn match csCharacter "'[^']*'" contains=csSpecialChar,csSpecialCharError,csUnicodeNumber display syn match csCharacter "'\\''" contains=csSpecialChar display syn match csCharacter "'[^\\]'" display @@ -217,11 +229,26 @@ syn match csInterpolationAlignDel +,+ contained display syn match csInterpolationFormatDel +:+ contained display syn region csVerbatimString matchgroup=csQuote start=+@"+ end=+"\%(u8\)\=+ skip=+""+ extend contains=csVerbatimQuote,@Spell + +" Interpolated raw string literals +for s:i in range(1, get(g:, "cs_raw_string_interpolation_brace_count", 8)) + exe 'syn region csInterpolatedRawString' .. s:i .. ' matchgroup=csQuote start=+$\{' .. s:i .. '}\z("""\+\)+ end=+\z1+ extend contains=csInterpolation' .. s:i .. ',csInterpolationDelimiterError' .. s:i .. ',@Spell' + exe 'syn match csInterpolationDelimiterError' .. s:i .. ' "}\{' .. s:i .. '}" contained' + exe 'syn match csInterpolationDelimiterError' .. s:i .. ' "{\{' .. 2 * s:i .. ',}" contained' + exe 'syn match csInterpolationDelimiterError' .. s:i .. ' "}\{' .. 2 * s:i .. ',}" contained' + exe 'syn region csInterpolation' .. s:i .. ' matchgroup=csInterpolationDelimiter start=+\%({\{' .. s:i .. '}\)\@' .. s:i .. '<!{\{' .. s:i .. '}{\@!+ end=+}\@<!}\{' .. s:i .. '}\%(}\{' .. s:i .. '}\)\@!+' .. + \ ' keepend contained contains=@csAll,csBraced,csBracketed,csInterpolationAlign,csInterpolationFormat,csInterpolationDelimiterError' .. s:i + + exe 'hi def link csInterpolationDelimiterError' .. s:i .. ' Error' + exe 'hi def link csInterpolatedRawString' .. s:i .. ' csRawString' +endfor +unlet s:i + syn match csVerbatimQuote +""+ contained syn region csInterVerbString matchgroup=csQuote start=+$@"+ start=+@$"+ end=+"\%(u8\)\=+ skip=+""+ extend contains=csInterpolation,csEscapedInterpolation,csSpecialChar,csSpecialError,csUnicodeNumber,csVerbatimQuote,@Spell -syn cluster csString contains=csString,csInterpolatedString,csVerbatimString,csInterVerbString +syn cluster csString contains=csString,csInterpolatedString,csVerbatimString,csInterVerbString,csRawString syn cluster csLiteral contains=csBoolean,@csNumber,csCharacter,@csString,csNull @@ -282,6 +309,8 @@ hi def link csLogicSymbols Operator hi def link csSpecialError Error hi def link csSpecialCharError Error hi def link csString String +hi def link csRawString csString +hi def link csRawStringError Error hi def link csQuote String hi def link csInterpolatedString String hi def link csVerbatimString String diff --git a/runtime/syntax/prql.vim b/runtime/syntax/prql.vim new file mode 100644 index 0000000000..2a224cdf02 --- /dev/null +++ b/runtime/syntax/prql.vim @@ -0,0 +1,178 @@ +" Vim syntax file +" Language: PRQL +" Maintainer: vanillajonathan +" Last Change: 2025-03-07 +" +" https://prql-lang.org/ +" https://github.com/PRQL/prql + +" quit when a syntax file was already loaded. +if exists("b:current_syntax") + finish +endif + +" We need nocompatible mode in order to continue lines with backslashes. +" Original setting will be restored. +let s:cpo_save = &cpo +set cpo&vim + +syn keyword prqlBoolean false true +syn keyword prqlSelf this that +syn keyword prqlStatement null +syn keyword prqlConditional case +syn keyword prqlStatement prql let type alias in +syn keyword prqlRepeat loop +syn match prqlOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\|\~\)=\?" +syn match prqlOperator display "&&\|||" +syn keyword prqlInclude module + +" Annotations +syn match prqlAnnotation "@" display contained +syn match prqlAnnotationName "@\s*{\h\%(\w\|=\)*}" display contains=prqlAnnotation + +syn match prqlFunction "\h\w*" display contained + +syn match prqlComment "#.*$" contains=prqlTodo,@Spell +syn keyword prqlTodo FIXME NOTE TODO XXX contained + +" Triple-quoted strings can contain doctests. +syn region prqlString matchgroup=prqlQuotes + \ start=+\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" + \ contains=prqlEscape,@Spell +syn region prqlString matchgroup=prqlTripleQuotes + \ start=+\z('''\|"""\)+ end="\z1" keepend + \ contains=prqlEscape,prqlSpaceError,prqlDoctest,@Spell +syn region prqlFString matchgroup=prqlQuotes + \ start=+[f]\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" + \ contains=prqlEscape,@Spell +syn region prqlFString matchgroup=prqlTripleQuotes + \ start=+f\z('''\|"""\)+ end="\z1" keepend + \ contains=prqlEscape,prqlSpaceError,prqlDoctest,@Spell +syn region prqlRString matchgroup=prqlQuotes + \ start=+r\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" + \ contains=@Spell +syn region prqlRString matchgroup=prqlTripleQuotes + \ start=+r\z('''\|"""\)+ end="\z1" keepend + \ contains=prqlSpaceError,prqlDoctest,@Spell +syn region prqlSString matchgroup=prqlQuotes + \ start=+s\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" + \ contains=@Spell +syn region prqlSString matchgroup=prqlTripleQuotes + \ start=+s\z('''\|"""\)+ end="\z1" keepend + \ contains=prqlSpaceError,prqlDoctest,@Spell + +syn match prqlEscape +\\[bfnrt'"\\]+ contained +syn match prqlEscape "\\\o\{1,3}" contained +syn match prqlEscape "\\x\x\{2}" contained +syn match prqlEscape "\%(\\u\x\{1,6}\)" contained +syn match prqlEscape "\\$" + +" It is very important to understand all details before changing the +" regular expressions below or their order. +" The word boundaries are *not* the floating-point number boundaries +" because of a possible leading or trailing decimal point. +" The expressions below ensure that all valid number literals are +" highlighted, and invalid number literals are not. For example, +" +" - a decimal point in '4.' at the end of a line is highlighted, +" - a second dot in 1.0.0 is not highlighted, +" - 08 is not highlighted, +" - 08e0 or 08j are highlighted, +" +if !exists("prql_no_number_highlight") + " numbers (including complex) + syn match prqlNumber "\<0[oO]\%(_\=\o\)\+\>" + syn match prqlNumber "\<0[xX]\%(_\=\x\)\+\>" + syn match prqlNumber "\<0[bB]\%(_\=[01]\)\+\>" + syn match prqlNumber "\<\%([1-9]\%(_\=\d\)*\|0\+\%(_\=0\)*\)\>" + syn match prqlNumber "\<\d\%(_\=\d\)*[jJ]\>" + syn match prqlNumber "\<\d\%(_\=\d\)*[eE][+-]\=\d\%(_\=\d\)*[jJ]\=\>" + syn match prqlNumber + \ "\<\d\%(_\=\d\)*\.\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\%(\W\|$\)\@=" + syn match prqlNumber + \ "\%(^\|\W\)\zs\%(\d\%(_\=\d\)*\)\=\.\d\%(_\=\d\)*\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\>" +endif + +" https://prql-lang.org/book/reference/stdlib/transforms/ +" +" PRQL built-in functions are in alphabetical order. +" + +" Built-in functions +syn keyword prqlBuiltin aggregate derive filter from group join select sort take window + +" Built-in types +syn keyword prqlType bool float int int8 int16 int32 int64 int128 text date time timestamp + +" avoid highlighting attributes as builtins +syn match prqlAttribute /\.\h\w*/hs=s+1 + \ contains=ALLBUT,prqlBuiltin,prqlFunction + \ transparent + +if exists("prql_space_error_highlight") + " trailing whitespace + syn match prqlSpaceError display excludenl "\s\+$" + " mixed tabs and spaces + syn match prqlSpaceError display " \+\t" + syn match prqlSpaceError display "\t\+ " +endif + +" Do not spell doctests inside strings. +" Notice that the end of a string, either ''', or """, will end the contained +" doctest too. Thus, we do *not* need to have it as an end pattern. +if !exists("prql_no_doctest_highlight") + if !exists("prql_no_doctest_code_highlight") + syn region prqlDoctest + \ start="^\s*>>>\s" end="^\s*$" + \ contained contains=ALLBUT,prqlDoctest,prqlFunction,@Spell + syn region prqlDoctestValue + \ start=+^\s*\%(>>>\s\|\.\.\.\s\|"""\|'''\)\@!\S\++ end="$" + \ contained + else + syn region prqlDoctest + \ start="^\s*>>>" end="^\s*$" + \ contained contains=@NoSpell + endif +endif + +" The default highlight links. Can be overridden later. +hi def link prqlBoolean Boolean +hi def link prqlStatement Statement +hi def link prqlType Type +hi def link prqlConditional Conditional +hi def link prqlRepeat Repeat +hi def link prqlOperator Operator +hi def link prqlInclude Include +hi def link prqlAnnotation Define +hi def link prqlAnnotationName Function +hi def link prqlFunction Function +hi def link prqlComment Comment +hi def link prqlTodo Todo +hi def link prqlSelf Constant +hi def link prqlString String +hi def link prqlFString String +hi def link prqlRString String +hi def link prqlSString String +hi def link prqlQuotes String +hi def link prqlTripleQuotes prqlQuotes +hi def link prqlEscape Special +if !exists("prql_no_number_highlight") + hi def link prqlNumber Number +endif +if !exists("prql_no_builtin_highlight") + hi def link prqlBuiltin Function +endif +if exists("prql_space_error_highlight") + hi def link prqlSpaceError Error +endif +if !exists("prql_no_doctest_highlight") + hi def link prqlDoctest Special + hi def link prqlDoctestValue Define +endif + +let b:current_syntax = "prql" + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:set sw=2 sts=2 ts=8 noet: diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index fa74d9a667..5420816726 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -455,8 +455,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// otherwise the same as "trunc". /// - ephemeral : for use with |nvim_set_decoration_provider()| /// callbacks. The mark will only be used for the current -/// redraw cycle, and not be permantently stored in the -/// buffer. +/// redraw cycle, and not be permanently stored in the buffer. /// - right_gravity : boolean that indicates the direction /// the extmark will be shifted in when new text is inserted /// (true for right, false for left). Defaults to true. diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 87d548bfab..843eb5aa11 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -916,7 +916,7 @@ typedef enum { typedef enum { kWinStyleUnused = 0, - kWinStyleMinimal, /// Minimal UI: no number column, eob markers, etc + kWinStyleMinimal, ///< Minimal UI: no number column, eob markers, etc } WinStyle; typedef enum { diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 1226bba436..a7339772ae 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -182,8 +182,9 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item) void buf_put_decor(buf_T *buf, DecorInline decor, int row, int row2) { - if (decor.ext) { + if (decor.ext && row < buf->b_ml.ml_line_count) { uint32_t idx = decor.data.ext.sh_idx; + row2 = MIN(buf->b_ml.ml_line_count - 1, row2); while (idx != DECOR_ID_INVALID) { DecorSignHighlight *sh = &kv_A(decor_items, idx); buf_put_decor_sh(buf, sh, row, row2); @@ -222,16 +223,17 @@ void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2) void buf_decor_remove(buf_T *buf, int row1, int row2, int col1, DecorInline decor, bool free) { decor_redraw(buf, row1, row2, col1, decor); - if (decor.ext) { + if (decor.ext && row1 < buf->b_ml.ml_line_count) { uint32_t idx = decor.data.ext.sh_idx; + row2 = MIN(buf->b_ml.ml_line_count - 1, row2); while (idx != DECOR_ID_INVALID) { DecorSignHighlight *sh = &kv_A(decor_items, idx); buf_remove_decor_sh(buf, row1, row2, sh); idx = sh->next; } - if (free) { - decor_free(decor); - } + } + if (free) { + decor_free(decor); } } diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 9e65abe3e4..16e3a95121 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -664,11 +664,15 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv) } /// Build and draw the 'statuscolumn' string for line "lnum" in window "wp". -static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int virtnum, int col_rows, +static void draw_statuscol(win_T *wp, winlinevars_T *wlv, int virtnum, int col_rows, statuscol_T *stcp) { - // When called for the first non-filler row of line "lnum" set num v:vars - linenr_T relnum = virtnum == 0 ? abs(get_cursor_rel_lnum(wp, lnum)) : -1; + // Adjust lnum for filler lines belonging to the line above and set lnum v:vars for first + // row, first non-filler line, and first filler line belonging to the current line. + linenr_T lnum = wlv->lnum - ((wlv->n_virt_lines - wlv->filler_todo) < wlv->n_virt_below); + linenr_T relnum = (virtnum == -wlv->filler_lines || virtnum == 0 + || virtnum == (wlv->n_virt_below - wlv->filler_lines)) + ? abs(get_cursor_rel_lnum(wp, lnum)) : -1; char buf[MAXPATHL]; // When a buffer's line count has changed, make a best estimate for the full @@ -1639,7 +1643,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b } else if (statuscol.draw) { // Draw 'statuscolumn' if it is set. const int v = (int)(ptr - line); - draw_statuscol(wp, &wlv, lnum, wlv.row - startrow - wlv.filler_lines, col_rows, &statuscol); + draw_statuscol(wp, &wlv, wlv.row - startrow - wlv.filler_lines, col_rows, &statuscol); if (wp->w_redr_statuscol) { break; } diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index e958610f20..35dcbf295b 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1238,7 +1238,7 @@ static bool win_redraw_signcols(win_T *wp) if (!buf->b_signcols.autom && (*wp->w_p_stc != NUL || (wp->w_maxscwidth > 1 && wp->w_minscwidth != wp->w_maxscwidth))) { buf->b_signcols.autom = true; - buf_signcols_count_range(buf, 0, buf->b_ml.ml_line_count, MAXLNUM, kFalse); + buf_signcols_count_range(buf, 0, buf->b_ml.ml_line_count - 1, MAXLNUM, kFalse); } while (buf->b_signcols.max > 0 && buf->b_signcols.count[buf->b_signcols.max - 1] == 0) { diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index eb3956d155..d29c96a763 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -7200,7 +7200,7 @@ M.funcs = { <results in `['two one']`. ]=], name = 'matchfuzzy', - params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'string' } }, + params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'table' } }, signature = 'matchfuzzy({list}, {str} [, {dict}])', }, matchfuzzypos = { @@ -7229,7 +7229,7 @@ M.funcs = { <results in `[[{"id": 10, "text": "hello"}], [[2, 3]], [127]]` ]=], name = 'matchfuzzypos', - params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'string' } }, + params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'table' } }, signature = 'matchfuzzypos({list}, {str} [, {dict}])', }, matchlist = { diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3b78092daf..af93db9956 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -406,6 +406,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) bool msg_didout_before_start = false; int count = 0; // line number count bool did_inc = false; // incremented RedrawingDisabled + int block_indent = -1; // indent for ext_cmdline block event int retval = OK; cstack_T cstack = { // conditional stack .cs_idx = -1, @@ -573,16 +574,18 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // 2. If no line given, get an allocated line with fgetline(). if (next_cmdline == NULL) { - // Need to set msg_didout for the first line after an ":if", - // otherwise the ":if" will be overwritten. - if (count == 1 && getline_equal(fgetline, cookie, getexline)) { - msg_didout = true; - } - if (fgetline == NULL - || (next_cmdline = fgetline(':', cookie, - cstack.cs_idx < - 0 ? 0 : (cstack.cs_idx + 1) * 2, - true)) == NULL) { + int indent = cstack.cs_idx < 0 ? 0 : (cstack.cs_idx + 1) * 2; + if (count >= 1 && getline_equal(fgetline, cookie, getexline)) { + if (ui_has(kUICmdline)) { + ui_ext_cmdline_block_append((size_t)MAX(0, block_indent), last_cmdline); + block_indent = indent; + } else if (count == 1) { + // Need to set msg_didout for the first line after an ":if", + // otherwise the ":if" will be overwritten. + msg_didout = true; + } + } + if (fgetline == NULL || (next_cmdline = fgetline(':', cookie, indent, true)) == NULL) { // Don't call wait_return() for aborted command line. The NULL // returned for the end of a sourced file or executed function // doesn't do this. @@ -939,6 +942,10 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) } } + if (block_indent >= 0) { + ui_ext_cmdline_block_leave(); + } + did_endif = false; // in case do_cmdline used recursively do_cmdline_end(); diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 7e6dfb8dea..cad0f71941 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -135,7 +135,7 @@ static void extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col, bool } else if (!mt_invalid(key) && key.flags & MT_FLAG_DECOR_SIGNTEXT && buf->b_signcols.autom) { row1 = MIN(alt.pos.row, MIN(key.pos.row, row)); row2 = MAX(alt.pos.row, MAX(key.pos.row, row)); - buf_signcols_count_range(buf, row1, row2, 0, kTrue); + buf_signcols_count_range(buf, row1, MIN(curbuf->b_ml.ml_line_count - 1, row2), 0, kTrue); } if (move) { @@ -145,7 +145,7 @@ static void extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col, bool if (invalid) { buf_put_decor(buf, mt_decor(key), MIN(row, key.pos.row), MAX(row, key.pos.row)); } else if (!mt_invalid(key) && key.flags & MT_FLAG_DECOR_SIGNTEXT && buf->b_signcols.autom) { - buf_signcols_count_range(buf, row1, row2, 0, kNone); + buf_signcols_count_range(buf, row1, MIN(curbuf->b_ml.ml_line_count - 1, row2), 0, kNone); } } @@ -180,7 +180,9 @@ void extmark_del(buf_T *buf, MarkTreeIter *itr, MTKey key, bool restore) } if (mt_decor_any(key)) { - if (mt_invalid(key)) { + // If key is an end mark it has been found first while iterating the marktree, + // indicating the decor is already invalid. + if (mt_invalid(key) || mt_end(key)) { decor_free(mt_decor(key)); } else { buf_decor_remove(buf, key.pos.row, key2.pos.row, key.pos.col, mt_decor(key), true); @@ -575,7 +577,8 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t // Remove signs inside edited region from "b_signcols.count", add after splicing. if (old_row > 0 || new_row > 0) { - buf_signcols_count_range(buf, start_row, start_row + old_row, 0, kTrue); + int row2 = MIN(buf->b_ml.ml_line_count - (new_row - old_row) - 1, start_row + old_row); + buf_signcols_count_range(buf, start_row, row2, 0, kTrue); } marktree_splice(buf->b_marktree, (int32_t)start_row, start_col, @@ -583,7 +586,8 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t new_row, new_col); if (old_row > 0 || new_row > 0) { - buf_signcols_count_range(buf, start_row, start_row + new_row, 0, kNone); + int row2 = MIN(buf->b_ml.ml_line_count - 1, start_row + new_row); + buf_signcols_count_range(buf, start_row, row2, 0, kNone); } if (undo == kExtmarkUndo) { diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index d02a698f08..1be4f601bc 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -2169,6 +2169,10 @@ static bool set_ctrl_x_mode(const int c) /// Stop insert completion mode static bool ins_compl_stop(const int c, const int prev_mode, bool retval) { + // Remove pre-inserted text when present. + if (ins_compl_preinsert_effect()) { + ins_compl_delete(false); + } // Get here when we have finished typing a sequence of ^N and // ^P or other completion characters in CTRL-X mode. Free up // memory that was used, and make sure we can redo the insert. diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index ca0349d1f6..2b9a972bc9 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -104,14 +104,14 @@ struct map_arguments { char alt_lhs[MAXMAPLEN + 1]; size_t alt_lhs_len; - char *rhs; /// The {rhs} of the mapping. + char *rhs; ///< The {rhs} of the mapping. size_t rhs_len; - LuaRef rhs_lua; /// lua function as {rhs} - bool rhs_is_noop; /// True when the {rhs} should be <Nop>. + LuaRef rhs_lua; ///< lua function as {rhs} + bool rhs_is_noop; ///< True when the {rhs} should be <Nop>. - char *orig_rhs; /// The original text of the {rhs}. + char *orig_rhs; ///< The original text of the {rhs}. size_t orig_rhs_len; - char *desc; /// map description + char *desc; ///< map description }; typedef struct map_arguments MapArguments; #define MAP_ARGUMENTS_INIT { false, false, false, false, false, false, false, false, \ diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 49de8b92ef..e9f8051ed3 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1483,7 +1483,7 @@ local options = { { abbreviation = 'cot', cb = 'did_set_completeopt', - defaults = 'menu,preview', + defaults = 'menu,popup', values = { 'menu', 'menuone', diff --git a/src/nvim/path.c b/src/nvim/path.c index 6c6a6f58c0..fd2b92e30d 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -613,7 +613,6 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in FUNC_ATTR_NONNULL_ALL { int start_len = gap->ga_len; - size_t len; bool starstar = false; static int stardepth = 0; // depth for "**" expansion @@ -625,9 +624,9 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in } } - // Make room for file name. When doing encoding conversion the actual - // length may be quite a bit longer, thus use the maximum possible length. - char *buf = xmalloc(MAXPATHL); + // Make room for file name (a bit too much to stay on the safe side). + const size_t buflen = strlen(path) + MAXPATHL; + char *buf = xmalloc(buflen); // Find the first part in the path name that contains a wildcard. // When EW_ICASE is set every letter is considered to be a wildcard. @@ -656,10 +655,10 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in ) { e = p; } - len = (size_t)(utfc_ptr2len(path_end)); - memcpy(p, path_end, len); - p += len; - path_end += len; + int charlen = utfc_ptr2len(path_end); + memcpy(p, path_end, (size_t)charlen); + p += charlen; + path_end += charlen; } e = p; *e = NUL; @@ -713,13 +712,14 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in return 0; } + size_t len = (size_t)(s - buf); // If "**" is by itself, this is the first time we encounter it and more // is following then find matches without any directory. if (!didstar && stardepth < 100 && starstar && e - s == 2 && *path_end == '/') { - STRCPY(s, path_end + 1); + vim_snprintf(s, buflen - len, "%s", path_end + 1); stardepth++; - do_path_expand(gap, buf, (size_t)(s - buf), flags, true); + do_path_expand(gap, buf, len, flags, true); stardepth--; } *s = NUL; @@ -731,6 +731,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in const char *name; scandir_next_with_dots(NULL); // initialize while (!got_int && (name = scandir_next_with_dots(&dir)) != NULL) { + len = (size_t)(s - buf); if ((name[0] != '.' || starts_with_dot || ((flags & EW_DODOT) @@ -738,21 +739,22 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in && (name[1] != '.' || name[2] != NUL))) && ((regmatch.regprog != NULL && vim_regexec(®match, name, 0)) || ((flags & EW_NOTWILD) - && path_fnamencmp(path + (s - buf), name, (size_t)(e - s)) == 0))) { - STRCPY(s, name); - len = strlen(buf); + && path_fnamencmp(path + len, name, (size_t)(e - s)) == 0))) { + len += (size_t)vim_snprintf(s, buflen - len, "%s", name); + if (len + 1 >= buflen) { + continue; + } if (starstar && stardepth < 100) { // For "**" in the pattern first go deeper in the tree to // find matches. - STRCPY(buf + len, "/**"); // NOLINT - STRCPY(buf + len + 3, path_end); + vim_snprintf(buf + len, buflen - len, "/**%s", path_end); // NOLINT stardepth++; do_path_expand(gap, buf, len + 1, flags, true); stardepth--; } - STRCPY(buf + len, path_end); + vim_snprintf(buf + len, buflen - len, "%s", path_end); if (path_has_exp_wildcard(path_end)) { // handle more wildcards // need to expand another component of the path // remove backslashes for the remaining components only diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 7c93be844a..440747be76 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -299,7 +299,7 @@ void tui_set_key_encoding(TUIData *tui) // Progressive enhancement flags: // 0b01 (1) Disambiguate escape codes // 0b10 (2) Report event types - out(tui, S_LEN("\x1b[>3u")); + out(tui, S_LEN("\x1b[>1u")); break; case kKeyEncodingXterm: out(tui, S_LEN("\x1b[>4;2m")); diff --git a/src/nvim/ui_defs.h b/src/nvim/ui_defs.h index bbc1655252..b140eee2c5 100644 --- a/src/nvim/ui_defs.h +++ b/src/nvim/ui_defs.h @@ -37,8 +37,8 @@ typedef struct { bool ui_ext[kUIExtCount]; ///< Externalized UI capabilities. int width; int height; - int pum_nlines; /// actual nr. lines shown in PUM - bool pum_pos; /// UI reports back pum position? + int pum_nlines; ///< actual nr. lines shown in PUM + bool pum_pos; ///< UI reports back pum position? double pum_row; double pum_col; double pum_height; diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua index 39072ede9c..106e0df347 100644 --- a/test/functional/editor/completion_spec.lua +++ b/test/functional/editor/completion_spec.lua @@ -4,8 +4,8 @@ local Screen = require('test.functional.ui.screen') local assert_alive = n.assert_alive local clear, feed = n.clear, n.feed -local eval, eq, neq, ok = n.eval, t.eq, t.neq, t.ok -local feed_command, source, expect = n.feed_command, n.source, n.expect +local eval, eq, ok = n.eval, t.eq, t.ok +local source, expect = n.source, n.expect local fn = n.fn local command = n.command local api = n.api @@ -17,6 +17,11 @@ describe('completion', function() before_each(function() clear() + source([[ + set completeopt-=noselect + " Avoid tags completion (if running test locally). + set complete-=t + ]]) screen = Screen.new(60, 8) screen:add_extra_attr_ids { [100] = { foreground = Screen.colors.Gray0, background = Screen.colors.Yellow }, @@ -57,29 +62,12 @@ describe('completion', function() it('is readonly', function() screen:try_resize(80, 8) feed('ifoo<ESC>o<C-x><C-n><ESC>') - feed_command('let v:completed_item.word = "bar"') - neq(nil, string.find(eval('v:errmsg'), '^E46: ')) - feed_command('let v:errmsg = ""') - - feed_command('let v:completed_item.abbr = "bar"') - neq(nil, string.find(eval('v:errmsg'), '^E46: ')) - feed_command('let v:errmsg = ""') - - feed_command('let v:completed_item.menu = "bar"') - neq(nil, string.find(eval('v:errmsg'), '^E46: ')) - feed_command('let v:errmsg = ""') - - feed_command('let v:completed_item.info = "bar"') - neq(nil, string.find(eval('v:errmsg'), '^E46: ')) - feed_command('let v:errmsg = ""') - - feed_command('let v:completed_item.kind = "bar"') - neq(nil, string.find(eval('v:errmsg'), '^E46: ')) - feed_command('let v:errmsg = ""') - - feed_command('let v:completed_item.user_data = "bar"') - neq(nil, string.find(eval('v:errmsg'), '^E46: ')) - feed_command('let v:errmsg = ""') + t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.word = "bar"')) + t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.abbr = "bar"')) + t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.menu = "bar"')) + t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.info = "bar"')) + t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.kind = "bar"')) + t.matches('E46%: ', t.pcall_err(command, 'let v:completed_item.user_data = "bar"')) end) it('returns expected dict in omni completion', function() source([[ @@ -122,7 +110,7 @@ describe('completion', function() end) it('inserts the first candidate if default', function() - feed_command('set completeopt+=menuone') + command('set completeopt+=menuone') feed('ifoo<ESC>o') screen:expect([[ foo | @@ -160,7 +148,7 @@ describe('completion', function() eq('foo', eval('getline(3)')) end) it('selects the first candidate if noinsert', function() - feed_command('set completeopt+=menuone,noinsert') + command('set completeopt+=menuone,noinsert') feed('ifoo<ESC>o<C-x><C-n>') screen:expect([[ foo | @@ -190,7 +178,7 @@ describe('completion', function() eq('foo', eval('getline(3)')) end) it('does not insert the first candidate if noselect', function() - feed_command('set completeopt+=menuone,noselect') + command('set completeopt+=menuone,noselect') feed('ifoo<ESC>o<C-x><C-n>') screen:expect([[ foo | @@ -221,7 +209,7 @@ describe('completion', function() eq('bar', eval('getline(3)')) end) it('does not select/insert the first candidate if noselect and noinsert', function() - feed_command('set completeopt+=menuone,noselect,noinsert') + command('set completeopt+=menuone,noselect,noinsert') feed('ifoo<ESC>o<C-x><C-n>') screen:expect([[ foo | @@ -258,14 +246,14 @@ describe('completion', function() eq('', eval('getline(3)')) end) it('does not change modified state if noinsert', function() - feed_command('set completeopt+=menuone,noinsert') - feed_command('setlocal nomodified') + command('set completeopt+=menuone,noinsert') + command('setlocal nomodified') feed('i<C-r>=TestComplete()<CR><ESC>') eq(0, eval('&l:modified')) end) it('does not change modified state if noselect', function() - feed_command('set completeopt+=menuone,noselect') - feed_command('setlocal nomodified') + command('set completeopt+=menuone,noselect') + command('setlocal nomodified') feed('i<C-r>=TestComplete()<CR><ESC>') eq(0, eval('&l:modified')) end) @@ -279,8 +267,8 @@ describe('completion', function() return '' endfunction ]]) - feed_command('set completeopt+=noselect,noinsert') - feed_command('inoremap <right> <c-r>=TestComplete()<cr>') + command('set completeopt+=noselect,noinsert') + command('inoremap <right> <c-r>=TestComplete()<cr>') end) local tests = { @@ -534,7 +522,7 @@ describe('completion', function() return '' endfunction ]]) - feed_command('set completeopt=menuone,noselect') + command('set completeopt=menuone,noselect') end) it('works', function() @@ -792,7 +780,7 @@ describe('completion', function() end) it('disables folding during completion', function() - feed_command('set foldmethod=indent') + command('set foldmethod=indent') feed('i<Tab>foo<CR><Tab>bar<Esc>gg') screen:expect([[ ^foo | @@ -811,7 +799,7 @@ describe('completion', function() end) it('popupmenu is not interrupted by events', function() - feed_command('set complete=.') + command('set complete=.') feed('ifoobar fooegg<cr>f<c-p>') screen:expect([[ @@ -1027,8 +1015,8 @@ describe('completion', function() end) it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function() - feed_command('set ignorecase infercase') - feed_command('edit runtime/doc/credits.txt') + command('set ignorecase infercase') + command('edit runtime/doc/credits.txt') feed('oX<C-X><C-N>') screen:expect { grid = [[ diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/editor/runtime_spec.lua index b903db14b4..ce46d25a54 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/editor/runtime_spec.lua @@ -51,7 +51,7 @@ describe('runtime:', function() mkdir_p(colorscheme_folder) end) - it('lua colorschemes work and are included in cmdline completion', function() + it('Lua colorschemes work and are included in cmdline completion', function() local colorscheme_file = table.concat({ colorscheme_folder, 'new_colorscheme.lua' }, sep) write_file(colorscheme_file, [[vim.g.lua_colorscheme = 1]]) @@ -129,7 +129,7 @@ describe('runtime:', function() mkdir_p(compiler_folder) end) - it('lua compilers work and are included in cmdline completion', function() + it('Lua compilers work and are included in cmdline completion', function() local compiler_file = compiler_folder .. sep .. 'new_compiler.lua' write_file(compiler_file, [[vim.b.lua_compiler = 1]]) @@ -170,7 +170,7 @@ describe('runtime:', function() describe('ftplugin', function() local ftplugin_folder = table.concat({ plug_dir, 'ftplugin' }, sep) - it('lua ftplugins work and are included in cmdline completion', function() + it('Lua ftplugins work and are included in cmdline completion', function() mkdir_p(ftplugin_folder) local ftplugin_file = table.concat({ ftplugin_folder, 'new-ft.lua' }, sep) write_file(ftplugin_file, [[vim.b.lua_ftplugin = 1]]) @@ -283,7 +283,7 @@ describe('runtime:', function() describe('indent', function() local indent_folder = table.concat({ plug_dir, 'indent' }, sep) - it('lua indents work and are included in cmdline completion', function() + it('Lua indents work and are included in cmdline completion', function() mkdir_p(indent_folder) local indent_file = table.concat({ indent_folder, 'new-ft.lua' }, sep) write_file(indent_file, [[vim.b.lua_indent = 1]]) @@ -328,23 +328,23 @@ describe('runtime:', function() exec([[let b:current_syntax = '']]) end) - it('loads lua syntaxes on filetype change', function() + it('loads Lua syntaxes on filetype change', function() exec('set filetype=my-lang') eq('my-lang', eval('b:current_syntax')) end) - it('loads lua syntaxes on syntax change', function() + it('loads Lua syntaxes on syntax change', function() exec('set syntax=my-lang') eq('my-lang', eval('b:current_syntax')) end) - it('loads lua syntaxes for :ownsyntax', function() + it('loads Lua syntaxes for :ownsyntax', function() exec('ownsyntax my-lang') eq('my-lang', eval('w:current_syntax')) eq('', eval('b:current_syntax')) end) - it('lua syntaxes are included in cmdline completion', function() + it('Lua syntaxes are included in cmdline completion', function() eq({ 'my-lang' }, fn.getcompletion('my-l', 'filetype')) eq({ 'my-lang' }, fn.getcompletion('my-l', 'syntax')) eq({ 'syntax/my-lang.lua' }, fn.getcompletion('syntax/my-l', 'runtime')) @@ -408,7 +408,7 @@ describe('runtime:', function() end) end) - it('lua file loaded by :runtime has proper script ID #32598', function() + it('Lua file loaded by :runtime has proper script ID #32598', function() local test_file = 'Xtest_runtime_cmd.lua' write_file( table.concat({ plug_dir, test_file }, sep), diff --git a/test/functional/fixtures/lua/test_plug/lua/health.lua b/test/functional/fixtures/lua/test_plug/lua/health.lua new file mode 100644 index 0000000000..75164f37ab --- /dev/null +++ b/test/functional/fixtures/lua/test_plug/lua/health.lua @@ -0,0 +1,8 @@ +local M = {} + +M.check = function() + vim.health.start('nested lua/ directory') + vim.health.ok('everything is ok') +end + +return M diff --git a/test/functional/legacy/matchparen_spec.lua b/test/functional/legacy/matchparen_spec.lua index 367830b564..665393463d 100644 --- a/test/functional/legacy/matchparen_spec.lua +++ b/test/functional/legacy/matchparen_spec.lua @@ -4,6 +4,7 @@ local Screen = require('test.functional.ui.screen') local clear = n.clear local exec = n.exec local feed = n.feed +local poke_eventloop = n.poke_eventloop describe('matchparen', function() before_each(clear) @@ -238,5 +239,26 @@ describe('matchparen', function() {1:~ }|*2 | ]]) + -- Send keys one by one so that CursorMoved is triggered. + for _, c in ipairs({ 'A', ' ', 'f', 'o', 'o', 'b', 'a', 'r' }) do + feed(c) + poke_eventloop() + end + screen:expect([[ + {18:#!/bin/sh} | + {25:SUSUWU_PRINT() (} | + {15:case} {15:"}{100:${LEVEL}}{15:"} {15:in} | + {15:"}{100:$SUSUWU_SH_NOTICE}{15:")} foobar^ | + {100:${SUSUWU_S}} {15:&&} {15:return} {26:1} | + {15:;;} | + {15:"}{100:$SUSUWU_SH_DEBUG}{15:")} | + {100:(}{15:!} {100:${SUSUWU_VERBOSE})} {15:&&} {15:return} {26:1} | + {15:;;} | + {15:esac} | + {18:# snip} | + {25:)} | + {1:~ }|*2 + {5:-- INSERT --} | + ]]) end) end) diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua index e73a0780aa..8eb2436cbe 100644 --- a/test/functional/legacy/messages_spec.lua +++ b/test/functional/legacy/messages_spec.lua @@ -88,7 +88,7 @@ describe('messages', function() end) -- oldtest: Test_mode_cleared_after_silent_message() - it('mode is cleared properly after slient message', function() + it('mode is cleared properly after silent message', function() screen = Screen.new(60, 10) exec([[ edit XsilentMessageMode.txt diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 406b5c3c16..1f754b9685 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -212,6 +212,18 @@ describe('vim.health', function() n.expect([[ ERROR: No healthchecks found.]]) end) + + it('nested lua/ directory', function() + command('checkhealth lua') + n.expect([[ + + ============================================================================== + test_plug.lua: require("test_plug.lua.health").check() + + nested lua/ directory ~ + - OK everything is ok + ]]) + end) end) end) diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index 94578aa6da..7772a47589 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -847,7 +847,7 @@ describe('vim.lsp.completion: protocol', function() exec_lua(function() local win = vim.api.nvim_get_current_win() vim.api.nvim_win_set_cursor(win, pos) - vim.lsp.completion.trigger() + vim.lsp.completion.get() end) retry(nil, nil, function() @@ -1153,7 +1153,7 @@ describe('vim.lsp.completion: protocol', function() end, }) - vim.lsp.completion.trigger() + vim.lsp.completion.get() return params end) diff --git a/test/functional/plugin/lsp/folding_range_spec.lua b/test/functional/plugin/lsp/folding_range_spec.lua index 7e68a598d2..601f00ef8a 100644 --- a/test/functional/plugin/lsp/folding_range_spec.lua +++ b/test/functional/plugin/lsp/folding_range_spec.lua @@ -612,7 +612,7 @@ static int foldLevel(linenr_T lnum) }) end) - it('is defered when the buffer is not up-to-date', function() + it('is deferred when the buffer is not up-to-date', function() exec_lua(function() vim.lsp.foldclose('comment') vim.lsp.util.buf_versions[bufnr] = 0 diff --git a/test/functional/testnvim.lua b/test/functional/testnvim.lua index ff5f9ff2e8..0a12cf0920 100644 --- a/test/functional/testnvim.lua +++ b/test/functional/testnvim.lua @@ -620,6 +620,8 @@ function M.insert(...) nvim_feed('<ESC>') end +--- @deprecated Use `command()` or `feed()` instead. +--- --- Executes an ex-command by user input. Because nvim_input() is used, Vimscript --- errors will not manifest as client (lua) errors. Use command() for that. --- @param ... string diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 0ee994ba0a..6e2f1f244f 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -477,7 +477,7 @@ describe('Command-line coloring', function() :++^ | ]]) end) - it('does not error out when called from a errorred out cycle', function() + it('does not error out when called from a errored out cycle', function() set_color_cb('ReturningGlobal', { { 0, 1, 'Normal' } }) feed(dedent([[ :set regexpengine=2 @@ -628,7 +628,7 @@ describe('Ex commands coloring', function() local msg = 'E5405: Chunk 0 start 10 splits multibyte character' eq('\n' .. msg, fn.execute('messages')) end) - it('does not error out when called from a errorred out cycle', function() + it('does not error out when called from a errored out cycle', function() -- Apparently when there is a cycle in which one of the commands errors out -- this error may be caught by color_cmdline before it is presented to the -- user. diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index ce7c9596bb..cb9d978a0f 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -865,6 +865,59 @@ local function test_cmdline(linegrid) }, }) end) + + it('works with conditionals', function() + local s1 = [[ + ^ | + {1:~ }|*3 + | + ]] + screen:expect(s1) + feed(':if 1<CR>') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { '' } }, + firstc = ':', + indent = 2, + pos = 0, + }, + }, + cmdline_block = { { { 'if 1' } } }, + }) + feed(':let x = 1<CR>') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { '' } }, + firstc = ':', + indent = 2, + pos = 0, + }, + }, + cmdline_block = { { { 'if 1' } }, { { ' :let x = 1' } } }, + }) + feed(':endif') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { ':endif' } }, + firstc = ':', + indent = 2, + pos = 6, + }, + }, + cmdline_block = { { { 'if 1' } }, { { ' :let x = 1' } } }, + }) + feed('<CR>') + screen:expect({ + grid = s1, + cmdline = { { abort = false } }, + }) + end) end -- the representation of cmdline and cmdline_block contents changed with ext_linegrid diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index c0c0bf4fc1..240a5acc99 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -6366,6 +6366,30 @@ l5 ]] }) end) + + it('signcolumn correctly tracked with signs beyond eob and pair end before start', function() + api.nvim_set_option_value('signcolumn', 'auto:2', {}) + api.nvim_set_option_value('filetype', 'lua', {}) + api.nvim_buf_set_lines(0, 0, -1, false, {'foo', 'bar'}) + api.nvim_buf_set_extmark(0, ns, 2, 0, {sign_text='S1'}) + api.nvim_set_hl(0, 'SignColumn', { link = 'Error' }) + screen:expect([[ + ^foo | + bar | + {1:~ }|*7 + | + ]]) + api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S2', end_row = 1}) + api.nvim_buf_set_lines(0, 0, -1, false, {'-- foo', '-- bar'}) + api.nvim_buf_clear_namespace(0, ns, 0, -1) + screen:expect([[ + ^-- foo | + -- bar | + {1:~ }|*7 + | + ]]) + assert_alive() + end) end) describe('decorations: virt_text', function() diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index b351afbae4..728f8ed3d0 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1311,7 +1311,7 @@ describe('builtin popupmenu', function() end end) - it('with preview-window above and tall and inverted', function() + it('with preview-window above, tall and inverted', function() feed(':ped<CR><c-w>8+') feed('iaa<cr>bb<cr>cc<cr>dd<cr>ee<cr>') feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>') @@ -1392,7 +1392,7 @@ describe('builtin popupmenu', function() end end) - it('with preview-window above and short and inverted', function() + it('with preview-window above, short and inverted', function() feed(':ped<CR><c-w>4+') feed('iaa<cr>bb<cr>cc<cr>dd<cr>ee<cr>') feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>') @@ -1468,7 +1468,7 @@ describe('builtin popupmenu', function() end end) - it('with preview-window below and inverted', function() + it('with preview-window below, inverted', function() feed(':ped<CR><c-w>4+<c-w>r') feed('iaa<cr>bb<cr>cc<cr>dd<cr>ee<cr>') feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>') @@ -1716,7 +1716,7 @@ describe('builtin popupmenu', function() return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}] endfunc set omnifunc=Omni_test - set completeopt+=longest + set completeopt-=popup completeopt+=longest,preview ]]) feed('Gi<C-X><C-O>') if multigrid then @@ -1850,7 +1850,7 @@ describe('builtin popupmenu', function() end end) - describe('floating window preview popup', function() + describe('completeopt=popup shows preview in floatwin', function() before_each(function() --row must > 10 screen:try_resize(40, 11) @@ -2264,7 +2264,7 @@ describe('builtin popupmenu', function() feed('<C-E><ESC>') end) - it('popup preview place in left', function() + it('popup preview placed to left', function() insert(('test'):rep(5)) feed('i<C-x><C-o>') if multigrid then @@ -7258,6 +7258,7 @@ describe('builtin popupmenu', function() endif return [#{word: "foo", info: "info"}, #{word: "bar"}, #{word: "你好"}] endfunc + set completeopt-=popup completeopt+=preview set omnifunc=Omni_test hi ComplMatchIns guifg=red ]]) @@ -7374,6 +7375,9 @@ describe('builtin popupmenu', function() endif return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}] endfunc + set completeopt-=popup completeopt+=preview + " Avoid unwanted results in case local workspace has a "tags" file. + set complete-=t set omnifunc=Omni_test hi Normal guibg=blue hi CursorLine guibg=green guifg=white @@ -7437,7 +7441,7 @@ describe('builtin popupmenu', function() feed('<Esc>') -- Does not highlight the compl leader - command('set cot+=menuone,noselect') + command('set completeopt+=menuone,noselect') feed('S<C-X><C-O>') local pum_start = [[ {10:^ }| @@ -7457,7 +7461,7 @@ describe('builtin popupmenu', function() ]]) feed('<C-E><ESC>') - command('set cot+=fuzzy') + command('set completeopt+=fuzzy') feed('S<C-X><C-O>') screen:expect(pum_start) feed('f<C-N>') @@ -7469,7 +7473,7 @@ describe('builtin popupmenu', function() ]]) feed('<C-E><Esc>') - command('set cot-=fuzzy') + command('set completeopt-=fuzzy') feed('Sf<C-N>') screen:expect([[ {10:f^ }| diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index 6c415b3dfa..2004606b63 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -500,7 +500,7 @@ describe('statuscolumn', function() {8:buffer 0 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {8:wrapped 1 5}aaaaaaaa | {8:virtual-2 5}virt_line | - {8:virtual-1 5}virt_line above | + {8:virtual-1 6}virt_line above | {8:buffer 0 6}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {8:wrapped 1 6}aaaaaaaa | {8:buffer 0 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| @@ -510,10 +510,26 @@ describe('statuscolumn', function() {8:wrapped 1 9}aaaaaaaa | | ]]) - -- Also test virt_lines at the end of buffer - exec_lua([[ - vim.api.nvim_buf_set_extmark(0, ns, 15, 0, { virt_lines = {{{"END", ""}}} }) + -- Also correct v:lnum with a partial redraw + exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_lines = {{{"virt_line", ""}}} })') + screen:expect([[ + {8:buffer 0 4}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8:wrapped 1 4}aaaaaaaa | + {8:buffer 0 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8:wrapped 1 5}aaaaaaaa | + {8:virtual-3 5}virt_line | + {8:virtual-2 5}virt_line | + {8:virtual-1 6}virt_line above | + {8:buffer 0 6}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8:wrapped 1 6}aaaaaaaa | + {8:buffer 0 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8:wrapped 1 7}aaaaaaaa | + {15:buffer 0 8}{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| + {8:buffer 0 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:@@@}| + | ]]) + -- Also test virt_lines at the end of buffer + exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 15, 0, { virt_lines = {{{"END", ""}}} })') feed('GkJzz') screen:expect([[ {8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| diff --git a/test/old/testdir/test_expand_func.vim b/test/old/testdir/test_expand_func.vim index 12750baf67..281e7c13e2 100644 --- a/test/old/testdir/test_expand_func.vim +++ b/test/old/testdir/test_expand_func.vim @@ -143,4 +143,11 @@ func Test_expand_wildignore() set wildignore& endfunc +" Passing a long string to expand with 'wildignorecase' should not crash Vim. +func Test_expand_long_str() + set wildignorecase + call expand('a'->repeat(99999)) + set wildignorecase& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 80fbb8a069..11a7c1b352 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -934,6 +934,9 @@ func CheckItems(checks) set noswapfile for [ft, names] in items(a:checks) for i in range(0, len(names) - 1) + if isdirectory(fnameescape(names[i])) + continue + endif new try exe 'edit ' .. fnameescape(names[i]) diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index c2062a355f..a08d0bd252 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2998,53 +2998,55 @@ function Test_completeopt_preinsert() endfunc set omnifunc=Omni_test set completeopt=menu,menuone,preinsert + func GetLine() + let g:line = getline('.') + let g:col = col('.') + endfunc new - call feedkeys("S\<C-X>\<C-O>f", 'tx') - call assert_equal("fobar", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + inoremap <buffer><F5> <C-R>=GetLine()<CR> + call feedkeys("S\<C-X>\<C-O>f\<F5>\<ESC>", 'tx') + call assert_equal("fobar", g:line) + call assert_equal(2, g:col) - call feedkeys("S\<C-X>\<C-O>foo", 'tx') - call assert_equal("foobar", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("S\<C-X>\<C-O>foo\<F5><ESC>", 'tx') + call assert_equal("foobar", g:line) call feedkeys("S\<C-X>\<C-O>foo\<BS>\<BS>\<BS>", 'tx') call assert_equal("", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') " delete a character and input new leader - call feedkeys("S\<C-X>\<C-O>foo\<BS>b", 'tx') - call assert_equal("fobar", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("S\<C-X>\<C-O>foo\<BS>b\<F5>\<ESC>", 'tx') + call assert_equal("fobar", g:line) + call assert_equal(4, g:col) " delete preinsert when prepare completion call feedkeys("S\<C-X>\<C-O>f\<Space>", 'tx') call assert_equal("f ", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') - call feedkeys("S\<C-X>\<C-O>你", 'tx') - call assert_equal("你的", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("S\<C-X>\<C-O>你\<F5>\<ESC>", 'tx') + call assert_equal("你的", g:line) + call assert_equal(4, g:col) - call feedkeys("S\<C-X>\<C-O>你好", 'tx') - call assert_equal("你好世界", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("S\<C-X>\<C-O>你好\<F5>\<ESC>", 'tx') + call assert_equal("你好世界", g:line) + call assert_equal(7, g:col) - call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>f", 'tx') - call assert_equal("hello fobar wo", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>f\<F5>\<ESC>", 'tx') + call assert_equal("hello fobar wo", g:line) + call assert_equal(9, g:col) - call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>f\<BS>", 'tx') - call assert_equal("hello wo", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>f\<BS>\<F5>\<ESC>", 'tx') + call assert_equal("hello wo", g:line) + call assert_equal(8, g:col) - call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>foo", 'tx') - call assert_equal("hello foobar wo", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>foo\<F5>\<ESC>", 'tx') + call assert_equal("hello foobar wo", g:line) + call assert_equal(11, g:col) - call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>foo\<BS>b", 'tx') - call assert_equal("hello fobar wo", getline('.')) - call feedkeys("\<C-E>\<ESC>", 'tx') + call feedkeys("Shello wo\<Left>\<Left>\<Left>\<C-X>\<C-O>foo\<BS>b\<F5>\<ESC>", 'tx') + call assert_equal("hello fobar wo", g:line) + call assert_equal(11, g:col) " confirm call feedkeys("S\<C-X>\<C-O>f\<C-Y>", 'tx') @@ -3056,9 +3058,9 @@ function Test_completeopt_preinsert() call assert_equal("fo", getline('.')) call assert_equal(2, col('.')) - call feedkeys("S hello hero\<CR>h\<C-X>\<C-N>", 'tx') - call assert_equal("hello", getline('.')) - call assert_equal(1, col('.')) + call feedkeys("S hello hero\<CR>h\<C-X>\<C-N>\<F5>\<ESC>", 'tx') + call assert_equal("hello", g:line) + call assert_equal(2, col('.')) call feedkeys("Sh\<C-X>\<C-N>\<C-Y>", 'tx') call assert_equal("hello", getline('.')) @@ -3078,17 +3080,17 @@ function Test_completeopt_preinsert() call assert_equal(1, col('.')) " whole line - call feedkeys("Shello hero\<CR>\<C-X>\<C-L>", 'tx') - call assert_equal("hello hero", getline('.')) - call assert_equal(1, col('.')) + call feedkeys("Shello hero\<CR>\<C-X>\<C-L>\<F5>\<ESC>", 'tx') + call assert_equal("hello hero", g:line) + call assert_equal(1, g:col) - call feedkeys("Shello hero\<CR>he\<C-X>\<C-L>", 'tx') - call assert_equal("hello hero", getline('.')) - call assert_equal(2, col('.')) + call feedkeys("Shello hero\<CR>he\<C-X>\<C-L>\<F5>\<ESC>", 'tx') + call assert_equal("hello hero", g:line) + call assert_equal(3, g:col) - call feedkeys("Shello hero\<CR>h\<C-X>\<C-N>er", 'tx') - call assert_equal("hero", getline('.')) - call assert_equal(3, col('.')) + call feedkeys("Shello hero\<CR>h\<C-X>\<C-N>er\<F5>\<ESC>", 'tx') + call assert_equal("hero", g:line) + call assert_equal(4, g:col) " can not work with fuzzy set cot+=fuzzy @@ -3098,13 +3100,13 @@ function Test_completeopt_preinsert() " test for fuzzy and noinsert set cot+=noinsert - call feedkeys("S\<C-X>\<C-O>fb", 'tx') - call assert_equal("fb", getline('.')) - call assert_equal(2, col('.')) + call feedkeys("S\<C-X>\<C-O>fb\<F5>\<ESC>", 'tx') + call assert_equal("fb", g:line) + call assert_equal(3, g:col) - call feedkeys("S\<C-X>\<C-O>你", 'tx') - call assert_equal("你", getline('.')) - call assert_equal(1, col('.')) + call feedkeys("S\<C-X>\<C-O>你\<F5>\<ESC>", 'tx') + call assert_equal("你", g:line) + call assert_equal(4, g:col) call feedkeys("S\<C-X>\<C-O>fb\<C-Y>", 'tx') call assert_equal("fobar", getline('.')) @@ -3117,9 +3119,15 @@ function Test_completeopt_preinsert() call assert_equal(7, col('.')) set cot=preinsert,menuone - call feedkeys("Sfoo1 foo2\<CR>f\<C-X>\<C-N>", 'tx') - call assert_equal("foo1", getline('.')) - call assert_equal(1, col('.')) + call feedkeys("Sfoo1 foo2\<CR>f\<C-X>\<C-N>\<F5>\<ESC>", 'tx') + call assert_equal("foo1", g:line) + call assert_equal(2, g:col) + + inoremap <buffer> <f3> <cmd>call complete(4, [{'word': "fobar"}, {'word': "foobar"}])<CR> + call feedkeys("Swp.\<F3>\<F5>\<BS>\<ESC>", 'tx') + call assert_equal("wp.fobar", g:line) + call assert_equal(4, g:col) + call assert_equal("wp.", getline('.')) bw! set cot& diff --git a/test/old/testdir/test_plugin_matchparen.vim b/test/old/testdir/test_plugin_matchparen.vim index 0739906a42..6739abcfde 100644 --- a/test/old/testdir/test_plugin_matchparen.vim +++ b/test/old/testdir/test_plugin_matchparen.vim @@ -168,6 +168,12 @@ func Test_matchparen_ignore_sh_case() let buf = RunVimInTerminal('-S '.filename, #{rows: 10}) call VerifyScreenDump(buf, 'Test_matchparen_sh_case_1', {}) + " Send keys one by one so that CursorMoved is triggered. + for c in 'A foobar' + call term_sendkeys(buf, c) + call term_wait(buf) + endfor + call VerifyScreenDump(buf, 'Test_matchparen_sh_case_2', {}) call StopVimInTerminal(buf) endfunc diff --git a/test/old/testdir/test_sha256.vim b/test/old/testdir/test_sha256.vim index f6f430b04e..b0941c60e3 100644 --- a/test/old/testdir/test_sha256.vim +++ b/test/old/testdir/test_sha256.vim @@ -1,7 +1,7 @@ " Tests for the sha256() function. source check.vim -CheckFeature cryptv +" CheckFeature cryptv CheckFunction sha256 function Test_sha256() diff --git a/test/old/testdir/test_tabline.vim b/test/old/testdir/test_tabline.vim index d423f8a22c..4de6f845cb 100644 --- a/test/old/testdir/test_tabline.vim +++ b/test/old/testdir/test_tabline.vim @@ -210,6 +210,9 @@ endfunc " Test 'tabline' with truncated double-width label at the start. func Test_tabline_truncated_double_width() + let save_TabLine = nvim_get_hl(0, #{name: 'TabLine'}) + " Nvim: avoid combining TabLine with TabLineFill in custom tabline + hi TabLine cterm=underline,nocombine gui=underline,nocombine tabnew redraw call assert_match('X$', Screenline(1)) @@ -226,6 +229,7 @@ func Test_tabline_truncated_double_width() bw! set tabline= + call nvim_set_hl(0, 'TabLine', save_TabLine) endfunc " vim: shiftwidth=2 sts=2 expandtab |