aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/doc/api.txt4
-rw-r--r--runtime/doc/autocmd.txt8
-rw-r--r--runtime/doc/builtin.txt25
-rw-r--r--runtime/doc/eval.txt23
-rw-r--r--runtime/doc/lsp.txt235
-rw-r--r--runtime/doc/lua-guide.txt2
-rw-r--r--runtime/doc/lua.txt19
-rw-r--r--runtime/doc/map.txt8
-rw-r--r--runtime/doc/news.txt14
-rw-r--r--runtime/doc/options.txt49
-rw-r--r--runtime/doc/repeat.txt4
-rw-r--r--runtime/doc/starting.txt8
-rw-r--r--runtime/doc/syntax.txt4
-rw-r--r--runtime/doc/treesitter.txt18
-rw-r--r--runtime/doc/ui.txt1
-rw-r--r--runtime/doc/usr_41.txt1
-rw-r--r--runtime/lua/man.lua20
-rw-r--r--runtime/lua/nvim/health.lua474
-rw-r--r--runtime/lua/vim/_init_packages.lua9
-rw-r--r--runtime/lua/vim/filetype.lua7
-rw-r--r--runtime/lua/vim/fs.lua2
-rw-r--r--runtime/lua/vim/health.lua15
-rw-r--r--runtime/lua/vim/lsp.lua231
-rw-r--r--runtime/lua/vim/lsp/buf.lua23
-rw-r--r--runtime/lua/vim/lsp/handlers.lua7
-rw-r--r--runtime/lua/vim/lsp/protocol.lua11
-rw-r--r--runtime/lua/vim/shared.lua29
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua6
-rw-r--r--runtime/lua/vim/treesitter/language.lua12
-rw-r--r--runtime/lua/vim/treesitter/query.lua10
-rw-r--r--runtime/nvim.appdata.xml3
-rw-r--r--runtime/tutor/tutor.tutor.json4
32 files changed, 745 insertions, 541 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index d74657dc8e..95a929b808 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -1133,7 +1133,7 @@ nvim_list_uis() *nvim_list_uis()*
• "width" Requested width of the UI
• "rgb" true if the UI uses RGB colors (false implies |cterm-colors|)
• "ext_..." Requested UI extensions, see |ui-option|
- • "chan" Channel id of remote UI or 0 for TUI
+ • "chan" |channel-id| of remote UI
nvim_list_wins() *nvim_list_wins()*
Gets the current list of window handles.
@@ -3281,7 +3281,7 @@ nvim_create_autocmd({event}, {*opts}) *nvim_create_autocmd()*
• match: (string) expanded value of |<amatch>|
• buf: (number) expanded value of |<abuf>|
• file: (string) expanded value of |<afile>|
- • data: (any) arbitrary data passed to
+ • data: (any) arbitrary data passed from
|nvim_exec_autocmds()|
• command (string) optional: Vim command to execute on event.
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index a39407aeca..8cc4754880 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -681,16 +681,12 @@ FuncUndefined When a user function is used but it isn't
UIEnter After a UI connects via |nvim_ui_attach()|, or
after builtin TUI is started, after |VimEnter|.
Sets these |v:event| keys:
- chan: 0 for builtin TUI
- 1 for |--embed|
- |channel-id| of the UI otherwise
+ chan: |channel-id| of the UI
*UILeave*
UILeave After a UI disconnects from Nvim, or after
builtin TUI is stopped, after |VimLeave|.
Sets these |v:event| keys:
- chan: 0 for builtin TUI
- 1 for |--embed|
- |channel-id| of the UI otherwise
+ chan: |channel-id| of the UI
*InsertChange*
InsertChange When typing <Insert> while in Insert or
Replace mode. The |v:insertmode| variable
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index cc1d1b568d..c8f5570bae 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -173,6 +173,7 @@ getbufline({buf}, {lnum} [, {end}])
getbufoneline({buf}, {lnum}) String line {lnum} of buffer {buf}
getbufvar({buf}, {varname} [, {def}])
any variable {varname} in buffer {buf}
+getcellwidths() List get character cell width overrides
getchangelist([{buf}]) List list of change list items
getchar([expr]) Number or String
get one character from the user
@@ -2745,6 +2746,13 @@ getbufvar({buf}, {varname} [, {def}]) *getbufvar()*
< Can also be used as a |method|: >
GetBufnr()->getbufvar(varname)
<
+getcellwidths() *getcellwidths()*
+ Returns a |List| of cell widths of character ranges overridden
+ by |setcellwidths()|. The format is equal to the argument of
+ |setcellwidths()|. If no character ranges have their cell
+ widths overridden, an empty List is returned.
+
+
getchangelist([{buf}]) *getchangelist()*
Returns the |changelist| for the buffer {buf}. For the use
of {buf}, see |bufname()| above. If buffer {buf} doesn't
@@ -2958,7 +2966,8 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
arglist file names in argument list
augroup autocmd groups
buffer buffer names
- behave :behave suboptions
+ behave |:behave| suboptions
+ breakpoint |:breakadd| and |:breakdel| suboptions
cmdline |cmdline-completion| result
color color schemes
command Ex command
@@ -2974,7 +2983,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
function function name
help help subjects
highlight highlight groups
- history :history suboptions
+ history |:history| suboptions
locale locale names (as output of locale -a)
mapclear buffer argument
mapping mapping name
@@ -2982,6 +2991,8 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
messages |:messages| suboptions
option options
packadd optional package |pack-add| names
+ runtime |:runtime| completion
+ scriptnames sourced script names |:scriptnames|
shellcmd Shell command
sign |:sign| suboptions
syntax syntax file names |'syntax'|
@@ -2999,6 +3010,13 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
is applied to filter the results. Otherwise all the matches
are returned. The 'wildignorecase' option always applies.
+ If the 'wildoptions' option contains "fuzzy", then fuzzy
+ matching is used to get the completion matches. Otherwise
+ regular expression matching is used. Thus this function
+ follows the user preference, what happens on the command line.
+ If you do not want this you can make 'wildoptions' empty
+ before calling getcompletion() and restore it afterwards.
+
If {type} is "cmdline", then the |cmdline-completion| result is
returned. For example, to complete the possible values after
a ":call" command: >
@@ -6934,7 +6952,7 @@ setcellwidths({list}) *setcellwidths()*
{low} and {high} can be the same, in which case this refers to
one character. Otherwise it is the range of characters from
{low} to {high} (inclusive). *E1111* *E1114*
- Only characters with value 0x100 and higher can be used.
+ Only characters with value 0x80 and higher can be used.
{width} must be either 1 or 2, indicating the character width
in screen cells. *E1112*
@@ -8311,6 +8329,7 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
"underdotted" "1" if dotted underlined
"underdashed" "1" if dashed underlined
"strikethrough" "1" if struckthrough
+ "altfont" "1" if alternative font
"nocombine" "1" if nocombine
Returns an empty string on error.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 6feb5cbb49..58759a6053 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2295,13 +2295,15 @@ v:version Vim version number: major version times 100 plus minor
:if has("nvim-0.2.1")
<
- *v:vim_did_enter* *vim_did_enter-variable*
-v:vim_did_enter 0 during startup, 1 just before |VimEnter|.
+ *v:virtnum* *virtnum-variable*
+v:virtnum Virtual line number for the 'statuscolumn' expression.
+ Negative when drawing the status column for virtual lines, zero
+ when drawing an actual buffer line, and positive when drawing
+ the wrapped part of a buffer line.
Read-only.
- *v:wrap* *wrap-variable*
-v:wrap Boolean indicating whether 'statuscolumn' is being evaluated
- for the wrapped part of a line.
+ *v:vim_did_enter* *vim_did_enter-variable*
+v:vim_did_enter 0 during startup, 1 just before |VimEnter|.
Read-only.
*v:warningmsg* *warningmsg-variable*
@@ -2679,6 +2681,8 @@ text...
[depth] is relevant when locking a |List| or
|Dictionary|. It specifies how deep the locking goes:
+ 0 Lock the variable {name} but not its
+ value.
1 Lock the |List| or |Dictionary| itself,
cannot add or remove items, but can
still change their values.
@@ -2692,7 +2696,14 @@ text...
|Dictionary|, one level deeper.
The default [depth] is 2, thus when {name} is a |List|
or |Dictionary| the values cannot be changed.
- *E743*
+
+ Example with [depth] 0: >
+ let mylist = [1, 2, 3]
+ lockvar 0 mylist
+ let mylist[0] = 77 " OK
+ call add(mylist, 4] " OK
+ let mylist = [7, 8, 9] " Error!
+< *E743*
For unlimited depth use [!] and omit [depth].
However, there is a maximum depth of 100 to catch
loops.
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 46cfa60529..215515a2d9 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -832,128 +832,118 @@ start({config}, {opts}) *vim.lsp.start()*
start_client({config}) *vim.lsp.start_client()*
Starts and initializes a client with the given configuration.
- Parameter `cmd` is required.
-
- The following parameters describe fields in the {config} table.
-
- Parameters: ~
- • {cmd} (table|string|fun(dispatchers: table):table)
- command string or list treated like |jobstart()|.
- The command must launch the language server
- process. `cmd` can also be a function that
- creates an RPC client. The function receives a
- dispatchers table and must return a table with
- the functions `request`, `notify`, `is_closing`
- and `terminate` See |vim.lsp.rpc.request()| and
- |vim.lsp.rpc.notify()| For TCP there is a
- built-in rpc client factory:
- |vim.lsp.rpc.connect()|
- • {cmd_cwd} (string, default=|getcwd()|) Directory to launch
- the `cmd` process. Not related to `root_dir`.
- • {cmd_env} (table) Environment flags to pass to the LSP on
- spawn. Can be specified using keys like a map or
- as a list with `k=v` pairs or both. Non-string values are coerced to
- string. Example: >
-
- { "PRODUCTION=true"; "TEST=123"; PORT = 8080; HOST = "0.0.0.0"; }
+ Field `cmd` in {config} is required.
+
+ Parameters: ~
+ • {config} (table) Configuration for the server:
+ • cmd: (table|string|fun(dispatchers: table):table) command
+ string or list treated like |jobstart()|. The command must
+ launch the language server process. `cmd` can also be a
+ function that creates an RPC client. The function receives
+ a dispatchers table and must return a table with the
+ functions `request`, `notify`, `is_closing` and
+ `terminate` See |vim.lsp.rpc.request()| and
+ |vim.lsp.rpc.notify()| For TCP there is a built-in rpc
+ client factory: |vim.lsp.rpc.connect()|
+ • cmd_cwd: (string, default=|getcwd()|) Directory to launch
+ the `cmd` process. Not related to `root_dir`.
+ • cmd_env: (table) Environment flags to pass to the LSP on
+ spawn. Can be specified using keys like a map or as a list
+ with `k=v` pairs or both. Non-string values are coerced to string.
+ Example: >
+
+ { "PRODUCTION=true"; "TEST=123"; PORT = 8080; HOST = "0.0.0.0"; }
<
- • {detached} (boolean, default true) Daemonize the server
- process so that it runs in a separate process
- group from Nvim. Nvim will shutdown the process
- on exit, but if Nvim fails to exit cleanly this
- could leave behind orphaned server processes.
- • {workspace_folders} (table) List of workspace folders passed to the
- language server. For backwards compatibility
- rootUri and rootPath will be derived from the
- first workspace folder in this list. See
- `workspaceFolders` in the LSP spec.
- • {capabilities} Map overriding the default capabilities defined
- by |vim.lsp.protocol.make_client_capabilities()|,
- passed to the language server on initialization.
- Hint: use make_client_capabilities() and modify
- its result.
- • Note: To send an empty dictionary use
- `{[vim.type_idx]=vim.types.dictionary}`, else
- it will be encoded as an array.
- • {handlers} Map of language server method names to
- |lsp-handler|
- • {settings} Map with language server specific settings. These
- are returned to the language server if requested
- via `workspace/configuration`. Keys are
- case-sensitive.
- • {commands} (table) Table that maps string of clientside
- commands to user-defined functions. Commands
- passed to start_client take precedence over the
- global command registry. Each key must be a
- unique command name, and the value is a function
- which is called if any LSP action (code action,
- code lenses, ...) triggers the command.
- • {init_options} Values to pass in the initialization request as
- `initializationOptions`. See `initialize` in the
- LSP spec.
- • {name} (string, default=client-id) Name in log messages.
- • {get_language_id} function(bufnr, filetype) -> language ID as
- string. Defaults to the filetype.
- • {offset_encoding} (default="utf-16") One of "utf-8", "utf-16", or
- "utf-32" which is the encoding that the LSP
- server expects. Client does not verify this is
- correct.
- • {on_error} Callback with parameters (code, ...), invoked
- when the client operation throws an error. `code`
- is a number describing the error. Other arguments
- may be passed depending on the error kind. See
- `vim.lsp.rpc.client_errors` for possible errors.
- Use `vim.lsp.rpc.client_errors[code]` to get
- human-friendly name.
- • {before_init} Callback with parameters (initialize_params,
- config) invoked before the LSP "initialize"
- phase, where `params` contains the parameters
- being sent to the server and `config` is the
- config that was passed to
- |vim.lsp.start_client()|. You can use this to
- modify parameters before they are sent.
- • {on_init} Callback (client, initialize_result) invoked
- after LSP "initialize", where `result` is a table
- of `capabilities` and anything else the server
- may send. For example, clangd sends
- `initialize_result.offsetEncoding` if
- `capabilities.offsetEncoding` was sent to it. You
- can only modify the `client.offset_encoding` here
- before any notifications are sent. Most language
- servers expect to be sent client specified
- settings after initialization. Neovim does not
- make this assumption. A
- `workspace/didChangeConfiguration` notification
- should be sent to the server during on_init.
- • {on_exit} Callback (code, signal, client_id) invoked on
- client exit.
- • code: exit code of the process
- • signal: number describing the signal used to
- terminate (if any)
- • client_id: client handle
- • {on_attach} Callback (client, bufnr) invoked when client
- attaches to a buffer.
- • {trace} "off" | "messages" | "verbose" | nil passed
- directly to the language server in the initialize
- request. Invalid/empty values will default to
- "off"
- • {flags} A table with flags for the client. The current
- (experimental) flags are:
- • allow_incremental_sync (bool, default true):
- Allow using incremental sync for buffer edits
- • debounce_text_changes (number, default 150):
- Debounce didChange notifications to the server
- by the given number in milliseconds. No
- debounce occurs if nil
- • exit_timeout (number|boolean, default false):
- Milliseconds to wait for server to exit cleanly
- after sending the "shutdown" request before
- sending kill -15. If set to false, nvim exits
- immediately after sending the "shutdown"
- request to the server.
- • {root_dir} (string) Directory where the LSP server will base
- its workspaceFolders, rootUri, and rootPath on
- initialization.
+ • detached: (boolean, default true) Daemonize the server
+ process so that it runs in a separate process group from
+ Nvim. Nvim will shutdown the process on exit, but if Nvim
+ fails to exit cleanly this could leave behind orphaned
+ server processes.
+ • workspace_folders: (table) List of workspace folders
+ passed to the language server. For backwards compatibility
+ rootUri and rootPath will be derived from the first
+ workspace folder in this list. See `workspaceFolders` in
+ the LSP spec.
+ • capabilities: Map overriding the default capabilities
+ defined by |vim.lsp.protocol.make_client_capabilities()|,
+ passed to the language server on initialization. Hint: use
+ make_client_capabilities() and modify its result.
+ • Note: To send an empty dictionary use
+ `{[vim.type_idx]=vim.types.dictionary}`, else it will be
+ encoded as an array.
+
+ • handlers: Map of language server method names to
+ |lsp-handler|
+ • settings: Map with language server specific settings.
+ These are returned to the language server if requested via
+ `workspace/configuration`. Keys are case-sensitive.
+ • commands: table Table that maps string of clientside
+ commands to user-defined functions. Commands passed to
+ start_client take precedence over the global command
+ registry. Each key must be a unique command name, and the
+ value is a function which is called if any LSP action
+ (code action, code lenses, ...) triggers the command.
+ • init_options Values to pass in the initialization request
+ as `initializationOptions`. See `initialize` in the LSP
+ spec.
+ • name: (string, default=client-id) Name in log messages.
+ • get_language_id: function(bufnr, filetype) -> language ID
+ as string. Defaults to the filetype.
+ • offset_encoding: (default="utf-16") One of "utf-8",
+ "utf-16", or "utf-32" which is the encoding that the LSP
+ server expects. Client does not verify this is correct.
+ • on_error: Callback with parameters (code, ...), invoked
+ when the client operation throws an error. `code` is a
+ number describing the error. Other arguments may be passed
+ depending on the error kind. See
+ `vim.lsp.rpc.client_errors` for possible errors. Use
+ `vim.lsp.rpc.client_errors[code]` to get human-friendly
+ name.
+ • before_init: Callback with parameters (initialize_params,
+ config) invoked before the LSP "initialize" phase, where
+ `params` contains the parameters being sent to the server
+ and `config` is the config that was passed to
+ |vim.lsp.start_client()|. You can use this to modify
+ parameters before they are sent.
+ • on_init: Callback (client, initialize_result) invoked
+ after LSP "initialize", where `result` is a table of
+ `capabilities` and anything else the server may send. For
+ example, clangd sends `initialize_result.offsetEncoding`
+ if `capabilities.offsetEncoding` was sent to it. You can
+ only modify the `client.offset_encoding` here before any
+ notifications are sent. Most language servers expect to be
+ sent client specified settings after initialization.
+ Neovim does not make this assumption. A
+ `workspace/didChangeConfiguration` notification should be
+ sent to the server during on_init.
+ • on_exit Callback (code, signal, client_id) invoked on
+ client exit.
+ • code: exit code of the process
+ • signal: number describing the signal used to terminate
+ (if any)
+ • client_id: client handle
+
+ • on_attach: Callback (client, bufnr) invoked when client
+ attaches to a buffer.
+ • trace: ("off" | "messages" | "verbose" | nil) passed
+ directly to the language server in the initialize request.
+ Invalid/empty values will default to "off"
+ • flags: A table with flags for the client. The current
+ (experimental) flags are:
+ • allow_incremental_sync (bool, default true): Allow using
+ incremental sync for buffer edits
+ • debounce_text_changes (number, default 150): Debounce
+ didChange notifications to the server by the given
+ number in milliseconds. No debounce occurs if nil
+ • exit_timeout (number|boolean, default false):
+ Milliseconds to wait for server to exit cleanly after
+ sending the "shutdown" request before sending kill -15.
+ If set to false, nvim exits immediately after sending
+ the "shutdown" request to the server.
+
+ • root_dir: (string) Directory where the LSP server will
+ base its workspaceFolders, rootUri, and rootPath on
+ initialization.
Return: ~
Client id. |vim.lsp.get_client_by_id()| Note: client may not be fully
@@ -1022,6 +1012,8 @@ code_action({options}) *vim.lsp.buf.code_action()*
• only (table|nil): List of LSP `CodeActionKind`s used to
filter the code actions. Most language servers support
values like `refactor` or `quickfix`.
+ • triggerKind (number|nil): The reason why code actions
+ were requested.
• filter: (function|nil) Predicate taking an `CodeAction`
and returning a boolean.
@@ -1036,6 +1028,7 @@ code_action({options}) *vim.lsp.buf.code_action()*
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
+ vim.lsp.protocol.constants.CodeActionTriggerKind
completion({context}) *vim.lsp.buf.completion()*
Retrieves the completion items at the current cursor position. Can only be
diff --git a/runtime/doc/lua-guide.txt b/runtime/doc/lua-guide.txt
index 71dc48b715..b971a7d2ad 100644
--- a/runtime/doc/lua-guide.txt
+++ b/runtime/doc/lua-guide.txt
@@ -406,9 +406,9 @@ mandatory arguments:
prefix for which the mapping will take effect. The prefixes are the ones
listed in |:map-modes|, or "!" for |:map!|, or empty string for |:map|.
• {lhs} is a string with the key sequences that should trigger the mapping.
- An empty string is equivalent to |<Nop>|, which disables a key.
• {rhs} is either a string with a Vim command or a Lua function that should
be executed when the {lhs} is entered.
+ An empty string is equivalent to |<Nop>|, which disables a key.
Examples:
>lua
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 16d0bcb612..47249a484b 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -132,8 +132,7 @@ back to Lua's default search mechanism. The first script found is run and
The return value is cached after the first call to `require()` for each module,
with subsequent calls returning the cached value without searching for, or
-executing any script. For further details on `require()`, see the Lua
-documentation at https://www.lua.org/manual/5.1/manual.html#pdf-require.
+executing any script. For further details on `require()`, see |luaref-require()|.
For example, if 'runtimepath' is `foo,bar` and |package.cpath| was
`./?.so;./?.dll` at startup, `require('mod')` searches these paths in order
@@ -1641,6 +1640,7 @@ gsplit({s}, {sep}, {plain}) *vim.gsplit()*
See also: ~
|vim.split()|
+ |luaref-patterns|
https://www.lua.org/pil/20.2.html
http://lua-users.org/wiki/StringLibraryTutorial
@@ -1694,6 +1694,18 @@ pesc({s}) *vim.pesc()*
See also: ~
https://github.com/rxi/lume
+spairs({t}) *vim.spairs()*
+ Enumerate a table sorted by its keys.
+
+ Parameters: ~
+ • {t} (table) List-like table
+
+ Return: ~
+ iterator over sorted keys and their values
+
+ See also: ~
+ Based on https://github.com/premake/premake-core/blob/master/src/base/table.lua
+
split({s}, {sep}, {kwargs}) *vim.split()*
Splits a string at each instance of a separator.
@@ -1913,6 +1925,7 @@ trim({s}) *vim.trim()*
(string) String with whitespace removed from its beginning and end
See also: ~
+ |luaref-patterns|
https://www.lua.org/pil/20.2.html
validate({opt}) *vim.validate()*
@@ -2379,7 +2392,7 @@ normalize({path}) *vim.fs.normalize()*
Examples: >lua
- vim.fs.normalize('C:\Users\jdoe')
+ vim.fs.normalize('C:\\Users\\jdoe')
--> 'C:/Users/jdoe'
vim.fs.normalize('~/src/neovim')
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index ccd48a8959..cb8b162eb6 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1432,9 +1432,11 @@ The function arguments are:
The function may use these for determining context. For the "custom"
argument, it is not necessary to filter candidates against the (implicit
pattern in) ArgLead. Vim will filter the candidates with its regexp engine
-after function return, and this is probably more efficient in most cases. For
-the "customlist" argument, Vim will not filter the returned completion
-candidates and the user supplied function should filter the candidates.
+after function return, and this is probably more efficient in most cases. If
+'wildoptions' contains "fuzzy", then the candidates will be filtered using
+|fuzzy-matching|. For the "customlist" argument, Vim will not
+filter the returned completion candidates and the user supplied function
+should filter the candidates.
The following example lists user names to a Finger command >
:com -complete=custom,ListUsers -nargs=1 Finger !finger <args>
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index ce07c3035c..5c234677ef 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -45,6 +45,8 @@ The following changes may require adaptations in user config or plugins.
- `printheader`
- `printmbcharset`
+• libiconv is now a required build dependency.
+
==============================================================================
NEW FEATURES *news-features*
@@ -143,6 +145,12 @@ The following new APIs or features were added.
instance in the background and display its UI on demand, which previously
only was possible using an external UI implementation.
+• Several improvements were made to make the code generation scripts more
+ deterministic, and a `LUA_GEN_PRG` build parameter has been introduced to
+ allow for a workaround for some remaining reproducibility problems.
+
+• |:highlight| now supports an additional attribute "altfont".
+
==============================================================================
CHANGED FEATURES *news-changes*
@@ -159,11 +167,17 @@ The following changes to existing APIs or features add new behavior.
resulting in a nvim binary which only could be run headless or embedded
in an external process. As of this version, TUI is always available.
+• API calls now show more information about where an exception happened.
+
==============================================================================
REMOVED FEATURES *news-removed*
The following deprecated functions or APIs were removed.
+• It is no longer possible to scroll the whole screen when showing messages
+ longer than 'cmdheight'. |msgsep| is now always enabled even if 'display'
+ doesn't contain the "msgsep" flag.
+
• `filetype.vim` is removed in favor of |lua-filetype|
(Note that filetype logic and tests still align with Vim, so additions or
changes need to be contributed there first.)
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 4498dda300..b1af90a604 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3843,21 +3843,21 @@ A jump table for the options with a short description can be found at |Q_op|.
The third character is optional.
tab:xy The 'x' is always used, then 'y' as many times as will
- fit. Thus "tab:>-" displays:
+ fit. Thus "tab:>-" displays: >
>
>-
>--
etc.
-
+<
tab:xyz The 'z' is always used, then 'x' is prepended, and
then 'y' is used as many times as will fit. Thus
- "tab:<->" displays:
+ "tab:<->" displays: >
>
<>
<->
<-->
etc.
-
+<
When "tab:" is omitted, a tab is shown as ^I.
*lcs-space*
space:c Character to show for a space. When omitted, spaces
@@ -3869,22 +3869,25 @@ A jump table for the options with a short description can be found at |Q_op|.
setting, except for single spaces. When omitted, the
"space" setting is used. For example,
`:set listchars=multispace:---+` shows ten consecutive
- spaces as:
- ---+---+-- ~
+ spaces as: >
+ ---+---+--
+<
*lcs-lead*
lead:c Character to show for leading spaces. When omitted,
leading spaces are blank. Overrides the "space" and
"multispace" settings for leading spaces. You can
combine it with "tab:", for example: >
:set listchars+=tab:>-,lead:.
-< *lcs-leadmultispace*
+<
+ *lcs-leadmultispace*
leadmultispace:c...
Like the |lcs-multispace| value, but for leading
spaces only. Also overrides |lcs-lead| for leading
multiple spaces.
`:set listchars=leadmultispace:---+` shows ten
- consecutive leading spaces as:
- ---+---+--XXX ~
+ consecutive leading spaces as: >
+ ---+---+--XXX
+<
Where "XXX" denotes the first non-blank characters in
the line.
*lcs-trail*
@@ -6017,12 +6020,20 @@ A jump table for the options with a short description can be found at |Q_op|.
%s sign column for currently drawn line
%C fold column for currently drawn line
- To draw the sign and fold columns, they must be included in
- 'statuscolumn'.
+ NOTE: To draw the sign and fold columns, their items must be included in
+ 'statuscolumn'. Even when they are not included, the status column width
+ will adapt to the 'signcolumn' and 'foldcolumn' width.
+
+ The |v:lnum| variable holds the line number to be drawn.
+ The |v:relnum| variable holds the relative line number to be drawn.
+ The |v:virtnum| variable is negative when drawing virtual lines, zero
+ when drawing the actual buffer line, and positive when
+ drawing the wrapped part of a buffer line.
- The |v:lnum| variable holds the line number to be drawn.
- The |v:relnum| variable holds the relative line number to be drawn.
- The |v:wrap| variable holds true for the wrapped part of a line.
+ NOTE: The %@ click execute function item is supported as well but the
+ specified function will be the same for each row in the same column.
+ It cannot be switched out through a dynamic 'statuscolumn' format, the
+ handler should be written with this in mind.
Examples: >vim
" Relative number with bar separator and click handlers:
@@ -6032,7 +6043,7 @@ A jump table for the options with a short description can be found at |Q_op|.
:let &stc='%=%{v:relnum?v:relnum:v:lnum} '
" Line numbers in hexadecimal for non wrapped part of lines:
- :let &stc='%=%{v:wrap?"":printf("%x",v:lnum)} '
+ :let &stc='%=%{v:virtnum>0?"":printf("%x",v:lnum)} '
" Human readable line numbers with thousands separator:
:let &stc='%{substitute(v:lnum,"\\d\\zs\\ze\\'
@@ -7123,6 +7134,14 @@ A jump table for the options with a short description can be found at |Q_op|.
global
A list of words that change how |cmdline-completion| is done.
The following values are supported:
+ fuzzy Use |fuzzy-matching| to find completion matches. When
+ this value is specified, wildcard expansion will not
+ be used for completion. The matches will be sorted by
+ the "best match" rather than alphabetically sorted.
+ This will find more matches than the wildcard
+ expansion. Currently fuzzy matching based completion
+ is not supported for file and directory names and
+ instead wildcard expansion is used.
pum Display the completion matches using the popup menu
in the same style as the |ins-completion-menu|.
tagfile When using CTRL-D to list matching tags, the kind of
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index 1bbd20702b..bf77aacdc0 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -211,9 +211,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
When [!] is included, all found files are sourced.
Else only the first found file is sourced.
- When [where] is omitted, first 'runtimepath' is
- searched, then directories under "start" in 'packpath'
- are searched.
+ When [where] is omitted only 'runtimepath' is used.
Other values:
START search only under "start" in 'packpath'
OPT search only under "opt" in 'packpath'
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 179bacdb24..5e0718c3bb 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -239,6 +239,14 @@ argument.
Disables |shada| unless |-i| was given.
Disables swapfile (like |-n|).
+ *-ll*
+-ll {script} [args]
+ Execute a lua script, similarly to |-l|, but the editor is not
+ initialized. This gives a lua enviroment similar to a worker
+ thread. See |lua-loop-threading|.
+
+ Unlike `-l` no prior arguments are allowed.
+
*-b*
-b Binary mode. File I/O will only recognize <NL> to separate
lines. The 'expandtab' option will be reset. The 'textwidth'
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index b4afc3f233..bd5a4f1926 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -4958,7 +4958,8 @@ the same syntax file on all UIs.
*bold* *underline* *undercurl*
*underdouble* *underdotted*
*underdashed* *inverse* *italic*
- *standout* *nocombine* *strikethrough*
+ *standout* *strikethrough* *altfont*
+ *nocombine*
cterm={attr-list} *attr-list* *highlight-cterm* *E418*
attr-list is a comma-separated list (without spaces) of the
following items (in any order):
@@ -4973,6 +4974,7 @@ cterm={attr-list} *attr-list* *highlight-cterm* *E418*
inverse same as reverse
italic
standout
+ altfont
nocombine override attributes instead of combining them
NONE no attributes used (used to reset it)
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index 096cec6678..9bfdc0b94e 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -684,6 +684,7 @@ require_language({lang}, {path}, {silent}, {symbol_name})
Parameters: ~
• {lang} (string) Language the parser should parse
+ (alphanumerical and `_` only)
• {path} (string|nil) Optional path the parser is located at
• {silent} (boolean|nil) Don't throw an error if language not
found
@@ -708,8 +709,15 @@ add_directive({name}, {handler}, {force})
Parameters: ~
• {name} (string) Name of the directive, without leading #
- • {handler} function(match:string, pattern:string, bufnr:number,
- predicate:function, metadata:table)
+ • {handler} function(match:table, pattern:string, bufnr:number,
+ predicate:string[], metadata:table)
+ • match: see |treesitter-query|
+ • node-level data are accessible via `match[capture_id]`
+
+ • pattern: see |treesitter-query|
+ • predicate: list of strings containing the full directive
+ being called, e.g. `(node (#set! conceal "-"))` would get
+ the predicate `{ "#set!", "conceal", "-" }`
*vim.treesitter.query.add_predicate()*
add_predicate({name}, {handler}, {force})
@@ -717,8 +725,10 @@ add_predicate({name}, {handler}, {force})
Parameters: ~
• {name} (string) Name of the predicate, without leading #
- • {handler} function(match:string, pattern:string, bufnr:number,
- predicate:function)
+ • {handler} function(match:table, pattern:string, bufnr:number,
+ predicate:string[])
+ • see |vim.treesitter.query.add_directive()| for argument
+ meanings
*vim.treesitter.query.get_node_text()*
get_node_text({node}, {source}, {opts})
diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt
index a2ae9f22ce..3110d0817c 100644
--- a/runtime/doc/ui.txt
+++ b/runtime/doc/ui.txt
@@ -324,6 +324,7 @@ numerical highlight ids to the actual attributes.
`underdouble`: double underlined text. The lines have `special` color.
`underdotted`: underdotted text. The dots have `special` color.
`underdashed`: underdashed text. The dashes have `special` color.
+ `altfont`: alternative font.
`blend`: Blend level (0-100). Could be used by UIs to
support blending floating windows to the
background or to signal a transparent cursor.
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 226bd029a3..910aebae70 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -624,6 +624,7 @@ String manipulation: *string-functions*
strwidth() size of string when displayed
strdisplaywidth() size of string when displayed, deals with tabs
setcellwidths() set character cell width overrides
+ getcellwidths() get character cell width overrides
substitute() substitute a pattern match with a string
submatch() get a specific match in ":s" and substitute()
strpart() get part of a string using byte index
diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua
index a644dd68b8..0956022ac6 100644
--- a/runtime/lua/man.lua
+++ b/runtime/lua/man.lua
@@ -149,15 +149,21 @@ local function highlight_line(line, linenr)
if overstrike then
local last_hl = hls[#hls]
if char == prev_char then
- if char == '_' and attr == UNDERLINE and last_hl and last_hl.final == byte then
- -- This underscore is in the middle of an underlined word
- attr = UNDERLINE
+ if char == '_' and attr == ITALIC and last_hl and last_hl.final == byte then
+ -- This underscore is in the middle of an italic word
+ attr = ITALIC
else
attr = BOLD
end
elseif prev_char == '_' then
- -- char is underlined
- attr = UNDERLINE
+ -- Even though underline is strictly what this should be. <bs>_ was used by nroff to
+ -- indicate italics which wasn't possible on old typewriters so underline was used. Modern
+ -- terminals now support italics so lets use that now.
+ -- See:
+ -- - https://unix.stackexchange.com/questions/274658/purpose-of-ascii-text-with-overstriking-file-format/274795#274795
+ -- - https://cmd.inp.nsk.su/old/cmd2/manuals/unix/UNIX_Unleashed/ch08.htm
+ -- attr = UNDERLINE
+ attr = ITALIC
elseif prev_char == '+' and char == 'o' then
-- bullet (overstrike text '+^Ho')
attr = BOLD
@@ -420,6 +426,10 @@ local function extract_sect_and_name_path(path)
end
local function find_man()
+ if vim.bo.filetype == 'man' then
+ return true
+ end
+
local win = 1
while win <= fn.winnr('$') do
local buf = fn.winbufnr(win)
diff --git a/runtime/lua/nvim/health.lua b/runtime/lua/nvim/health.lua
index c00b921d5c..f11899434e 100644
--- a/runtime/lua/nvim/health.lua
+++ b/runtime/lua/nvim/health.lua
@@ -1,6 +1,22 @@
local M = {}
local health = require('vim.health')
+local fn_bool = function(key)
+ return function(...)
+ return vim.fn[key](...) == 1
+ end
+end
+
+local has = fn_bool('has')
+local executable = fn_bool('executable')
+local empty = fn_bool('empty')
+local filereadable = fn_bool('filereadable')
+local filewritable = fn_bool('filewritable')
+
+local shell_error = function()
+ return vim.v.shell_error ~= 0
+end
+
local suggest_faq = 'https://github.com/neovim/neovim/wiki/Building-Neovim#optimized-builds'
local function check_runtime()
@@ -37,15 +53,6 @@ end
local function check_config()
health.report_start('Configuration')
local ok = true
- local empty = function(o)
- return 0 ~= vim.fn.empty(o)
- end
- local filereadable = function(o)
- return 0 ~= vim.fn.filereadable(o)
- end
- local filewritable = function(o)
- return 0 ~= vim.fn.filewritable(o)
- end
local vimrc = (
empty(vim.env.MYVIMRC) and vim.fn.stdpath('config') .. '/init.vim' or vim.env.MYVIMRC
@@ -65,7 +72,7 @@ local function check_config()
health.report_error('$VIM is invalid: ' .. vim.env.VIM)
end
- if 1 == vim.fn.exists('$NVIM_TUI_ENABLE_CURSOR_SHAPE') then
+ if vim.env.NVIM_TUI_ENABLE_CURSOR_SHAPE then
ok = false
health.report_warn('$NVIM_TUI_ENABLE_CURSOR_SHAPE is ignored in Nvim 0.2+', {
"Use the 'guicursor' option to configure cursor shape. :help 'guicursor'",
@@ -139,240 +146,249 @@ local function check_config()
end
local function check_performance()
- vim.api.nvim_exec([=[
- func! s:check_performance() abort
- let s:suggest_faq = ']=] .. suggest_faq .. [=['
-
- call health#report_start('Performance')
-
- " check buildtype
- let s:buildtype = matchstr(execute('version'), '\v\cbuild type:?\s*[^\n\r\t ]+')
- if empty(s:buildtype)
- call health#report_error('failed to get build type from :version')
- elseif s:buildtype =~# '\v(MinSizeRel|Release|RelWithDebInfo)'
- call health#report_ok(s:buildtype)
- else
- call health#report_info(s:buildtype)
- call health#report_warn(
- \ 'Non-optimized '.(has('debug')?'(DEBUG) ':'').'build. Nvim will be slower.',
- \ ['Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.',
- \ s:suggest_faq])
- endif
-
- " check for slow shell invocation
- let s:slow_cmd_time = 1.5
- let s:start_time = reltime()
- call system('echo')
- let s:elapsed_time = reltimefloat(reltime(s:start_time))
- if s:elapsed_time > s:slow_cmd_time
- call health#report_warn(
- \ 'Slow shell invocation (took '.printf('%.2f', s:elapsed_time).' seconds).')
- endif
- endf
-
- call s:check_performance()
- ]=], false)
+ health.report_start('Performance')
+
+ -- Check buildtype
+ local buildtype = vim.fn.matchstr(vim.fn.execute('version'), [[\v\cbuild type:?\s*[^\n\r\t ]+]])
+ if empty(buildtype) then
+ health.report_error('failed to get build type from :version')
+ elseif vim.regex([[\v(MinSizeRel|Release|RelWithDebInfo)]]):match_str(buildtype) then
+ health.report_ok(buildtype)
+ else
+ health.report_info(buildtype)
+ health.report_warn('Non-optimized debug build. Nvim will be slower.', {
+ 'Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.',
+ suggest_faq,
+ })
+ end
+
+ -- check for slow shell invocation
+ local slow_cmd_time = 1.5
+ local start_time = vim.fn.reltime()
+ vim.fn.system('echo')
+ local elapsed_time = vim.fn.reltimefloat(vim.fn.reltime(start_time))
+ if elapsed_time > slow_cmd_time then
+ health.report_warn(
+ 'Slow shell invocation (took ' .. vim.fn.printf('%.2f', elapsed_time) .. ' seconds).'
+ )
+ end
end
-- Load the remote plugin manifest file and check for unregistered plugins
local function check_rplugin_manifest()
- vim.api.nvim_exec(
- [=[
- func! s:check_rplugin_manifest() abort
- call health#report_start('Remote Plugins')
- let existing_rplugins = {}
-
- for item in remote#host#PluginsForHost('python')
- let existing_rplugins[item.path] = 'python'
- endfor
-
- for item in remote#host#PluginsForHost('python3')
- let existing_rplugins[item.path] = 'python3'
- endfor
-
- let require_update = 0
-
- for path in map(split(&runtimepath, ','), 'resolve(v:val)')
- let python_glob = glob(path.'/rplugin/python*', 1, 1)
- if empty(python_glob)
- continue
- endif
-
- let python_dir = python_glob[0]
- let python_version = fnamemodify(python_dir, ':t')
-
- for script in glob(python_dir.'/*.py', 1, 1)
- \ + glob(python_dir.'/*/__init__.py', 1, 1)
- let contents = join(readfile(script))
- if contents =~# '\<\%(from\|import\)\s\+neovim\>'
- if script =~# '[\/]__init__\.py$'
- let script = tr(fnamemodify(script, ':h'), '\', '/')
- endif
-
- if !has_key(existing_rplugins, script)
- let msg = printf('"%s" is not registered.', fnamemodify(path, ':t'))
- if python_version ==# 'pythonx'
- if !has('python3')
- let msg .= ' (python3 not available)'
- endif
- elseif !has(python_version)
- let msg .= printf(' (%s not available)', python_version)
- else
- let require_update = 1
- endif
-
- call health#report_warn(msg)
- endif
-
- break
- endif
- endfor
- endfor
-
- if require_update
- call health#report_warn('Out of date', ['Run `:UpdateRemotePlugins`'])
- else
- call health#report_ok('Up to date')
- endif
- endf
+ health.report_start('Remote Plugins')
- call s:check_rplugin_manifest()
- ]=],
- false
- )
+ local existing_rplugins = {}
+ for _, item in ipairs(vim.fn['remote#host#PluginsForHost']('python')) do
+ existing_rplugins[item.path] = 'python'
+ end
+
+ for item in ipairs(vim.fn['remote#host#PluginsForHost']('python3')) do
+ existing_rplugins[item.path] = 'python3'
+ end
+
+ local require_update = false
+ local handle_path = function(path)
+ local python_glob = vim.fn.glob(path .. '/rplugin/python*', true, true)
+ if empty(python_glob) then
+ return
+ end
+
+ local python_dir = python_glob[1]
+ local python_version = vim.fn.fnamemodify(python_dir, ':t')
+
+ local scripts = vim.fn.glob(python_dir .. '/*.py', true, true)
+ vim.list_extend(scripts, vim.fn.glob(python_dir .. '/*/__init__.py', true, true))
+
+ for script in ipairs(scripts) do
+ local contents = vim.fn.join(vim.fn.readfile(script))
+ if vim.regex([[\<\%(from\|import\)\s\+neovim\>]]):match_str(contents) then
+ if vim.regex([[[\/]__init__\.py$]]):match_str(script) then
+ script = vim.fn.tr(vim.fn.fnamemodify(script, ':h'), '\\', '/')
+ end
+ if not existing_rplugins[script] then
+ local msg = vim.fn.printf('"%s" is not registered.', vim.fn.fnamemodify(path, ':t'))
+ if python_version == 'pythonx' then
+ if not has('python3') then
+ msg = msg .. ' (python3 not available)'
+ end
+ elseif not has(python_version) then
+ msg = msg .. vim.fn.printf(' (%s not available)', python_version)
+ else
+ require_update = true
+ end
+
+ health.report_warn(msg)
+ end
+
+ break
+ end
+ end
+ end
+
+ for _, path in ipairs(vim.fn.map(vim.fn.split(vim.o.runtimepath, ','), 'resolve(v:val)')) do
+ handle_path(path)
+ end
+
+ if require_update then
+ health.report_warn('Out of date', { 'Run `:UpdateRemotePlugins`' })
+ else
+ health.report_ok('Up to date')
+ end
end
local function check_tmux()
- vim.api.nvim_exec([=[
- let s:suggest_faq = ']=] .. suggest_faq .. [=['
-
- func! s:get_tmux_option(option) abort
- let cmd = 'tmux show-option -qvg '.a:option " try global scope
- let out = system(split(cmd))
- let val = substitute(out, '\v(\s|\r|\n)', '', 'g')
- if v:shell_error
- call health#report_error('command failed: '.cmd."\n".out)
+ if empty(vim.env.TMUX) or not executable('tmux') then
+ return
+ end
+
+ local get_tmux_option = function(option)
+ local cmd = 'tmux show-option -qvg ' .. option -- try global scope
+ local out = vim.fn.system(vim.fn.split(cmd))
+ local val = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ if shell_error() then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
return 'error'
- elseif empty(val)
- let cmd = 'tmux show-option -qvgs '.a:option " try session scope
- let out = system(split(cmd))
- let val = substitute(out, '\v(\s|\r|\n)', '', 'g')
- if v:shell_error
- call health#report_error('command failed: '.cmd."\n".out)
+ elseif empty(val) then
+ cmd = 'tmux show-option -qvgs ' .. option -- try session scope
+ out = vim.fn.system(vim.fn.split(cmd))
+ val = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ if shell_error() then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
return 'error'
- endif
- endif
+ end
+ end
return val
- endf
+ end
- func! s:check_tmux() abort
- if empty($TMUX) || !executable('tmux')
- return
- endif
- call health#report_start('tmux')
-
- " check escape-time
- let suggestions = ["set escape-time in ~/.tmux.conf:\nset-option -sg escape-time 10",
- \ s:suggest_faq]
- let tmux_esc_time = s:get_tmux_option('escape-time')
- if tmux_esc_time !=# 'error'
- if empty(tmux_esc_time)
- call health#report_error('`escape-time` is not set', suggestions)
- elseif tmux_esc_time > 300
- call health#report_error(
- \ '`escape-time` ('.tmux_esc_time.') is higher than 300ms', suggestions)
- else
- call health#report_ok('escape-time: '.tmux_esc_time)
- endif
- endif
-
- " check focus-events
- let suggestions = ["(tmux 1.9+ only) Set `focus-events` in ~/.tmux.conf:\nset-option -g focus-events on"]
- let tmux_focus_events = s:get_tmux_option('focus-events')
- if tmux_focus_events !=# 'error'
- if empty(tmux_focus_events) || tmux_focus_events !=# 'on'
- call health#report_warn(
- \ "`focus-events` is not enabled. |'autoread'| may not work.", suggestions)
- else
- call health#report_ok('focus-events: '.tmux_focus_events)
- endif
- endif
-
- " check default-terminal and $TERM
- call health#report_info('$TERM: '.$TERM)
- let cmd = 'tmux show-option -qvg default-terminal'
- let out = system(split(cmd))
- let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g')
- if empty(tmux_default_term)
- let cmd = 'tmux show-option -qvgs default-terminal'
- let out = system(split(cmd))
- let tmux_default_term = substitute(out, '\v(\s|\r|\n)', '', 'g')
- endif
-
- if v:shell_error
- call health#report_error('command failed: '.cmd."\n".out)
- elseif tmux_default_term !=# $TERM
- call health#report_info('default-terminal: '.tmux_default_term)
- call health#report_error(
- \ '$TERM differs from the tmux `default-terminal` setting. Colors might look wrong.',
- \ ['$TERM may have been set by some rc (.bashrc, .zshrc, ...).'])
- elseif $TERM !~# '\v(tmux-256color|screen-256color)'
- call health#report_error(
- \ '$TERM should be "screen-256color" or "tmux-256color" in tmux. Colors might look wrong.',
- \ ["Set default-terminal in ~/.tmux.conf:\nset-option -g default-terminal \"screen-256color\"",
- \ s:suggest_faq])
- endif
-
- " check for RGB capabilities
- let info = system(['tmux', 'show-messages', '-JT'])
- let has_tc = stridx(info, " Tc: (flag) true") != -1
- let has_rgb = stridx(info, " RGB: (flag) true") != -1
- if !has_tc && !has_rgb
- call health#report_warn(
- \ "Neither Tc nor RGB capability set. True colors are disabled. |'termguicolors'| won't work properly.",
- \ ["Put this in your ~/.tmux.conf and replace XXX by your $TERM outside of tmux:\nset-option -sa terminal-overrides ',XXX:RGB'",
- \ "For older tmux versions use this instead:\nset-option -ga terminal-overrides ',XXX:Tc'"])
- endif
- endf
-
- call s:check_tmux()
- ]=], false)
+ health.report_start('tmux')
+
+ -- check escape-time
+ local suggestions =
+ { 'set escape-time in ~/.tmux.conf:\nset-option -sg escape-time 10', suggest_faq }
+ local tmux_esc_time = get_tmux_option('escape-time')
+ if tmux_esc_time ~= 'error' then
+ if empty(tmux_esc_time) then
+ health.report_error('`escape-time` is not set', suggestions)
+ elseif tonumber(tmux_esc_time) > 300 then
+ health.report_error(
+ '`escape-time` (' .. tmux_esc_time .. ') is higher than 300ms',
+ suggestions
+ )
+ else
+ health.report_ok('escape-time: ' .. tmux_esc_time)
+ end
+ end
+
+ -- check focus-events
+ local tmux_focus_events = get_tmux_option('focus-events')
+ if tmux_focus_events ~= 'error' then
+ if empty(tmux_focus_events) or tmux_focus_events ~= 'on' then
+ health.report_warn(
+ "`focus-events` is not enabled. |'autoread'| may not work.",
+ { '(tmux 1.9+ only) Set `focus-events` in ~/.tmux.conf:\nset-option -g focus-events on' }
+ )
+ else
+ health.report_ok('focus-events: ' .. tmux_focus_events)
+ end
+ end
+
+ -- check default-terminal and $TERM
+ health.report_info('$TERM: ' .. vim.env.TERM)
+ local cmd = 'tmux show-option -qvg default-terminal'
+ local out = vim.fn.system(vim.fn.split(cmd))
+ local tmux_default_term = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ if empty(tmux_default_term) then
+ cmd = 'tmux show-option -qvgs default-terminal'
+ out = vim.fn.system(vim.fn.split(cmd))
+ tmux_default_term = vim.fn.substitute(out, [[\v(\s|\r|\n)]], '', 'g')
+ end
+
+ if shell_error() then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
+ elseif tmux_default_term ~= vim.env.TERM then
+ health.report_info('default-terminal: ' .. tmux_default_term)
+ health.report_error(
+ '$TERM differs from the tmux `default-terminal` setting. Colors might look wrong.',
+ { '$TERM may have been set by some rc (.bashrc, .zshrc, ...).' }
+ )
+ elseif not vim.regex([[\v(tmux-256color|screen-256color)]]):match_str(vim.env.TERM) then
+ health.report_error(
+ '$TERM should be "screen-256color" or "tmux-256color" in tmux. Colors might look wrong.',
+ {
+ 'Set default-terminal in ~/.tmux.conf:\nset-option -g default-terminal "screen-256color"',
+ suggest_faq,
+ }
+ )
+ end
+
+ -- check for RGB capabilities
+ local info = vim.fn.system({ 'tmux', 'display-message', '-p', '#{client_termfeatures}' })
+ info = vim.split(vim.trim(info), ',', { trimempty = true })
+ if not vim.tbl_contains(info, 'RGB') then
+ local has_rgb = false
+ if #info == 0 then
+ -- client_termfeatures may not be supported; fallback to checking show-messages
+ info = vim.fn.system({ 'tmux', 'show-messages', '-JT' })
+ has_rgb = info:find(' Tc: (flag) true', 1, true) or info:find(' RGB: (flag) true', 1, true)
+ end
+ if not has_rgb then
+ health.report_warn(
+ "Neither Tc nor RGB capability set. True colors are disabled. |'termguicolors'| won't work properly.",
+ {
+ "Put this in your ~/.tmux.conf and replace XXX by your $TERM outside of tmux:\nset-option -sa terminal-features ',XXX:RGB'",
+ "For older tmux versions use this instead:\nset-option -ga terminal-overrides ',XXX:Tc'",
+ }
+ )
+ end
+ end
end
local function check_terminal()
- vim.api.nvim_exec(
- [=[
- func! s:check_terminal() abort
- if !executable('infocmp')
- return
- endif
- call health#report_start('terminal')
- let cmd = 'infocmp -L'
- let out = system(split(cmd))
- let kbs_entry = matchstr(out, 'key_backspace=[^,[:space:]]*')
- let kdch1_entry = matchstr(out, 'key_dc=[^,[:space:]]*')
-
- if v:shell_error
- \ && (!has('win32')
- \ || empty(matchstr(out,
- \ 'infocmp: couldn''t open terminfo file .\+'
- \ ..'\%(conemu\|vtpcon\|win32con\)')))
- call health#report_error('command failed: '.cmd."\n".out)
- else
- call health#report_info(printf('key_backspace (kbs) terminfo entry: `%s`', (empty(kbs_entry) ? '? (not found)' : kbs_entry)))
- call health#report_info(printf('key_dc (kdch1) terminfo entry: `%s`', (empty(kbs_entry) ? '? (not found)' : kdch1_entry)))
- endif
- for env_var in ['XTERM_VERSION', 'VTE_VERSION', 'TERM_PROGRAM', 'COLORTERM', 'SSH_TTY']
- if exists('$'.env_var)
- call health#report_info(printf('$%s="%s"', env_var, eval('$'.env_var)))
- endif
- endfor
- endf
-
- call s:check_terminal()
- ]=],
- false
- )
+ if not executable('infocmp') then
+ return
+ end
+
+ health.report_start('terminal')
+ local cmd = 'infocmp -L'
+ local out = vim.fn.system(vim.fn.split(cmd))
+ local kbs_entry = vim.fn.matchstr(out, 'key_backspace=[^,[:space:]]*')
+ local kdch1_entry = vim.fn.matchstr(out, 'key_dc=[^,[:space:]]*')
+
+ if
+ shell_error()
+ and (
+ not has('win32')
+ or empty(
+ vim.fn.matchstr(
+ out,
+ [[infocmp: couldn't open terminfo file .\+\%(conemu\|vtpcon\|win32con\)]]
+ )
+ )
+ )
+ then
+ health.report_error('command failed: ' .. cmd .. '\n' .. out)
+ else
+ health.report_info(
+ vim.fn.printf(
+ 'key_backspace (kbs) terminfo entry: `%s`',
+ (empty(kbs_entry) and '? (not found)' or kbs_entry)
+ )
+ )
+
+ health.report_info(
+ vim.fn.printf(
+ 'key_dc (kdch1) terminfo entry: `%s`',
+ (empty(kbs_entry) and '? (not found)' or kdch1_entry)
+ )
+ )
+ end
+
+ for env_var in ipairs({ 'XTERM_VERSION', 'VTE_VERSION', 'TERM_PROGRAM', 'COLORTERM', 'SSH_TTY' }) do
+ if vim.env[env_var] then
+ health.report_info(vim.fn.printf('$%s="%s"', env_var, vim.env[env_var]))
+ end
+ end
end
function M.check()
diff --git a/runtime/lua/vim/_init_packages.lua b/runtime/lua/vim/_init_packages.lua
index 0c4ee8636d..e3a442af5e 100644
--- a/runtime/lua/vim/_init_packages.lua
+++ b/runtime/lua/vim/_init_packages.lua
@@ -42,8 +42,11 @@ function vim._load_package(name)
return nil
end
--- Insert vim._load_package after the preloader at position 2
-table.insert(package.loaders, 2, vim._load_package)
+-- TODO(bfredl): dedicated state for this?
+if vim.api then
+ -- Insert vim._load_package after the preloader at position 2
+ table.insert(package.loaders, 2, vim._load_package)
+end
-- builtin functions which always should be available
require('vim.shared')
@@ -78,6 +81,6 @@ function vim.empty_dict()
end
-- only on main thread: functions for interacting with editor state
-if not vim.is_thread() then
+if vim.api and not vim.is_thread() then
require('vim._editor')
end
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index b73519f1be..d1a84fcecf 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -190,6 +190,7 @@ local extension = {
BUILD = 'bzl',
qc = 'c',
cabal = 'cabal',
+ capnp = 'capnp',
cdl = 'cdl',
toc = 'cdrtoc',
cfc = 'cf',
@@ -225,6 +226,7 @@ local extension = {
hook = function(path, bufnr)
return M.getlines(bufnr, 1) == '[Trigger]' and 'conf'
end,
+ nmconnection = 'confini',
mklx = 'context',
mkiv = 'context',
mkii = 'context',
@@ -330,6 +332,7 @@ local extension = {
am = 'elf',
exs = 'elixir',
elm = 'elm',
+ lc = 'elsa',
elv = 'elvish',
ent = function(path, bufnr)
return require('vim.filetype.detect').ent(bufnr)
@@ -566,6 +569,7 @@ local extension = {
libsonnet = 'jsonnet',
jsp = 'jsp',
jl = 'julia',
+ kdl = 'kdl',
kv = 'kivy',
kix = 'kix',
kts = 'kotlin',
@@ -1021,6 +1025,7 @@ local extension = {
texinfo = 'texinfo',
text = 'text',
tfvars = 'terraform-vars',
+ thrift = 'thrift',
tla = 'tla',
tli = 'tli',
toml = 'toml',
@@ -1459,6 +1464,7 @@ local filename = {
['Pipfile.lock'] = 'json',
['.firebaserc'] = 'json',
['.prettierrc'] = 'json',
+ ['.stylelintrc'] = 'json',
['.babelrc'] = 'jsonc',
['.eslintrc'] = 'jsonc',
['.hintrc'] = 'jsonc',
@@ -1694,6 +1700,7 @@ local filename = {
fglrxrc = 'xml',
['/etc/blkid.tab'] = 'xml',
['/etc/blkid.tab.old'] = 'xml',
+ ['.clangd'] = 'yaml',
['.clang-format'] = 'yaml',
['.clang-tidy'] = 'yaml',
['/etc/zprofile'] = 'zsh',
diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua
index 65e6ca677c..a0d2c4c339 100644
--- a/runtime/lua/vim/fs.lua
+++ b/runtime/lua/vim/fs.lua
@@ -282,7 +282,7 @@ end
---
--- Examples:
--- <pre>lua
---- vim.fs.normalize('C:\\Users\\jdoe')
+--- vim.fs.normalize('C:\\\\Users\\\\jdoe')
--- --> 'C:/Users/jdoe'
---
--- vim.fs.normalize('~/src/neovim')
diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua
index b875da0abc..044880e076 100644
--- a/runtime/lua/vim/health.lua
+++ b/runtime/lua/vim/health.lua
@@ -23,7 +23,20 @@ end
local path2name = function(path)
if path:match('%.lua$') then
-- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
- return path:gsub('.-lua[%\\%/]', '', 1):gsub('[%\\%/]', '.'):gsub('%.health.-$', '')
+
+ -- Get full path, make sure all slashes are '/'
+ path = vim.fs.normalize(path)
+
+ -- Remove everything up to the last /lua/ folder
+ path = path:gsub('^.*/lua/', '')
+
+ -- Remove the filename (health.lua)
+ path = vim.fn.fnamemodify(path, ':h')
+
+ -- Change slashes to dots
+ path = path:gsub('/', '.')
+
+ return path
else
-- Vim: transform "../autoload/health/provider.vim" into "provider"
return vim.fn.fnamemodify(path, ':t:r')
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index cfd6c938f7..c5392ac154 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -897,115 +897,114 @@ end
--
--- Starts and initializes a client with the given configuration.
---
---- Parameter `cmd` is required.
----
---- The following parameters describe fields in the {config} table.
----
----
----@param cmd: (table|string|fun(dispatchers: table):table) command string or
---- list treated like |jobstart()|. The command must launch the language server
---- process. `cmd` can also be a function that creates an RPC client.
---- The function receives a dispatchers table and must return a table with the
---- functions `request`, `notify`, `is_closing` and `terminate`
---- See |vim.lsp.rpc.request()| and |vim.lsp.rpc.notify()|
---- For TCP there is a built-in rpc client factory: |vim.lsp.rpc.connect()|
----
----@param cmd_cwd: (string, default=|getcwd()|) Directory to launch
---- the `cmd` process. Not related to `root_dir`.
----
----@param cmd_env: (table) Environment flags to pass to the LSP on
---- spawn. Can be specified using keys like a map or as a list with `k=v`
---- pairs or both. Non-string values are coerced to string.
---- Example:
---- <pre>
---- { "PRODUCTION=true"; "TEST=123"; PORT = 8080; HOST = "0.0.0.0"; }
---- </pre>
----
----@param detached: (boolean, default true) Daemonize the server process so that it runs in a
---- separate process group from Nvim. Nvim will shutdown the process on exit, but if Nvim fails to
---- exit cleanly this could leave behind orphaned server processes.
----
----@param workspace_folders (table) List of workspace folders passed to the
---- language server. For backwards compatibility rootUri and rootPath will be
---- derived from the first workspace folder in this list. See `workspaceFolders` in
---- the LSP spec.
----
----@param capabilities Map overriding the default capabilities defined by
---- |vim.lsp.protocol.make_client_capabilities()|, passed to the language
---- server on initialization. Hint: use make_client_capabilities() and modify
---- its result.
---- - Note: To send an empty dictionary use
---- `{[vim.type_idx]=vim.types.dictionary}`, else it will be encoded as an
---- array.
+--- Field `cmd` in {config} is required.
+---
+---@param config (table) Configuration for the server:
+--- - cmd: (table|string|fun(dispatchers: table):table) command string or
+--- list treated like |jobstart()|. The command must launch the language server
+--- process. `cmd` can also be a function that creates an RPC client.
+--- The function receives a dispatchers table and must return a table with the
+--- functions `request`, `notify`, `is_closing` and `terminate`
+--- See |vim.lsp.rpc.request()| and |vim.lsp.rpc.notify()|
+--- For TCP there is a built-in rpc client factory: |vim.lsp.rpc.connect()|
+---
+--- - cmd_cwd: (string, default=|getcwd()|) Directory to launch
+--- the `cmd` process. Not related to `root_dir`.
+---
+--- - cmd_env: (table) Environment flags to pass to the LSP on
+--- spawn. Can be specified using keys like a map or as a list with `k=v`
+--- pairs or both. Non-string values are coerced to string.
+--- Example:
+--- <pre>
+--- { "PRODUCTION=true"; "TEST=123"; PORT = 8080; HOST = "0.0.0.0"; }
+--- </pre>
+---
+--- - detached: (boolean, default true) Daemonize the server process so that it runs in a
+--- separate process group from Nvim. Nvim will shutdown the process on exit, but if Nvim fails to
+--- exit cleanly this could leave behind orphaned server processes.
+---
+--- - workspace_folders: (table) List of workspace folders passed to the
+--- language server. For backwards compatibility rootUri and rootPath will be
+--- derived from the first workspace folder in this list. See `workspaceFolders` in
+--- the LSP spec.
+---
+--- - capabilities: Map overriding the default capabilities defined by
+--- |vim.lsp.protocol.make_client_capabilities()|, passed to the language
+--- server on initialization. Hint: use make_client_capabilities() and modify
+--- its result.
+--- - Note: To send an empty dictionary use
+--- `{[vim.type_idx]=vim.types.dictionary}`, else it will be encoded as an
+--- array.
+---
+--- - handlers: Map of language server method names to |lsp-handler|
+---
+--- - settings: Map with language server specific settings. These are
+--- returned to the language server if requested via `workspace/configuration`.
+--- Keys are case-sensitive.
+---
+--- - commands: table Table that maps string of clientside commands to user-defined functions.
+--- Commands passed to start_client take precedence over the global command registry. Each key
+--- must be a unique command name, and the value is a function which is called if any LSP action
+--- (code action, code lenses, ...) triggers the command.
+---
+--- - init_options Values to pass in the initialization request
+--- as `initializationOptions`. See `initialize` in the LSP spec.
+---
+--- - name: (string, default=client-id) Name in log messages.
+---
+--- - get_language_id: function(bufnr, filetype) -> language ID as string.
+--- Defaults to the filetype.
+---
+--- - offset_encoding: (default="utf-16") One of "utf-8", "utf-16",
+--- or "utf-32" which is the encoding that the LSP server expects. Client does
+--- not verify this is correct.
+---
+--- - on_error: Callback with parameters (code, ...), invoked
+--- when the client operation throws an error. `code` is a number describing
+--- the error. Other arguments may be passed depending on the error kind. See
+--- `vim.lsp.rpc.client_errors` for possible errors.
+--- Use `vim.lsp.rpc.client_errors[code]` to get human-friendly name.
+---
+--- - before_init: Callback with parameters (initialize_params, config)
+--- invoked before the LSP "initialize" phase, where `params` contains the
+--- parameters being sent to the server and `config` is the config that was
+--- passed to |vim.lsp.start_client()|. You can use this to modify parameters before
+--- they are sent.
+---
+--- - on_init: Callback (client, initialize_result) invoked after LSP
+--- "initialize", where `result` is a table of `capabilities` and anything else
+--- the server may send. For example, clangd sends
+--- `initialize_result.offsetEncoding` if `capabilities.offsetEncoding` was
+--- sent to it. You can only modify the `client.offset_encoding` here before
+--- any notifications are sent. Most language servers expect to be sent client specified settings after
+--- initialization. Neovim does not make this assumption. A
+--- `workspace/didChangeConfiguration` notification should be sent
+--- to the server during on_init.
+---
+--- - on_exit Callback (code, signal, client_id) invoked on client
+--- exit.
+--- - code: exit code of the process
+--- - signal: number describing the signal used to terminate (if any)
+--- - client_id: client handle
---
----@param handlers Map of language server method names to |lsp-handler|
+--- - on_attach: Callback (client, bufnr) invoked when client
+--- attaches to a buffer.
---
----@param settings Map with language server specific settings. These are
---- returned to the language server if requested via `workspace/configuration`.
---- Keys are case-sensitive.
+--- - trace: ("off" | "messages" | "verbose" | nil) passed directly to the language
+--- server in the initialize request. Invalid/empty values will default to "off"
---
----@param commands table Table that maps string of clientside commands to user-defined functions.
---- Commands passed to start_client take precedence over the global command registry. Each key
---- must be a unique command name, and the value is a function which is called if any LSP action
---- (code action, code lenses, ...) triggers the command.
+--- - flags: A table with flags for the client. The current (experimental) flags are:
+--- - allow_incremental_sync (bool, default true): Allow using incremental sync for buffer edits
+--- - debounce_text_changes (number, default 150): Debounce didChange
+--- notifications to the server by the given number in milliseconds. No debounce
+--- occurs if nil
+--- - exit_timeout (number|boolean, default false): Milliseconds to wait for server to
+--- exit cleanly after sending the "shutdown" request before sending kill -15.
+--- If set to false, nvim exits immediately after sending the "shutdown" request to the server.
---
----@param init_options Values to pass in the initialization request
---- as `initializationOptions`. See `initialize` in the LSP spec.
----
----@param name (string, default=client-id) Name in log messages.
----
----@param get_language_id function(bufnr, filetype) -> language ID as string.
---- Defaults to the filetype.
----
----@param offset_encoding (default="utf-16") One of "utf-8", "utf-16",
---- or "utf-32" which is the encoding that the LSP server expects. Client does
---- not verify this is correct.
----
----@param on_error Callback with parameters (code, ...), invoked
---- when the client operation throws an error. `code` is a number describing
---- the error. Other arguments may be passed depending on the error kind. See
---- `vim.lsp.rpc.client_errors` for possible errors.
---- Use `vim.lsp.rpc.client_errors[code]` to get human-friendly name.
----
----@param before_init Callback with parameters (initialize_params, config)
---- invoked before the LSP "initialize" phase, where `params` contains the
---- parameters being sent to the server and `config` is the config that was
---- passed to |vim.lsp.start_client()|. You can use this to modify parameters before
---- they are sent.
----
----@param on_init Callback (client, initialize_result) invoked after LSP
---- "initialize", where `result` is a table of `capabilities` and anything else
---- the server may send. For example, clangd sends
---- `initialize_result.offsetEncoding` if `capabilities.offsetEncoding` was
---- sent to it. You can only modify the `client.offset_encoding` here before
---- any notifications are sent. Most language servers expect to be sent client specified settings after
---- initialization. Neovim does not make this assumption. A
---- `workspace/didChangeConfiguration` notification should be sent
---- to the server during on_init.
----
----@param on_exit Callback (code, signal, client_id) invoked on client
---- exit.
---- - code: exit code of the process
---- - signal: number describing the signal used to terminate (if any)
---- - client_id: client handle
----
----@param on_attach Callback (client, bufnr) invoked when client
---- attaches to a buffer.
----
----@param trace: "off" | "messages" | "verbose" | nil passed directly to the language
---- server in the initialize request. Invalid/empty values will default to "off"
----@param flags: A table with flags for the client. The current (experimental) flags are:
---- - allow_incremental_sync (bool, default true): Allow using incremental sync for buffer edits
---- - debounce_text_changes (number, default 150): Debounce didChange
---- notifications to the server by the given number in milliseconds. No debounce
---- occurs if nil
---- - exit_timeout (number|boolean, default false): Milliseconds to wait for server to
---- exit cleanly after sending the "shutdown" request before sending kill -15.
---- If set to false, nvim exits immediately after sending the "shutdown" request to the server.
----
----@param root_dir string Directory where the LSP
---- server will base its workspaceFolders, rootUri, and rootPath
---- on initialization.
+--- - root_dir: (string) Directory where the LSP
+--- server will base its workspaceFolders, rootUri, and rootPath
+--- on initialization.
---
---@returns Client id. |vim.lsp.get_client_by_id()| Note: client may not be
--- fully initialized. Use `on_init` to do any actions once
@@ -1557,15 +1556,21 @@ end
--- Notify all attached clients that a buffer has changed.
local text_document_did_change_handler
do
- text_document_did_change_handler =
- function(_, bufnr, changedtick, firstline, lastline, new_lastline)
- -- Detach (nvim_buf_attach) via returning True to on_lines if no clients are attached
- if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then
- return true
- end
- util.buf_versions[bufnr] = changedtick
- changetracking.send_changes(bufnr, firstline, lastline, new_lastline)
+ text_document_did_change_handler = function(
+ _,
+ bufnr,
+ changedtick,
+ firstline,
+ lastline,
+ new_lastline
+ )
+ -- Detach (nvim_buf_attach) via returning True to on_lines if no clients are attached
+ if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then
+ return true
end
+ util.buf_versions[bufnr] = changedtick
+ changetracking.send_changes(bufnr, firstline, lastline, new_lastline)
+ end
end
---@private
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index 8f4bd15eaa..6ac885c78f 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -197,20 +197,21 @@ function M.format(options)
clients = vim.tbl_filter(options.filter, clients)
end
+ local mode = api.nvim_get_mode().mode
+ local range = options.range
+ if not range and mode == 'v' or mode == 'V' then
+ range = range_from_selection()
+ end
+ local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting'
+
clients = vim.tbl_filter(function(client)
- return client.supports_method('textDocument/formatting')
+ return client.supports_method(method)
end, clients)
if #clients == 0 then
vim.notify('[LSP] Format request failed, no matching language servers.')
end
- local mode = api.nvim_get_mode().mode
- local range = options.range
- if not range and mode == 'v' or mode == 'V' then
- range = range_from_selection()
- end
-
---@private
local function set_range(client, params)
if range then
@@ -221,7 +222,6 @@ function M.format(options)
return params
end
- local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting'
if options.async then
local do_format
do_format = function(idx, client)
@@ -487,7 +487,7 @@ function M.add_workspace_folder(workspace_folder)
end
local params = util.make_workspace_params(
{ { uri = vim.uri_from_fname(workspace_folder), name = workspace_folder } },
- { {} }
+ {}
)
for _, client in pairs(vim.lsp.get_active_clients({ bufnr = 0 })) do
local found = false
@@ -733,6 +733,7 @@ end
--- List of LSP `CodeActionKind`s used to filter the code actions.
--- Most language servers support values like `refactor`
--- or `quickfix`.
+--- - triggerKind (number|nil): The reason why code actions were requested.
--- - filter: (function|nil)
--- Predicate taking an `CodeAction` and returning a boolean.
--- - apply: (boolean|nil)
@@ -746,6 +747,7 @@ end
--- using mark-like indexing. See |api-indexing|
---
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
+---@see vim.lsp.protocol.constants.CodeActionTriggerKind
function M.code_action(options)
validate({ options = { options, 't', true } })
options = options or {}
@@ -755,6 +757,9 @@ function M.code_action(options)
options = { options = options }
end
local context = options.context or {}
+ if not context.triggerKind then
+ context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked
+ end
if not context.diagnostics then
local bufnr = api.nvim_get_current_buf()
context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(bufnr)
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index b383ca1c35..5096100a60 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -131,9 +131,10 @@ end
--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
M['workspace/applyEdit'] = function(_, workspace_edit, ctx)
- if not workspace_edit then
- return
- end
+ assert(
+ workspace_edit,
+ 'workspace/applyEdit must be called with `ApplyWorkspaceEditParams`. Server is violating the specification'
+ )
-- TODO(ashkan) Do something more with label?
local client_id = ctx.client_id
local client = vim.lsp.get_client_by_id(client_id)
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index 92cda0b34f..12345b6c8c 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -304,6 +304,17 @@ local constants = {
-- Base kind for an organize imports source action
SourceOrganizeImports = 'source.organizeImports',
},
+ -- The reason why code actions were requested.
+ ---@enum lsp.CodeActionTriggerKind
+ CodeActionTriggerKind = {
+ -- Code actions were explicitly requested by the user or by an extension.
+ Invoked = 1,
+ -- Code actions were requested automatically.
+ --
+ -- This typically happens when current selection in a file changes, but can
+ -- also be triggered when file content changes.
+ Automatic = 2,
+ },
}
for k, v in pairs(constants) do
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index b53c66ba63..cc48e3f193 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -60,6 +60,7 @@ end)()
--- Splits a string at each instance of a separator.
---
---@see |vim.split()|
+---@see |luaref-patterns|
---@see https://www.lua.org/pil/20.2.html
---@see http://lua-users.org/wiki/StringLibraryTutorial
---
@@ -457,6 +458,33 @@ function vim.tbl_flatten(t)
return result
end
+--- Enumerate a table sorted by its keys.
+---
+---@see Based on https://github.com/premake/premake-core/blob/master/src/base/table.lua
+---
+---@param t table List-like table
+---@return iterator over sorted keys and their values
+function vim.spairs(t)
+ assert(type(t) == 'table', string.format('Expected table, got %s', type(t)))
+
+ -- collect the keys
+ local keys = {}
+ for k in pairs(t) do
+ table.insert(keys, k)
+ end
+ table.sort(keys)
+
+ -- Return the iterator function.
+ -- TODO(justinmk): Return "iterator function, table {t}, and nil", like pairs()?
+ local i = 0
+ return function()
+ i = i + 1
+ if keys[i] then
+ return keys[i], t[keys[i]]
+ end
+ end
+end
+
--- Tests if a Lua table can be treated as an array.
---
--- Empty table `{}` is assumed to be an array, unless it was created by
@@ -529,6 +557,7 @@ end
--- Trim whitespace (Lua pattern "%s") from both sides of a string.
---
+---@see |luaref-patterns|
---@see https://www.lua.org/pil/20.2.html
---@param s string String to trim
---@return string String with whitespace removed from its beginning and end
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index e99994c8a9..d77a0d0d03 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -88,7 +88,6 @@ function TSHighlighter.new(tree, opts)
end
end
- self.orig_syntax = vim.bo[self.bufnr].syntax
self.orig_spelloptions = vim.bo[self.bufnr].spelloptions
vim.bo[self.bufnr].syntax = ''
@@ -120,8 +119,11 @@ function TSHighlighter:destroy()
end
if vim.api.nvim_buf_is_loaded(self.bufnr) then
- vim.bo[self.bufnr].syntax = self.orig_syntax
vim.bo[self.bufnr].spelloptions = self.orig_spelloptions
+ vim.b[self.bufnr].ts_highlight = nil
+ if vim.g.syntax_on == 1 then
+ a.nvim_exec_autocmds('FileType', { group = 'syntaxset', buffer = self.bufnr })
+ end
end
end
diff --git a/runtime/lua/vim/treesitter/language.lua b/runtime/lua/vim/treesitter/language.lua
index c92d63b8c4..8634e53b7b 100644
--- a/runtime/lua/vim/treesitter/language.lua
+++ b/runtime/lua/vim/treesitter/language.lua
@@ -6,7 +6,7 @@ local M = {}
---
--- Parsers are searched in the `parser` runtime directory, or the provided {path}
---
----@param lang string Language the parser should parse
+---@param lang string Language the parser should parse (alphanumerical and `_` only)
---@param path (string|nil) Optional path the parser is located at
---@param silent (boolean|nil) Don't throw an error if language not found
---@param symbol_name (string|nil) Internal symbol name for the language to load
@@ -16,13 +16,19 @@ function M.require_language(lang, path, silent, symbol_name)
return true
end
if path == nil then
- local fname = 'parser/' .. vim.fn.fnameescape(lang) .. '.*'
+ if not (lang and lang:match('[%w_]+') == lang) then
+ if silent then
+ return false
+ end
+ error("'" .. lang .. "' is not a valid language name")
+ end
+
+ local fname = 'parser/' .. lang .. '.*'
local paths = a.nvim_get_runtime_file(fname, false)
if #paths == 0 then
if silent then
return false
end
-
error("no parser for '" .. lang .. "' language, see :help treesitter-parsers")
end
path = paths[1]
diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua
index 4bec5db527..dbf134573d 100644
--- a/runtime/lua/vim/treesitter/query.lua
+++ b/runtime/lua/vim/treesitter/query.lua
@@ -419,7 +419,8 @@ local directive_handlers = {
--- Adds a new predicate to be used in queries
---
---@param name string Name of the predicate, without leading #
----@param handler function(match:string, pattern:string, bufnr:number, predicate:function)
+---@param handler function(match:table, pattern:string, bufnr:number, predicate:string[])
+--- - see |vim.treesitter.query.add_directive()| for argument meanings
function M.add_predicate(name, handler, force)
if predicate_handlers[name] and not force then
error(string.format('Overriding %s', name))
@@ -436,7 +437,12 @@ end
--- metadata table `metadata[capture_id].key = value`
---
---@param name string Name of the directive, without leading #
----@param handler function(match:string, pattern:string, bufnr:number, predicate:function, metadata:table)
+---@param handler function(match:table, pattern:string, bufnr:number, predicate:string[], metadata:table)
+--- - match: see |treesitter-query|
+--- - node-level data are accessible via `match[capture_id]`
+--- - pattern: see |treesitter-query|
+--- - predicate: list of strings containing the full directive being called, e.g.
+--- `(node (#set! conceal "-"))` would get the predicate `{ "#set!", "conceal", "-" }`
function M.add_directive(name, handler, force)
if directive_handlers[name] and not force then
error(string.format('Overriding %s', name))
diff --git a/runtime/nvim.appdata.xml b/runtime/nvim.appdata.xml
index 7411a7190a..7d2ea49df4 100644
--- a/runtime/nvim.appdata.xml
+++ b/runtime/nvim.appdata.xml
@@ -26,9 +26,12 @@
</screenshots>
<releases>
+ <release date="2023-02-02" version="0.8.3"/>
<release date="2022-12-29" version="0.8.2"/>
<release date="2022-11-14" version="0.8.1"/>
<release date="2022-09-30" version="0.8.0"/>
+ <release date="2022-06-26" version="0.7.2"/>
+ <release date="2022-06-26" version="0.7.1"/>
<release date="2022-04-15" version="0.7.0"/>
<release date="2021-12-31" version="0.6.1"/>
<release date="2021-11-30" version="0.6.0"/>
diff --git a/runtime/tutor/tutor.tutor.json b/runtime/tutor/tutor.tutor.json
index bf3eae8586..e8628e2f0e 100644
--- a/runtime/tutor/tutor.tutor.json
+++ b/runtime/tutor/tutor.tutor.json
@@ -2,8 +2,8 @@
"expect": {
"63": "This is text with **important information**",
"64": "This is text with **important information**",
- "71": "Document '&variable'",
- "72": "Document '&variable'",
+ "71": "TODO: Document '&variable'",
+ "72": "TODO: Document '&variable'",
"78": "# This is a level 1 header",
"79": "# This is a level 1 header",
"80": "### This is a level 3 header",