Compare commits

...

6 Commits

Author SHA1 Message Date
Justin M. Keyes
b63bf2ec39
Merge f40f4c7d8a into 7121983c45 2024-12-18 14:40:43 +00:00
Lewis Russell
7121983c45 refactor(man.lua): various changes
- Replace all uses of vim.regex with simpler Lua patterns.
- Replace all uses of vim.fn.substitute with string.gsub.
- Rework error handling so expected errors are passed back via a return.
  - These get routed up an passed to `vim.notify()`
  - Any other errors will cause a stack trace.
- Reworked the module initialization of `localfile_arg`
- Updated all type annotations.
- Refactored CLI completion by introduction a parse_cmdline()
  function.
- Simplified `show_toc()`
- Refactor highlighting
- Inline some functions
- Fix completion on MacOS 13 and earlier.
  - Prefer `manpath -q` over `man -w`
- Make completion more efficient by avoiding vim.fn.sort and vim.fn.uniq
  - Reimplement using a single loop
2024-12-18 14:40:36 +00:00
phanium
888a803755
fix(lsp): vim.lsp.start fails if existing client has no workspace_folders #31608
Problem:
regression since https://github.com/neovim/neovim/pull/31340

`nvim -l repro.lua`:
```lua
vim.lsp.start { cmd = { 'lua-language-server' }, name = 'lua_ls' }
vim.lsp.start { cmd = { 'lua-language-server' }, name = 'lua_ls', root_dir = 'foo' }

-- swapped case will be ok:
-- vim.lsp.start { cmd = { 'lua-language-server' }, name = 'lua_ls', root_dir = 'foo' }
-- vim.lsp.start { cmd = { 'lua-language-server' }, name = 'lua_ls' }
```

Failure:
```
E5113: Error while calling lua chunk: /…/lua/vim/lsp.lua:214: bad argument #1 to
'ipairs' (table expected, got nil)
stack traceback:
        [C]: in function 'ipairs'
        /…/lua/vim/lsp.lua:214: in function 'reuse_client'
        /…/lua/vim/lsp.lua:629: in function 'start'
        repro.lua:34: in main chunk
```
2024-12-18 06:37:12 -08:00
Peter Lithammer
07d5dc8938
feat(lsp): show server version in :checkhealth #31611
Problem:
Language server version information missing from `:checkhealth vim.lsp`.

Solution:
Store `InitializeResult.serverInfo.version` from the `initialize`
response and display for each client in `:checkhealth vim.lsp`.
2024-12-18 06:31:25 -08:00
Justin M. Keyes
f9eb68f340
fix(coverity): error handling CHECKED_RETURN #31618
CID 516406:  Error handling issues  (CHECKED_RETURN)
    /src/nvim/api/vimscript.c: 284 in nvim_call_dict_function()
    278       Object rv = OBJECT_INIT;
    279
    280       typval_T rettv;
    281       bool mustfree = false;
    282       switch (dict.type) {
    283       case kObjectTypeString:
    >>>     CID 516406:  Error handling issues  (CHECKED_RETURN)
    >>>     Calling "eval0" without checking return value (as is done elsewhere 10 out of 12 times).
    284         TRY_WRAP(err, {
    285           eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE);
    286           clear_evalarg(&EVALARG_EVALUATE, NULL);
    287         });
    288         if (ERROR_SET(err)) {
    289           return rv;
2024-12-18 06:05:37 -08:00
Justin M. Keyes
f40f4c7d8a docs: misc
todo

- https://github.com/neovim/neovim/pull/30085#discussion_r1741869280
2024-12-17 16:12:32 +01:00
18 changed files with 454 additions and 442 deletions

View File

@ -17,10 +17,14 @@ TUI and GUI (assuming the UI supports the given feature). See |TUI| for notes
specific to the terminal UI. Help tags with the "gui-" prefix refer to UI specific to the terminal UI. Help tags with the "gui-" prefix refer to UI
features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|. features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
Nvim provides a default, builtin UI (the |TUI|), but there are many other ==============================================================================
(third-party) GUIs that you can use instead: Third-party GUIs *third-party-guis* *vscode*
Nvim provides a builtin "terminal UI" (|TUI|), but also works with many
(third-party) GUIs which may provide a fresh look or extra features on top of
Nvim. For example, "vscode-neovim" essentally allows you to use VSCode as
a Nvim GUI.
*vscode*
- vscode-neovim (Nvim in VSCode!) https://github.com/vscode-neovim/vscode-neovim - vscode-neovim (Nvim in VSCode!) https://github.com/vscode-neovim/vscode-neovim
- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim - Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
- Neovide https://neovide.dev/ - Neovide https://neovide.dev/

View File

@ -32,8 +32,9 @@ and |user-manual|.
Resources *resources* Resources *resources*
*internet* *www* *distribution* *internet* *www* *distribution*
- Nvim home page: https://neovim.io/ Nvim home page:
- Vim FAQ: https://vimhelp.org/vim_faq.txt.html
https://neovim.io/
*book* *book*
There are many resources to learn Vi, Vim, and Nvim. We recommend: There are many resources to learn Vi, Vim, and Nvim. We recommend:
@ -48,6 +49,7 @@ There are many resources to learn Vi, Vim, and Nvim. We recommend:
- For more information try one of these: - For more information try one of these:
- https://iccf-holland.org/click5.html - https://iccf-holland.org/click5.html
- https://www.vim.org/iccf/click5.html - https://www.vim.org/iccf/click5.html
- Vim FAQ: https://vimhelp.org/vim_faq.txt.html
*bugs* *bug-report* *feature-request* *bugs* *bug-report* *feature-request*
Report bugs and request features here: https://github.com/neovim/neovim/issues Report bugs and request features here: https://github.com/neovim/neovim/issues
@ -67,18 +69,24 @@ To install or upgrade Nvim, you can...
- Build from source: - Build from source:
https://github.com/neovim/neovim/blob/master/INSTALL.md#install-from-source https://github.com/neovim/neovim/blob/master/INSTALL.md#install-from-source
*uninstall* ------------------------------------------------------------------------------
Un-installing Nvim *uninstall*
To uninstall Nvim: To uninstall Nvim:
- If you downloaded a pre-built archive or built Nvim from source (e.g. `make - If you downloaded a pre-built archive or built Nvim from source (e.g.
install`), just delete its files, typically located in: > `make install`), just delete its files, typically located in: >
/usr/local/bin/nvim /usr/local/bin/nvim
/usr/local/share/nvim /usr/local/share/nvim
<
- To find where Nvim is installed, run these commands: >
:echo v:progpath
:echo $VIMRUNTIME
< <
- If you installed via package manager, read your package manager's - If you installed via package manager, read your package manager's
documentation. Common examples: documentation. Common examples:
- APT (Debian, Ubuntu, …): `apt-get remove neovim` - APT (Debian, Ubuntu, …): `apt-get remove neovim`
- Homebrew (macOS): `brew install neovim` - Homebrew (macOS): `brew uninstall neovim`
- Scoop (Windows): `scoop install neovim` - Scoop (Windows): `scoop uninstall neovim`
============================================================================== ==============================================================================
Sponsor Vim/Nvim development *sponsor* *register* Sponsor Vim/Nvim development *sponsor* *register*

View File

@ -348,22 +348,17 @@ Each response handler has this signature: >
*lsp-handler-resolution* *lsp-handler-resolution*
Handlers can be set by (in increasing priority): Handlers can be set by (in increasing priority):
- Setting a field in vim.lsp.handlers. *vim.lsp.handlers* *vim.lsp.handlers*
`vim.lsp.handlers` is a global table that contains the default mapping of - Setting a field in `vim.lsp.handlers`. The `vim.lsp.handlers` global table
|lsp-method| names to lsp-handlers. contains the default mappings of |lsp-method| names to handlers. (Note: only
for server-to-client requests/notifications, not client-to-server.)
Example: >lua Example: >lua
vim.lsp.handlers['textDocument/publishDiagnostics'] = my_custom_diagnostics_handler vim.lsp.handlers['textDocument/publishDiagnostics'] = my_custom_diagnostics_handler
< <
Note: this only applies for requests/notifications made by the - Passing a {handlers} parameter to |vim.lsp.start()|. This sets the default
server to the client. |lsp-handler| for a specific server. (Note: only for server-to-client
requests/notifications, not client-to-server.)
- The {handlers} parameter of |vim.lsp.start()|. This sets the default
|lsp-handler| for a specific server.
Example: >lua Example: >lua
vim.lsp.start { vim.lsp.start {
..., -- Other configuration omitted. ..., -- Other configuration omitted.
handlers = { handlers = {
@ -371,14 +366,9 @@ Handlers can be set by (in increasing priority):
}, },
} }
< <
Note: this only applies for requests/notifications made by the - Passing a {handler} parameter to |vim.lsp.buf_request_all()|. This sets the
server to the client. |lsp-handler| ONLY for the given request(s).
- The {handler} parameter of |vim.lsp.buf_request_all()|. This sets
the |lsp-handler| ONLY for the given request(s).
Example: >lua Example: >lua
vim.lsp.buf_request_all( vim.lsp.buf_request_all(
0, 0,
'textDocument/publishDiagnostics', 'textDocument/publishDiagnostics',
@ -1126,6 +1116,9 @@ Lua module: vim.lsp.client *lsp-client*
• {server_capabilities} (`lsp.ServerCapabilities?`) Response from the • {server_capabilities} (`lsp.ServerCapabilities?`) Response from the
server sent on `initialize` describing the server sent on `initialize` describing the
server's capabilities. server's capabilities.
• {server_info} (`lsp.ServerInfo?`) Response from the server
sent on `initialize` describing information
about the server.
• {progress} (`vim.lsp.Client.Progress`) A ring buffer • {progress} (`vim.lsp.Client.Progress`) A ring buffer
(|vim.ringbuf()|) containing progress messages (|vim.ringbuf()|) containing progress messages
sent by the server. See sent by the server. See

View File

@ -817,8 +817,8 @@ vim.json.encode({obj}, {opts}) *vim.json.encode()*
Parameters: ~ Parameters: ~
• {obj} (`any`) • {obj} (`any`)
• {opts} (`table<string,any>?`) Options table with keys: • {opts} (`table<string,any>?`) Options table with keys:
• escape_slash: (boolean) (default false) When true, escapes • escape_slash: (boolean) (default false) Escape slash
`/` character in JSON strings characters "/" in string values.
Return: ~ Return: ~
(`string`) (`string`)

View File

@ -12,7 +12,7 @@ manual.
Type |gO| to see the table of contents. Type |gO| to see the table of contents.
============================================================================== ==============================================================================
1. Key mapping *keybind* *key-mapping* *mapping* *macro* 1. Key mapping *keybind* *key-mapping* *mapping*
Key mapping is used to change the meaning of typed keys. The most common use Key mapping is used to change the meaning of typed keys. The most common use
is to define a sequence of commands for a function key. Example: > is to define a sequence of commands for a function key. Example: >

View File

@ -61,7 +61,6 @@ DEFAULTS
current buffer, respectively. current buffer, respectively.
• 'number', 'relativenumber', 'signcolumn', and 'foldcolumn' are disabled in • 'number', 'relativenumber', 'signcolumn', and 'foldcolumn' are disabled in
|terminal| buffers. See |terminal-config| for an example of changing these defaults. |terminal| buffers. See |terminal-config| for an example of changing these defaults.
• |vim.json.encode()| no longer escapes the forward slash symbol by default
DIAGNOSTICS DIAGNOSTICS
@ -115,6 +114,7 @@ LSP
• |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()| • |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()|
and |vim.lsp.util.make_given_range_params()| now require the `position_encoding` and |vim.lsp.util.make_given_range_params()| now require the `position_encoding`
parameter. parameter.
• `:checkhealth vim.lsp` displays the server version (if available).
LUA LUA
@ -123,6 +123,7 @@ LUA
• Command-line completions for: `vim.g`, `vim.t`, `vim.w`, `vim.b`, `vim.v`, • Command-line completions for: `vim.g`, `vim.t`, `vim.w`, `vim.b`, `vim.v`,
`vim.o`, `vim.wo`, `vim.bo`, `vim.opt`, `vim.opt_local`, `vim.opt_global`, `vim.o`, `vim.wo`, `vim.bo`, `vim.opt`, `vim.opt_local`, `vim.opt_global`,
and `vim.fn`. and `vim.fn`.
• |vim.json.encode()| no longer escapes forward slashes "/" by default
OPTIONS OPTIONS
@ -176,7 +177,6 @@ The following new features were added.
API API
• |nvim__ns_set()| can set properties for a namespace • |nvim__ns_set()| can set properties for a namespace
• |vim.json.encode()| has an option to enable forward slash escaping
DEFAULTS DEFAULTS
@ -254,6 +254,7 @@ LUA
is more performant and easier to read. is more performant and easier to read.
• |vim.str_byteindex()| and |vim.str_utfindex()| gained overload signatures • |vim.str_byteindex()| and |vim.str_utfindex()| gained overload signatures
supporting two new parameters, `encoding` and `strict_indexing`. supporting two new parameters, `encoding` and `strict_indexing`.
• |vim.json.encode()| has an option to enable forward slash escaping
OPTIONS OPTIONS
@ -265,6 +266,8 @@ PERFORMANCE
• Significantly reduced redraw time for long lines with treesitter • Significantly reduced redraw time for long lines with treesitter
highlighting. highlighting.
• LSP diagnostics and inlay hints are de-duplicated (new requests cancel
inflight requests). This greatly improves performance with slow LSP servers.
PLUGINS PLUGINS

View File

@ -111,7 +111,7 @@ To abort this type CTRL-C twice.
============================================================================== ==============================================================================
Complex repeats *complex-repeat* Complex repeats *complex-repeat*
*q* *recording* *q* *recording* *macro*
q{0-9a-zA-Z"} Record typed characters into register {0-9a-zA-Z"} q{0-9a-zA-Z"} Record typed characters into register {0-9a-zA-Z"}
(uppercase to append). The 'q' command is disabled (uppercase to append). The 'q' command is disabled
while executing a register, and it doesn't work inside while executing a register, and it doesn't work inside

View File

@ -24,7 +24,7 @@ User configuration and data files are found in standard |base-directories|
session information. |shada| session information. |shada|
============================================================================== ==============================================================================
Defaults *nvim-defaults* Defaults *defaults* *nvim-defaults*
- Filetype detection is enabled by default. This can be disabled by adding - Filetype detection is enabled by default. This can be disabled by adding
":filetype off" to |init.vim|. ":filetype off" to |init.vim|.
@ -291,7 +291,8 @@ Commands:
User commands can support |:command-preview| to show results as you type User commands can support |:command-preview| to show results as you type
- |:write| with "++p" flag creates parent directories. - |:write| with "++p" flag creates parent directories.
Events: Events (autocommands):
- Fixed inconsistent behavior in execution of nested autocommands #23368
- |RecordingEnter| - |RecordingEnter|
- |RecordingLeave| - |RecordingLeave|
- |SearchWrapped| - |SearchWrapped|
@ -299,6 +300,8 @@ Events:
- |TabNewEntered| - |TabNewEntered|
- |TermClose| - |TermClose|
- |TermOpen| - |TermOpen|
- |TermResponse| is fired for any OSC sequence received from the terminal,
instead of the Primary Device Attributes response. |v:termresponse|
- |UIEnter| - |UIEnter|
- |UILeave| - |UILeave|
@ -366,7 +369,7 @@ Options:
- 'shortmess' - 'shortmess'
- "F" flag does not affect output from autocommands. - "F" flag does not affect output from autocommands.
- "q" flag fully hides macro recording message. - "q" flag fully hides macro recording message.
- 'signcolumn' supports up to 9 dynamic/fixed columns - 'signcolumn' can show multiple signs (dynamic or fixed columns)
- 'statuscolumn' full control of columns using 'statusline' format - 'statuscolumn' full control of columns using 'statusline' format
- 'tabline' middle-click on tabpage label closes tabpage, - 'tabline' middle-click on tabpage label closes tabpage,
and %@Func@foo%X can call any function on mouse-click and %@Func@foo%X can call any function on mouse-click
@ -375,6 +378,10 @@ Options:
- 'winblend' pseudo-transparency in floating windows |api-floatwin| - 'winblend' pseudo-transparency in floating windows |api-floatwin|
- 'winhighlight' window-local highlights - 'winhighlight' window-local highlights
Performance:
- Signs are implemented using Nvim's internal "marktree" (btree) structure.
- Folds are not updated during insert-mode.
Providers: Providers:
- If a Python interpreter is available on your `$PATH`, |:python| and - If a Python interpreter is available on your `$PATH`, |:python| and
|:python3| are always available. See |provider-python|. |:python3| are always available. See |provider-python|.
@ -392,6 +399,7 @@ Shell:
- |system()| does not support writing/reading "backgrounded" commands. |E5677| - |system()| does not support writing/reading "backgrounded" commands. |E5677|
Signs: Signs:
- 'signcolumn' can show multiple signs.
- Signs are removed if the associated line is deleted. - Signs are removed if the associated line is deleted.
- Signs placed twice with the same identifier in the same group are moved. - Signs placed twice with the same identifier in the same group are moved.
@ -584,9 +592,6 @@ Mappings:
Motion: Motion:
- The |jumplist| avoids useless/phantom jumps. - The |jumplist| avoids useless/phantom jumps.
Performance:
- Folds are not updated during insert-mode.
Syntax highlighting: Syntax highlighting:
- syncolor.vim has been removed. Nvim now sets up default highlighting groups - syncolor.vim has been removed. Nvim now sets up default highlighting groups
automatically for both light and dark backgrounds, regardless of whether or automatically for both light and dark backgrounds, regardless of whether or
@ -611,12 +616,6 @@ Working directory (Vim implemented some of these after Nvim):
- `getcwd(-1)` is equivalent to `getcwd(-1, 0)` instead of returning the global - `getcwd(-1)` is equivalent to `getcwd(-1, 0)` instead of returning the global
working directory. Use `getcwd(-1, -1)` to get the global working directory. working directory. Use `getcwd(-1, -1)` to get the global working directory.
Autocommands:
- Fixed inconsistent behavior in execution of nested autocommands:
https://github.com/neovim/neovim/issues/23368
- |TermResponse| is fired for any OSC sequence received from the terminal,
instead of the Primary Device Attributes response. |v:termresponse|
Options: Options:
- 'titlestring' uses printf-style '%' items (see: 'statusline') to implement - 'titlestring' uses printf-style '%' items (see: 'statusline') to implement
the default behaviour. The implementation is equivalent to setting the default behaviour. The implementation is equivalent to setting

File diff suppressed because it is too large Load Diff

View File

@ -26,9 +26,9 @@ vim.json = {}
---@param str string Stringified JSON data. ---@param str string Stringified JSON data.
---@param opts? table<string,any> Options table with keys: ---@param opts? table<string,any> Options table with keys:
--- - luanil: (table) Table with keys: --- - luanil: (table) Table with keys:
--- * object: (boolean) When true, converts `null` in JSON objects --- - object: (boolean) When true, converts `null` in JSON objects
--- to Lua `nil` instead of |vim.NIL|. --- to Lua `nil` instead of |vim.NIL|.
--- * array: (boolean) When true, converts `null` in JSON arrays --- - array: (boolean) When true, converts `null` in JSON arrays
--- to Lua `nil` instead of |vim.NIL|. --- to Lua `nil` instead of |vim.NIL|.
---@return any ---@return any
function vim.json.decode(str, opts) end function vim.json.decode(str, opts) end
@ -36,7 +36,7 @@ function vim.json.decode(str, opts) end
--- Encodes (or "packs") Lua object {obj} as JSON in a Lua string. --- Encodes (or "packs") Lua object {obj} as JSON in a Lua string.
---@param obj any ---@param obj any
---@param opts? table<string,any> Options table with keys: ---@param opts? table<string,any> Options table with keys:
--- - escape_slash: (boolean) (default false) When true, escapes `/` --- - escape_slash: (boolean) (default false) Escape slash
--- character in JSON strings --- characters "/" in string values.
---@return string ---@return string
function vim.json.encode(obj, opts) end function vim.json.encode(obj, opts) end

View File

@ -211,7 +211,7 @@ local function reuse_client_default(client, config)
for _, config_folder in ipairs(config_folders) do for _, config_folder in ipairs(config_folders) do
local found = false local found = false
for _, client_folder in ipairs(client.workspace_folders) do for _, client_folder in ipairs(client.workspace_folders or {}) do
if config_folder.uri == client_folder.uri then if config_folder.uri == client_folder.uri then
found = true found = true
break break

View File

@ -174,6 +174,10 @@ local validate = vim.validate
--- capabilities. --- capabilities.
--- @field server_capabilities lsp.ServerCapabilities? --- @field server_capabilities lsp.ServerCapabilities?
--- ---
--- Response from the server sent on `initialize` describing information about
--- the server.
--- @field server_info lsp.ServerInfo?
---
--- A ring buffer (|vim.ringbuf()|) containing progress messages --- A ring buffer (|vim.ringbuf()|) containing progress messages
--- sent by the server. --- sent by the server.
--- @field progress vim.lsp.Client.Progress --- @field progress vim.lsp.Client.Progress
@ -556,6 +560,8 @@ function Client:initialize()
self.offset_encoding = self.server_capabilities.positionEncoding self.offset_encoding = self.server_capabilities.positionEncoding
end end
self.server_info = result.serverInfo
if next(self.settings) then if next(self.settings) then
self:notify(ms.workspace_didChangeConfiguration, { settings = self.settings }) self:notify(ms.workspace_didChangeConfiguration, { settings = self.settings })
end end

View File

@ -40,6 +40,8 @@ local function check_active_clients()
local clients = vim.lsp.get_clients() local clients = vim.lsp.get_clients()
if next(clients) then if next(clients) then
for _, client in pairs(clients) do for _, client in pairs(clients) do
local server_version = vim.tbl_get(client, 'server_info', 'version')
or '? (no serverInfo.version response)'
local cmd ---@type string local cmd ---@type string
local ccmd = client.config.cmd local ccmd = client.config.cmd
if type(ccmd) == 'table' then if type(ccmd) == 'table' then
@ -62,6 +64,7 @@ local function check_active_clients()
end end
report_info(table.concat({ report_info(table.concat({
string.format('%s (id: %d)', client.name, client.id), string.format('%s (id: %d)', client.name, client.id),
string.format('- Version: %s', server_version),
dirs_info, dirs_info,
string.format('- Command: %s', cmd), string.format('- Command: %s', cmd),
string.format('- Settings: %s', vim.inspect(client.settings, { newline = '\n ' })), string.format('- Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),

View File

@ -8,9 +8,9 @@ vim.api.nvim_create_user_command('Man', function(params)
if params.bang then if params.bang then
man.init_pager() man.init_pager()
else else
local ok, err = pcall(man.open_page, params.count, params.smods, params.fargs) local err = man.open_page(params.count, params.smods, params.fargs)
if not ok then if err then
vim.notify(man.errormsg or err, vim.log.levels.ERROR) vim.notify('man.lua: ' .. err, vim.log.levels.ERROR)
end end
end end
end, { end, {
@ -31,6 +31,9 @@ vim.api.nvim_create_autocmd('BufReadCmd', {
pattern = 'man://*', pattern = 'man://*',
nested = true, nested = true,
callback = function(params) callback = function(params)
require('man').read_page(vim.fn.matchstr(params.match, 'man://\\zs.*')) local err = require('man').read_page(assert(params.match:match('man://(.*)')))
if err then
vim.notify('man.lua: ' .. err, vim.log.levels.ERROR)
end
end, end,
}) })

View File

@ -229,10 +229,9 @@ static Object _call_function(String fn, Array args, dict_T *self, Arena *arena,
funcexe.fe_selfdict = self; funcexe.fe_selfdict = self;
TRY_WRAP(err, { TRY_WRAP(err, {
// call_func() retval is deceptive, ignore it. Instead we set `msg_list` // call_func() retval is deceptive, ignore it. Instead TRY_WRAP sets `msg_list` to capture
// (see above) to capture abort-causing non-exception errors. // abort-causing non-exception errors.
call_func(fn.data, (int)fn.size, &rettv, (int)args.size, (void)call_func(fn.data, (int)fn.size, &rettv, (int)args.size, vim_args, &funcexe);
vim_args, &funcexe);
}); });
if (!ERROR_SET(err)) { if (!ERROR_SET(err)) {
@ -280,18 +279,23 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Arena *arena,
typval_T rettv; typval_T rettv;
bool mustfree = false; bool mustfree = false;
switch (dict.type) { switch (dict.type) {
case kObjectTypeString: case kObjectTypeString: {
int eval_ret;
TRY_WRAP(err, { TRY_WRAP(err, {
eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE); eval_ret = eval0(dict.data.string.data, &rettv, NULL, &EVALARG_EVALUATE);
clear_evalarg(&EVALARG_EVALUATE, NULL); clear_evalarg(&EVALARG_EVALUATE, NULL);
}); });
if (ERROR_SET(err)) { if (ERROR_SET(err)) {
return rv; return rv;
} }
if (eval_ret != OK) {
abort(); // Should not happen.
}
// Evaluation of the string arg created a new dict or increased the // Evaluation of the string arg created a new dict or increased the
// refcount of a dict. Not necessary for a RPC dict. // refcount of a dict. Not necessary for a RPC dict.
mustfree = true; mustfree = true;
break; break;
}
case kObjectTypeDict: case kObjectTypeDict:
object_to_vim(dict, &rettv, err); object_to_vim(dict, &rettv, err);
break; break;

View File

@ -152,7 +152,7 @@ describe('vim.json.encode()', function()
clear() clear()
end) end)
it('dumps strings with & without escaped slash', function() it('escape_slash', function()
-- With slash -- With slash
eq('"Test\\/"', exec_lua([[return vim.json.encode('Test/', { escape_slash = true })]])) eq('"Test\\/"', exec_lua([[return vim.json.encode('Test/', { escape_slash = true })]]))
eq( eq(

View File

@ -1854,6 +1854,20 @@ describe('LSP', function()
end, end,
} }
end) end)
it('vim.lsp.start when existing client has no workspace_folders', function()
exec_lua(create_server_definition)
eq(
{ 2, 'foo', 'foo' },
exec_lua(function()
local server = _G._create_server()
vim.lsp.start { cmd = server.cmd, name = 'foo' }
vim.lsp.start { cmd = server.cmd, name = 'foo', root_dir = 'bar' }
local foos = vim.lsp.get_clients()
return { #foos, foos[1].name, foos[2].name }
end)
)
end)
end) end)
describe('parsing tests', function() describe('parsing tests', function()

View File

@ -21,13 +21,12 @@ local function get_search_history(name)
local man = require('man') local man = require('man')
local res = {} local res = {}
--- @diagnostic disable-next-line:duplicate-set-field --- @diagnostic disable-next-line:duplicate-set-field
man.find_path = function(sect, name0) man._find_path = function(name0, sect)
table.insert(res, { sect, name0 }) table.insert(res, { sect, name0 })
return nil return nil
end end
local ok, rv = pcall(man.open_page, -1, { tab = 0 }, args) local err = man.open_page(-1, { tab = 0 }, args)
assert(not ok) assert(err and err:match('no manual entry'))
assert(rv and rv:match('no manual entry'))
return res return res
end) end)
end end
@ -225,7 +224,7 @@ describe(':Man', function()
matches('^/.+', actual_file) matches('^/.+', actual_file)
local args = { nvim_prog, '--headless', '+:Man ' .. actual_file, '+q' } local args = { nvim_prog, '--headless', '+:Man ' .. actual_file, '+q' }
matches( matches(
('Error detected while processing command line:\r\n' .. 'man.lua: "no manual entry for %s"'):format( ('Error detected while processing command line:\r\n' .. 'man.lua: no manual entry for %s'):format(
pesc(actual_file) pesc(actual_file)
), ),
fn.system(args, { '' }) fn.system(args, { '' })
@ -235,8 +234,8 @@ describe(':Man', function()
it('tries variants with spaces, underscores #22503', function() it('tries variants with spaces, underscores #22503', function()
eq({ eq({
{ '', 'NAME WITH SPACES' }, { vim.NIL, 'NAME WITH SPACES' },
{ '', 'NAME_WITH_SPACES' }, { vim.NIL, 'NAME_WITH_SPACES' },
}, get_search_history('NAME WITH SPACES')) }, get_search_history('NAME WITH SPACES'))
eq({ eq({
{ '3', 'some other man' }, { '3', 'some other man' },
@ -255,8 +254,8 @@ describe(':Man', function()
{ 'n', 'some_other_man' }, { 'n', 'some_other_man' },
}, get_search_history('n some other man')) }, get_search_history('n some other man'))
eq({ eq({
{ '', '123some other man' }, { vim.NIL, '123some other man' },
{ '', '123some_other_man' }, { vim.NIL, '123some_other_man' },
}, get_search_history('123some other man')) }, get_search_history('123some other man'))
eq({ eq({
{ '1', 'other_man' }, { '1', 'other_man' },
@ -265,11 +264,10 @@ describe(':Man', function()
end) end)
it('can complete', function() it('can complete', function()
t.skip(t.is_os('mac') and t.is_arch('x86_64'), 'not supported on intel mac')
eq( eq(
true, true,
exec_lua(function() exec_lua(function()
return #require('man').man_complete('f', 'Man g') > 0 return #require('man').man_complete('f', 'Man f') > 0
end) end)
) )
end) end)