aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/autoload/man.vim12
-rw-r--r--runtime/doc/api.txt105
-rw-r--r--runtime/doc/diagnostic.txt113
-rw-r--r--runtime/doc/editing.txt11
-rw-r--r--runtime/doc/eval.txt11
-rw-r--r--runtime/doc/lsp.txt6
-rw-r--r--runtime/doc/lua.txt14
-rw-r--r--runtime/doc/options.txt6
-rw-r--r--runtime/doc/vim_diff.txt16
-rw-r--r--runtime/lua/vim/diagnostic.lua289
-rw-r--r--runtime/lua/vim/lsp.lua2
-rw-r--r--runtime/lua/vim/lsp/codelens.lua6
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua21
13 files changed, 356 insertions, 256 deletions
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim
index 4f132b6121..90d353f9de 100644
--- a/runtime/autoload/man.vim
+++ b/runtime/autoload/man.vim
@@ -197,13 +197,21 @@ function! s:extract_sect_and_name_ref(ref) abort
if empty(name)
throw 'manpage reference cannot contain only parentheses'
endif
- return ['', name]
+ return ['', s:spaces_to_underscores(name)]
endif
let left = split(ref, '(')
" see ':Man 3X curses' on why tolower.
" TODO(nhooyr) Not sure if this is portable across OSs
" but I have not seen a single uppercase section.
- return [tolower(split(left[1], ')')[0]), left[0]]
+ return [tolower(split(left[1], ')')[0]), s:spaces_to_underscores(left[0])]
+endfunction
+
+" replace spaces in a man page name with underscores
+" intended for PostgreSQL, which has man pages like 'CREATE_TABLE(7)';
+" while editing SQL source code, it's nice to visually select 'CREATE TABLE'
+" and hit 'K', which requires this transformation
+function! s:spaces_to_underscores(str)
+ return substitute(a:str, ' ', '_', 'g')
endfunction
function! s:get_path(sect, name) abort
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 1ad0a6883e..1573bec7ac 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -531,6 +531,20 @@ nvim__get_hl_defs({ns_id}) *nvim__get_hl_defs()*
nvim__get_lib_dir() *nvim__get_lib_dir()*
TODO: Documentation
+nvim__get_runtime({pat}, {all}, {*opts}) *nvim__get_runtime()*
+ Find files in runtime directories
+
+ Attributes: ~
+ {fast}
+
+ Parameters: ~
+ {pat} pattern of files to search for
+ {all} whether to return all matches or only the first
+ {options} is_lua: only search lua subdirs
+
+ Return: ~
+ list of absolute paths to the found files
+
nvim__id({obj}) *nvim__id()*
Returns object given as argument.
@@ -582,6 +596,9 @@ nvim__id_float({flt}) *nvim__id_float()*
nvim__inspect_cell({grid}, {row}, {col}) *nvim__inspect_cell()*
TODO: Documentation
+nvim__runtime_inspect() *nvim__runtime_inspect()*
+ TODO: Documentation
+
nvim__screenshot({path}) *nvim__screenshot()*
TODO: Documentation
@@ -802,6 +819,39 @@ nvim_eval({expr}) *nvim_eval()*
Return: ~
Evaluation result or expanded object
+nvim_eval_statusline({str}, {*opts}) *nvim_eval_statusline()*
+ Evaluates statusline string.
+
+ Attributes: ~
+ {fast}
+
+ Parameters: ~
+ {str} Statusline string (see 'statusline').
+ {opts} Optional parameters.
+ • winid: (number) |window-ID| of the window to use
+ as context for statusline.
+ • maxwidth: (number) Maximum width of statusline.
+ • fillchar: (string) Character to fill blank
+ spaces in the statusline (see 'fillchars').
+ • highlights: (boolean) Return highlight
+ information.
+ • use_tabline: (boolean) Evaluate tabline instead
+ of statusline. When |TRUE|, {winid} is ignored.
+
+ Return: ~
+ Dictionary containing statusline information, with these
+ keys:
+ • str: (string) Characters that will be displayed on the
+ statusline.
+ • width: (number) Display width of the statusline.
+ • highlights: Array containing highlight information of
+ the statusline. Only included when the "highlights" key
+ in {opts} is |TRUE|. Each element of the array is a
+ |Dictionary| with these keys:
+ • start: (number) Byte index (0-based) of first
+ character that uses the highlight.
+ • group: (string) Name of highlight group.
+
nvim_exec({src}, {output}) *nvim_exec()*
Executes Vimscript (multiline block of Ex-commands), like
anonymous |:source|.
@@ -1827,7 +1877,7 @@ nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()*
callbacks.
{opts} Optional parameters.
• on_lines: Lua callback invoked on change.
- Return`true`to detach. Args:
+ Return `true` to detach. Args:
• the string "lines"
• buffer handle
• b:changedtick
@@ -1843,7 +1893,7 @@ nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()*
• on_bytes: lua callback invoked on change.
This callback receives more granular
information about the change compared to
- on_lines. Return`true`to detach. Args:
+ on_lines. Return `true` to detach. Args:
• the string "bytes"
• buffer handle
• b:changedtick
@@ -2282,7 +2332,7 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts})
• hl_mode : control how highlights are combined
with the highlights of the text. Currently
only affects virt_text highlights, but might
- affect`hl_group`in later versions.
+ affect `hl_group` in later versions.
• "replace": only show the virt_text color.
This is the default
• "combine": combine with background text
@@ -2692,28 +2742,29 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
{buffer} Buffer to display, or 0 for current buffer
{enter} Enter the window (make it the current window)
{config} Map defining the window configuration. Keys:
- • `relative`: Sets the window layout to "floating", placed
- at (row,col) coordinates relative to:
+ • relative: Sets the window layout to
+ "floating", placed at (row,col) coordinates
+ relative to:
• "editor" The global editor grid
• "win" Window given by the `win` field, or
current window.
• "cursor" Cursor position in current window.
- • `win` : |window-ID| for relative="win".
- • `anchor`: Decides which corner of the float to place
- at (row,col):
+ • win: |window-ID| for relative="win".
+ • anchor: Decides which corner of the float to
+ place at (row,col):
• "NW" northwest (default)
• "NE" northeast
• "SW" southwest
• "SE" southeast
- • `width` : Window width (in character cells).
+ • width: Window width (in character cells).
Minimum of 1.
- • `height` : Window height (in character cells).
+ • height: Window height (in character cells).
Minimum of 1.
- • `bufpos`: Places float relative to buffer text (only
- when relative="win"). Takes a tuple of
- zero-indexed [line, column].`row`and`col`if given are applied relative to this
+ • bufpos: Places float relative to buffer text
+ (only when relative="win"). Takes a tuple of
+ zero-indexed [line, column]. `row` and `col` if given are applied relative to this
position, else they default to:
• `row=1` and `col=0` if `anchor` is "NW" or
"NE"
@@ -2721,19 +2772,19 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
"SE" (thus like a tooltip near the buffer
text).
- • `row` : Row position in units of "screen cell
+ • row: Row position in units of "screen cell
height", may be fractional.
- • `col` : Column position in units of "screen
- cell width", may be fractional.
- • `focusable` : Enable focus by user actions
+ • col: Column position in units of "screen cell
+ width", may be fractional.
+ • focusable: Enable focus by user actions
(wincmds, mouse events). Defaults to true.
Non-focusable windows can be entered by
|nvim_set_current_win()|.
- • `external` : GUI should display the window as
- an external top-level window. Currently
- accepts no other positioning configuration
- together with this.
- • `zindex`: Stacking order. floats with higher`zindex`go on top on floats with lower indices. Must
+ • external: GUI should display the window as an
+ external top-level window. Currently accepts
+ no other positioning configuration together
+ with this.
+ • zindex: Stacking order. floats with higher `zindex` go on top on floats with lower indices. Must
be larger than zero. The following screen
elements have hard-coded z-indices:
• 100: insert completion popupmenu
@@ -2744,7 +2795,7 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
are recommended, unless there is a good
reason to overshadow builtin elements.
- • `style`: Configure the appearance of the window.
+ • style: Configure the appearance of the window.
Currently only takes one non-empty value:
• "minimal" Nvim will display the window with
many UI options disabled. This is useful
@@ -2759,9 +2810,9 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
and clearing the |EndOfBuffer| region in
'winhighlight'.
- • `border`: Style of (optional) window border. This can
- either be a string or an array. The string
- values are
+ • border: Style of (optional) window border.
+ This can either be a string or an array. The
+ string values are
• "none": No border (default).
• "single": A single line box.
• "double": A double line box.
@@ -2791,7 +2842,7 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
It could also be specified by character: [
{"+", "MyCorner"}, {"x", "MyBorder"} ].
- • `noautocmd` : If true then no buffer-related
+ • noautocmd: If true then no buffer-related
autocommand events such as |BufEnter|,
|BufLeave| or |BufWinEnter| may fire from
calling this function.
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 17d317522b..4d1e5ac997 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -262,12 +262,12 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
For example, if a user enables virtual text globally with >
- vim.diagnostic.config({virt_text = true})
+ vim.diagnostic.config({virtual_text = true})
<
and a diagnostic producer sets diagnostics with >
- vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
+ vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
<
then virtual text will not be enabled for those diagnostics.
@@ -302,7 +302,7 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
• format: (function) A function that takes
a diagnostic as input and returns a
string. The return value is the text used
- to display the diagnostic. Example:>
+ to display the diagnostic. Example: >
function(diagnostic)
if diagnostic.severity == vim.diagnostic.severity.ERROR then
@@ -324,6 +324,18 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
Otherwise, all signs use the same
priority.
+ • float: Options for floating windows:
+ • severity: See |diagnostic-severity|.
+ • show_header: (boolean, default true) Show
+ "Diagnostics:" header
+ • source: (string) Include the diagnostic
+ source in the message. One of "always" or
+ "if_many".
+ • format: (function) A function that takes
+ a diagnostic as input and returns a
+ string. The return value is the text used
+ to display the diagnostic.
+
• update_in_insert: (default false) Update
diagnostics in Insert mode (if false,
diagnostics are updated on InsertLeave)
@@ -442,12 +454,10 @@ goto_next({opts}) *vim.diagnostic.goto_next()*
• wrap: (boolean, default true) Whether to loop
around file or not. Similar to 'wrapscan'.
• severity: See |diagnostic-severity|.
- • enable_popup: (boolean, default true) Call
- |vim.diagnostic.show_line_diagnostics()| on
- jump.
- • popup_opts: (table) Table to pass as {opts}
- parameter to
- |vim.diagnostic.show_line_diagnostics()|
+ • float: (boolean or table, default true) If
+ "true", call |vim.diagnostic.open_float()| after
+ moving. If a table, pass the table as the {opts}
+ parameter to |vim.diagnostic.open_float()|.
• win_id: (number, default 0) Window ID
goto_prev({opts}) *vim.diagnostic.goto_prev()*
@@ -508,6 +518,46 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
diagnostic |diagnostic-structure| or `nil` if {pat} fails
to match {str}.
+open_float({bufnr}, {opts}) *vim.diagnostic.open_float()*
+ Show diagnostics in a floating window.
+
+ Parameters: ~
+ {bufnr} number|nil Buffer number. Defaults to the current
+ buffer.
+ {opts} table|nil Configuration table with the same keys
+ as |vim.lsp.util.open_floating_preview()| in
+ addition to the following:
+ • namespace: (number) Limit diagnostics to the
+ given namespace
+ • scope: (string, default "buffer") Show
+ diagnostics from the whole buffer ("buffer"),
+ the current cursor line ("line"), or the
+ current cursor position ("cursor").
+ • pos: (number or table) If {scope} is "line" or
+ "cursor", use this position rather than the
+ cursor position. If a number, interpreted as a
+ line number; otherwise, a (row, col) tuple.
+ • severity_sort: (default false) Sort diagnostics
+ by severity. Overrides the setting from
+ |vim.diagnostic.config()|.
+ • severity: See |diagnostic-severity|. Overrides
+ the setting from |vim.diagnostic.config()|.
+ • show_header: (boolean, default true) Show
+ "Diagnostics:" header. Overrides the setting
+ from |vim.diagnostic.config()|.
+ • source: (string) Include the diagnostic source
+ in the message. One of "always" or "if_many".
+ Overrides the setting from
+ |vim.diagnostic.config()|.
+ • format: (function) A function that takes a
+ diagnostic as input and returns a string. The
+ return value is the text used to display the
+ diagnostic. Overrides the setting from
+ |vim.diagnostic.config()|.
+
+ Return: ~
+ tuple ({float_bufnr}, {win_id})
+
reset({namespace}, {bufnr}) *vim.diagnostic.reset()*
Remove all diagnostics from the given namespace.
@@ -581,51 +631,6 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
{opts} table|nil Display options. See
|vim.diagnostic.config()|.
- *vim.diagnostic.show_line_diagnostics()*
-show_line_diagnostics({opts}, {bufnr}, {lnum})
- Open a floating window with the diagnostics from the given
- line.
-
- Parameters: ~
- {opts} table Configuration table. See
- |vim.diagnostic.show_position_diagnostics()|.
- {bufnr} number|nil Buffer number. Defaults to the current
- buffer.
- {lnum} number|nil Line number. Defaults to line number
- of cursor.
-
- Return: ~
- tuple ({popup_bufnr}, {win_id})
-
- *vim.diagnostic.show_position_diagnostics()*
-show_position_diagnostics({opts}, {bufnr}, {position})
- Open a floating window with the diagnostics at the given
- position.
-
- Parameters: ~
- {opts} table|nil Configuration table with the same
- keys as |vim.lsp.util.open_floating_preview()|
- in addition to the following:
- • namespace: (number) Limit diagnostics to the
- given namespace
- • severity: See |diagnostic-severity|.
- • show_header: (boolean, default true) Show
- "Diagnostics:" header
- • source: (string) Include the diagnostic
- source in the message. One of "always" or
- "if_many".
- • format: (function) A function that takes a
- diagnostic as input and returns a string.
- The return value is the text used to display
- the diagnostic.
- {bufnr} number|nil Buffer number. Defaults to the
- current buffer.
- {position} table|nil The (0,0)-indexed position. Defaults
- to the current cursor position.
-
- Return: ~
- tuple ({popup_bufnr}, {win_id})
-
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
Convert a list of diagnostics to a list of quickfix items that
can be passed to |setqflist()| or |setloclist()|.
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index efba9020f9..4e3173cfa9 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -1331,11 +1331,12 @@ window the current directory is changed to the last specified local current
directory. If none was specified, the global or tab-local directory is used.
When changing tabs the same behaviour applies. If the current tab has no
-local working directory the global working directory is used. When a |:cd|
-command is used, the current window and tab will lose their local current
-directories and will use the global current directory from now on. When
-a |:tcd| command is used, only the current window will lose its local working
-directory.
+local working directory the global working directory is used.
+
+When a |:cd| command is used, the current window and tab will lose their local
+current directories and will use the global current directory from now on.
+When a |:tcd| command is used, only the current window will lose its local
+working directory.
After using |:cd| the full path name will be used for reading and writing
files. On some networked file systems this may cause problems. The result of
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 4467afaa16..6549d0b5f3 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2461,8 +2461,8 @@ globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
has({feature}) Number |TRUE| if feature {feature} supported
has_key({dict}, {key}) Number |TRUE| if {dict} has entry {key}
haslocaldir([{winnr} [, {tabnr}]])
- Number |TRUE| if current window executed |:lcd|
- or |:tcd|
+ Number |TRUE| if the window executed |:lcd| or
+ the tab executed |:tcd|
hasmapto({what} [, {mode} [, {abbr}]])
Number |TRUE| if mapping to {what} exists
histadd({history}, {item}) String add an item to a history
@@ -5012,6 +5012,7 @@ getcwd([{winnr}[, {tabnr}]]) *getcwd()*
{winnr} can be the window number or the |window-ID|.
If both {winnr} and {tabnr} are -1 the global working
directory is returned.
+ Throw error if the arguments are invalid. |E5000| |E5001| |E5002|
Can also be used as a |method|: >
GetWinnr()->getcwd()
@@ -5774,8 +5775,9 @@ has_key({dict}, {key}) *has_key()*
mydict->has_key(key)
haslocaldir([{winnr}[, {tabnr}]]) *haslocaldir()*
- The result is a Number, which is 1 when the tabpage or window
- has set a local path via |:tcd| or |:lcd|, otherwise 0.
+ The result is a Number, which is 1 when the window has set a
+ local path via |:lcd| or when {winnr} is -1 and the tabpage
+ has set a local path via |:tcd|, otherwise 0.
Tabs and windows are identified by their respective numbers,
0 means current tab or window. Missing argument implies 0.
@@ -5787,6 +5789,7 @@ haslocaldir([{winnr}[, {tabnr}]]) *haslocaldir()*
With {winnr} and {tabnr} use the window in that tabpage.
{winnr} can be the window number or the |window-ID|.
If {winnr} is -1 it is ignored, only the tab is resolved.
+ Throw error if the arguments are invalid. |E5000| |E5001| |E5002|
Can also be used as a |method|: >
GetWinnr()->haslocaldir()
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index ac797de92d..5549d3c180 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -628,6 +628,10 @@ client_is_stopped({client_id}) *vim.lsp.client_is_stopped()*
flush({client}) *vim.lsp.flush()*
TODO: Documentation
+ *vim.lsp.for_each_buffer_client()*
+for_each_buffer_client({bufnr}, {fn})
+ TODO: Documentation
+
get_active_clients() *vim.lsp.get_active_clients()*
Gets all active clients.
@@ -666,7 +670,7 @@ omnifunc({findstart}, {base}) *vim.lsp.omnifunc()*
{base} If findstart=0, text to match against
Return: ~
- (number) Decided by`findstart`:
+ (number) Decided by {findstart}:
• findstart=0: column where the completion starts, or -2
or -3
• findstart=1: list of matches (actually just calls
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index a6ccf9f35c..fe94e89e2a 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -928,6 +928,7 @@ Example: >
vim.g.foo = 5 -- Set the g:foo Vimscript variable.
print(vim.g.foo) -- Get and print the g:foo Vimscript variable.
vim.g.foo = nil -- Delete (:unlet) the Vimscript variable.
+ vim.b[2].foo = 6 -- Set b:foo for buffer 2
vim.g *vim.g*
Global (|g:|) editor variables.
@@ -935,15 +936,18 @@ vim.g *vim.g*
vim.b *vim.b*
Buffer-scoped (|b:|) variables for the current buffer.
- Invalid or unset key returns `nil`.
+ Invalid or unset key returns `nil`. Can be indexed with
+ an integer to access variables for a specific buffer.
vim.w *vim.w*
Window-scoped (|w:|) variables for the current window.
- Invalid or unset key returns `nil`.
+ Invalid or unset key returns `nil`. Can be indexed with
+ an integer to access variables for a specific window.
vim.t *vim.t*
Tabpage-scoped (|t:|) variables for the current tabpage.
- Invalid or unset key returns `nil`.
+ Invalid or unset key returns `nil`. Can be indexed with
+ an integer to access variables for a specific tabpage.
vim.v *vim.v*
|v:| variables.
@@ -1518,7 +1522,7 @@ tbl_flatten({t}) *vim.tbl_flatten()*
Flattened copy of the given list-like table.
See also: ~
- Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua
+ From https://github.com/premake/premake-core/blob/master/src/base/table.lua
tbl_isempty({t}) *vim.tbl_isempty()*
Checks if a table is empty.
@@ -1554,7 +1558,7 @@ tbl_keys({t}) *vim.tbl_keys()*
list of keys
See also: ~
- Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua
+ From https://github.com/premake/premake-core/blob/master/src/base/table.lua
tbl_map({func}, {t}) *vim.tbl_map()*
Apply a function to all values of a table.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 3520d40591..be397117b2 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1159,9 +1159,9 @@ A jump table for the options with a short description can be found at |Q_op|.
'cdpath' 'cd' string (default: equivalent to $CDPATH or ",,")
global
This is a list of directories which will be searched when using the
- |:cd| and |:lcd| commands, provided that the directory being searched
- for has a relative path, not an absolute part starting with "/", "./"
- or "../", the 'cdpath' option is not used then.
+ |:cd|, |:tcd| and |:lcd| commands, provided that the directory being
+ searched for has a relative path, not an absolute part starting with
+ "/", "./" or "../", the 'cdpath' option is not used then.
The 'cdpath' option's value has the same form and semantics as
|'path'|. Also see |file-searching|.
The default value is taken from $CDPATH, with a "," prepended to look
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 7e7bb7d62f..77bf1d29eb 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -180,7 +180,6 @@ Commands:
|:match| can be invoked before highlight group is defined
Events:
- |DirChanged| can be triggered when switching to another window
|Signal|
|TabNewEntered|
|TermClose|
@@ -197,10 +196,6 @@ Functions:
|stdpath()|
|system()|, |systemlist()| can run {cmd} directly (without 'shell')
|matchadd()| can be called before highlight group is defined
- |getcwd()| and |haslocaldir()| may throw errors. *E5000* *E5001* *E5002*
- |haslocaldir()|'s only possible return values are 0 and 1, it never returns 2.
- `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.
Highlight groups:
|highlight-blend| controls blend level for a highlight group
@@ -253,6 +248,8 @@ Variables:
Nvim always builds with all features, in contrast to Vim which may have
certain features removed/added at compile-time. |feature-compile|
+Some Vim features were changed in Nvim, and vice versa.
+
If a Python interpreter is available on your `$PATH`, |:python| and |:python3|
are always available and may be used simultaneously. See |provider-python|.
@@ -428,6 +425,15 @@ Vimscript compatibility:
`shell_error` does not alias to |v:shell_error|
`this_session` does not alias to |v:this_session|
+Working directory (Vim implemented some of these later than Nvim):
+- |DirChanged| can be triggered when switching to another window.
+- |getcwd()| and |haslocaldir()| may throw errors if the tab page or window
+ cannot be found. *E5000* *E5001* *E5002*
+- |haslocaldir()| only checks for tab-local directory when -1 is passed as
+ window number, and its only possible returns values are 0 and 1.
+- `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.
+
==============================================================================
5. Missing legacy features *nvim-features-missing*
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index 326932d982..4cf22282a2 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -19,6 +19,7 @@ local global_diagnostic_options = {
signs = true,
underline = true,
virtual_text = true,
+ float = true,
update_in_insert = false,
severity_sort = false,
}
@@ -119,8 +120,8 @@ end
---@private
local function enabled_value(option, namespace)
- local ns = get_namespace(namespace)
- if type(ns.opts[option]) == "table" then
+ local ns = namespace and get_namespace(namespace) or {}
+ if ns.opts and type(ns.opts[option]) == "table" then
return ns.opts[option]
end
@@ -153,8 +154,9 @@ end
---@private
local function get_resolved_options(opts, namespace, bufnr)
- local ns = get_namespace(namespace)
- local resolved = vim.tbl_extend('keep', opts or {}, ns.opts, global_diagnostic_options)
+ local ns = namespace and get_namespace(namespace) or {}
+ -- Do not use tbl_deep_extend so that an empty table can be used to reset to default values
+ local resolved = vim.tbl_extend('keep', opts or {}, ns.opts or {}, global_diagnostic_options)
for k in pairs(global_diagnostic_options) do
if resolved[k] ~= nil then
resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr)
@@ -354,19 +356,15 @@ local function schedule_display(namespace, bufnr, args)
local key = make_augroup_key(namespace, bufnr)
if not registered_autocmds[key] then
- vim.cmd(string.format("augroup %s", key))
- vim.cmd(" au!")
- vim.cmd(
- string.format(
- [[autocmd %s <buffer=%s> lua vim.diagnostic._execute_scheduled_display(%s, %s)]],
- table.concat(insert_leave_auto_cmds, ","),
- bufnr,
- namespace,
- bufnr
- )
- )
- vim.cmd("augroup END")
-
+ vim.cmd(string.format([[augroup %s
+ au!
+ autocmd %s <buffer=%s> lua vim.diagnostic._execute_scheduled_display(%s, %s)
+ augroup END]],
+ key,
+ table.concat(insert_leave_auto_cmds, ","),
+ bufnr,
+ namespace,
+ bufnr))
registered_autocmds[key] = true
end
end
@@ -376,77 +374,14 @@ local function clear_scheduled_display(namespace, bufnr)
local key = make_augroup_key(namespace, bufnr)
if registered_autocmds[key] then
- vim.cmd(string.format("augroup %s", key))
- vim.cmd(" au!")
- vim.cmd("augroup END")
-
+ vim.cmd(string.format([[augroup %s
+ au!
+ augroup END]], key))
registered_autocmds[key] = nil
end
end
---@private
---- Open a floating window with the provided diagnostics
----@param opts table Configuration table
---- - show_header (boolean, default true): Show "Diagnostics:" header
---- - all opts for |vim.util.open_floating_preview()| can be used here
----@param diagnostics table: The diagnostics to display
----@return table {popup_bufnr, win_id}
-local function show_diagnostics(opts, diagnostics)
- if not diagnostics or vim.tbl_isempty(diagnostics) then
- return
- end
- local lines = {}
- local highlights = {}
- local show_header = vim.F.if_nil(opts.show_header, true)
- if show_header then
- table.insert(lines, "Diagnostics:")
- table.insert(highlights, {0, "Bold"})
- end
-
- if opts.format then
- diagnostics = reformat_diagnostics(opts.format, diagnostics)
- end
-
- if opts.source then
- diagnostics = prefix_source(opts.source, diagnostics)
- end
-
- -- Use global setting for severity_sort since 'show_diagnostics' is namespace
- -- independent
- local severity_sort = global_diagnostic_options.severity_sort
- if severity_sort then
- if type(severity_sort) == "table" and severity_sort.reverse then
- table.sort(diagnostics, function(a, b) return a.severity > b.severity end)
- else
- table.sort(diagnostics, function(a, b) return a.severity < b.severity end)
- end
- end
-
- for i, diagnostic in ipairs(diagnostics) do
- local prefix = string.format("%d. ", i)
- local hiname = floating_highlight_map[diagnostic.severity]
- assert(hiname, 'unknown severity: ' .. tostring(diagnostic.severity))
-
- local message_lines = vim.split(diagnostic.message, '\n', true)
- table.insert(lines, prefix..message_lines[1])
- table.insert(highlights, {#prefix, hiname})
- for j = 2, #message_lines do
- table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
- table.insert(highlights, {0, hiname})
- end
- end
-
- local popup_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
- for i, hi in ipairs(highlights) do
- local prefixlen, hiname = unpack(hi)
- -- Start highlight after the prefix
- vim.api.nvim_buf_add_highlight(popup_bufnr, -1, hiname, i-1, prefixlen, -1)
- end
-
- return popup_bufnr, winnr
-end
-
----@private
local function set_list(loclist, opts)
opts = opts or {}
local open = vim.F.if_nil(opts.open, true)
@@ -469,6 +404,7 @@ local function set_list(loclist, opts)
end
---@private
+--- To (slightly) improve performance, modifies diagnostics in place.
local function clamp_line_numbers(bufnr, diagnostics)
local buf_line_count = vim.api.nvim_buf_line_count(bufnr)
if buf_line_count == 0 then
@@ -526,7 +462,7 @@ end
local function diagnostic_move_pos(opts, pos)
opts = opts or {}
- local enable_popup = vim.F.if_nil(opts.enable_popup, true)
+ local float = vim.F.if_nil(opts.float, true)
local win_id = opts.win_id or vim.api.nvim_get_current_win()
if not pos then
@@ -539,10 +475,13 @@ local function diagnostic_move_pos(opts, pos)
vim.api.nvim_win_set_cursor(win_id, {pos[1] + 1, pos[2]})
- if enable_popup then
- -- This is a bit weird... I'm surprised that we need to wait til the next tick to do this.
+ if float then
+ local float_opts = type(float) == "table" and float or {}
vim.schedule(function()
- M.show_position_diagnostics(opts.popup_opts, vim.api.nvim_win_get_buf(win_id))
+ M.open_float(
+ vim.api.nvim_win_get_buf(win_id),
+ vim.tbl_extend("keep", float_opts, {scope="cursor"})
+ )
end)
end
end
@@ -561,12 +500,12 @@ end
---
--- For example, if a user enables virtual text globally with
--- <pre>
---- vim.diagnostic.config({virt_text = true})
+--- vim.diagnostic.config({virtual_text = true})
--- </pre>
---
--- and a diagnostic producer sets diagnostics with
--- <pre>
---- vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
+--- vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
--- </pre>
---
--- then virtual text will not be enabled for those diagnostics.
@@ -603,6 +542,13 @@ end
--- * priority: (number, default 10) Base priority to use for signs. When
--- {severity_sort} is used, the priority of a sign is adjusted based on
--- its severity. Otherwise, all signs use the same priority.
+--- - float: Options for floating windows:
+--- * severity: See |diagnostic-severity|.
+--- * show_header: (boolean, default true) Show "Diagnostics:" header
+--- * source: (string) Include the diagnostic source in
+--- the message. One of "always" or "if_many".
+--- * format: (function) A function that takes a diagnostic as input and returns a
+--- string. The return value is the text used to display the diagnostic.
--- - update_in_insert: (default false) Update diagnostics in Insert mode (if false,
--- diagnostics are updated on InsertLeave)
--- - severity_sort: (default false) Sort diagnostics by severity. This affects the order in
@@ -825,10 +771,9 @@ end
--- |nvim_win_get_cursor()|. Defaults to the current cursor position.
--- - wrap: (boolean, default true) Whether to loop around file or not. Similar to 'wrapscan'.
--- - severity: See |diagnostic-severity|.
---- - enable_popup: (boolean, default true) Call |vim.diagnostic.show_line_diagnostics()|
---- on jump.
---- - popup_opts: (table) Table to pass as {opts} parameter to
---- |vim.diagnostic.show_line_diagnostics()|
+--- - float: (boolean or table, default true) If "true", call |vim.diagnostic.open_float()|
+--- after moving. If a table, pass the table as the {opts} parameter to
+--- |vim.diagnostic.open_float()|.
--- - win_id: (number, default 0) Window ID
function M.goto_next(opts)
return diagnostic_move_pos(
@@ -1144,68 +1089,136 @@ function M.show(namespace, bufnr, diagnostics, opts)
save_extmarks(namespace, bufnr)
end
---- Open a floating window with the diagnostics at the given position.
+--- Show diagnostics in a floating window.
---
+---@param bufnr number|nil Buffer number. Defaults to the current buffer.
---@param opts table|nil Configuration table with the same keys as
--- |vim.lsp.util.open_floating_preview()| in addition to the following:
--- - namespace: (number) Limit diagnostics to the given namespace
---- - severity: See |diagnostic-severity|.
---- - show_header: (boolean, default true) Show "Diagnostics:" header
---- - source: (string) Include the diagnostic source in
---- the message. One of "always" or "if_many".
+--- - scope: (string, default "buffer") Show diagnostics from the whole buffer ("buffer"),
+--- the current cursor line ("line"), or the current cursor position ("cursor").
+--- - pos: (number or table) If {scope} is "line" or "cursor", use this position rather
+--- than the cursor position. If a number, interpreted as a line number;
+--- otherwise, a (row, col) tuple.
+--- - severity_sort: (default false) Sort diagnostics by severity. Overrides the setting
+--- from |vim.diagnostic.config()|.
+--- - severity: See |diagnostic-severity|. Overrides the setting from
+--- |vim.diagnostic.config()|.
+--- - show_header: (boolean, default true) Show "Diagnostics:" header. Overrides the
+--- setting from |vim.diagnostic.config()|.
+--- - source: (string) Include the diagnostic source in the message. One of "always" or
+--- "if_many". Overrides the setting from |vim.diagnostic.config()|.
--- - format: (function) A function that takes a diagnostic as input and returns a
--- string. The return value is the text used to display the diagnostic.
----@param bufnr number|nil Buffer number. Defaults to the current buffer.
----@param position table|nil The (0,0)-indexed position. Defaults to the current cursor position.
----@return tuple ({popup_bufnr}, {win_id})
-function M.show_position_diagnostics(opts, bufnr, position)
+--- Overrides the setting from |vim.diagnostic.config()|.
+---@return tuple ({float_bufnr}, {win_id})
+function M.open_float(bufnr, opts)
vim.validate {
- opts = { opts, 't', true },
bufnr = { bufnr, 'n', true },
- position = { position, 't', true },
+ opts = { opts, 't', true },
}
opts = opts or {}
-
- opts.focus_id = "position_diagnostics"
bufnr = get_bufnr(bufnr)
- if not position then
- local curr_position = vim.api.nvim_win_get_cursor(0)
- curr_position[1] = curr_position[1] - 1
- position = curr_position
- end
- local match_position_predicate = function(diag)
- return position[1] == diag.lnum and
- position[2] >= diag.col and
- (position[2] <= diag.end_col or position[1] < diag.end_lnum)
+ local scope = opts.scope or "buffer"
+ local lnum, col
+ if scope == "line" or scope == "cursor" then
+ if not opts.pos then
+ local pos = vim.api.nvim_win_get_cursor(0)
+ lnum = pos[1] - 1
+ col = pos[2]
+ elseif type(opts.pos) == "number" then
+ lnum = opts.pos
+ elseif type(opts.pos) == "table" then
+ lnum, col = unpack(opts.pos)
+ else
+ error("Invalid value for option 'pos'")
+ end
+ elseif scope ~= "buffer" then
+ error("Invalid value for option 'scope'")
end
+
local diagnostics = M.get(bufnr, opts)
clamp_line_numbers(bufnr, diagnostics)
- local position_diagnostics = vim.tbl_filter(match_position_predicate, diagnostics)
- return show_diagnostics(opts, position_diagnostics)
-end
---- Open a floating window with the diagnostics from the given line.
----
----@param opts table Configuration table. See |vim.diagnostic.show_position_diagnostics()|.
----@param bufnr number|nil Buffer number. Defaults to the current buffer.
----@param lnum number|nil Line number. Defaults to line number of cursor.
----@return tuple ({popup_bufnr}, {win_id})
-function M.show_line_diagnostics(opts, bufnr, lnum)
- vim.validate {
- opts = { opts, 't', true },
- bufnr = { bufnr, 'n', true },
- lnum = { lnum, 'n', true },
- }
+ if scope == "line" then
+ diagnostics = vim.tbl_filter(function(d)
+ return d.lnum == lnum
+ end, diagnostics)
+ elseif scope == "cursor" then
+ -- LSP servers can send diagnostics with `end_col` past the length of the line
+ local line_length = #vim.api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1]
+ diagnostics = vim.tbl_filter(function(d)
+ return d.lnum == lnum
+ and math.min(d.col, line_length - 1) <= col
+ and (d.end_col >= col or d.end_lnum > lnum)
+ end, diagnostics)
+ end
- opts = opts or {}
- opts.focus_id = "line_diagnostics"
- bufnr = get_bufnr(bufnr)
- local diagnostics = M.get(bufnr, opts)
- clamp_line_numbers(bufnr, diagnostics)
- lnum = lnum or (vim.api.nvim_win_get_cursor(0)[1] - 1)
- local line_diagnostics = diagnostic_lines(diagnostics)[lnum]
- return show_diagnostics(opts, line_diagnostics)
+ if vim.tbl_isempty(diagnostics) then
+ return
+ end
+
+ local severity_sort = vim.F.if_nil(opts.severity_sort, global_diagnostic_options.severity_sort)
+ if severity_sort then
+ if type(severity_sort) == "table" and severity_sort.reverse then
+ table.sort(diagnostics, function(a, b) return a.severity > b.severity end)
+ else
+ table.sort(diagnostics, function(a, b) return a.severity < b.severity end)
+ end
+ end
+
+ do
+ -- Resolve options with user settings from vim.diagnostic.config
+ -- Unlike the other decoration functions (e.g. set_virtual_text, set_signs, etc.) `open_float`
+ -- does not have a dedicated table for configuration options; instead, the options are mixed in
+ -- with its `opts` table which also includes "keyword" parameters. So we create a dedicated
+ -- options table that inherits missing keys from the global configuration before resolving.
+ local t = global_diagnostic_options.float
+ local float_opts = vim.tbl_extend("keep", opts, type(t) == "table" and t or {})
+ opts = get_resolved_options({ float = float_opts }, nil, bufnr).float
+ end
+
+ local lines = {}
+ local highlights = {}
+ local show_header = vim.F.if_nil(opts.show_header, true)
+ if show_header then
+ table.insert(lines, "Diagnostics:")
+ table.insert(highlights, {0, "Bold"})
+ end
+
+ if opts.format then
+ diagnostics = reformat_diagnostics(opts.format, diagnostics)
+ end
+
+ if opts.source then
+ diagnostics = prefix_source(opts.source, diagnostics)
+ end
+
+ for i, diagnostic in ipairs(diagnostics) do
+ local prefix = string.format("%d. ", i)
+ local hiname = floating_highlight_map[diagnostic.severity]
+ local message_lines = vim.split(diagnostic.message, '\n')
+ table.insert(lines, prefix..message_lines[1])
+ table.insert(highlights, {#prefix, hiname})
+ for j = 2, #message_lines do
+ table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
+ table.insert(highlights, {0, hiname})
+ end
+ end
+
+ -- Used by open_floating_preview to allow the float to be focused
+ if not opts.focus_id then
+ opts.focus_id = scope
+ end
+ local float_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
+ for i, hi in ipairs(highlights) do
+ local prefixlen, hiname = unpack(hi)
+ -- Start highlight after the prefix
+ vim.api.nvim_buf_add_highlight(float_bufnr, -1, hiname, i-1, prefixlen, -1)
+ end
+
+ return float_bufnr, winnr
end
--- Remove all diagnostics from the given namespace.
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 9c35351608..ad6c90cd03 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -1430,7 +1430,7 @@ end
---@param findstart 0 or 1, decides behavior
---@param base If findstart=0, text to match against
---
----@returns (number) Decided by `findstart`:
+---@returns (number) Decided by {findstart}:
--- - findstart=0: column where the completion starts, or -2 or -3
--- - findstart=1: list of matches (actually just calls |complete()|)
function lsp.omnifunc(findstart, base)
diff --git a/runtime/lua/vim/lsp/codelens.lua b/runtime/lua/vim/lsp/codelens.lua
index 6d3912781e..63fcbe430b 100644
--- a/runtime/lua/vim/lsp/codelens.lua
+++ b/runtime/lua/vim/lsp/codelens.lua
@@ -138,7 +138,8 @@ function M.display(lenses, bufnr, client_id)
end
end
if #chunks > 0 then
- api.nvim_buf_set_extmark(bufnr, ns, i, 0, { virt_text = chunks })
+ api.nvim_buf_set_extmark(bufnr, ns, i, 0, { virt_text = chunks,
+ hl_mode="combine" })
end
end
end
@@ -199,7 +200,8 @@ local function resolve_lenses(lenses, bufnr, client_id, callback)
ns,
lens.range.start.line,
0,
- { virt_text = {{ lens.command.title, 'LspCodeLens' }} }
+ { virt_text = {{ lens.command.title, 'LspCodeLens' }},
+ hl_mode="combine" }
)
end
countdown()
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 0e63c0dd29..8fb7971c5a 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -551,14 +551,15 @@ end
---@param position table|nil The (0,0)-indexed position
---@return table {popup_bufnr, win_id}
function M.show_position_diagnostics(opts, buf_nr, position)
- if opts then
- if opts.severity then
- opts.severity = severity_lsp_to_vim(opts.severity)
- elseif opts.severity_limit then
- opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
- end
+ opts = opts or {}
+ opts.where = "cursor"
+ opts.pos = position
+ if opts.severity then
+ opts.severity = severity_lsp_to_vim(opts.severity)
+ elseif opts.severity_limit then
+ opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
end
- return vim.diagnostic.show_position_diagnostics(opts, buf_nr, position)
+ return vim.diagnostic.open_float(buf_nr, opts)
end
--- Open a floating window with the diagnostics from {line_nr}
@@ -573,11 +574,13 @@ end
---@param client_id number|nil the client id
---@return table {popup_bufnr, win_id}
function M.show_line_diagnostics(opts, buf_nr, line_nr, client_id)
+ opts = opts or {}
+ opts.where = "line"
+ opts.pos = line_nr
if client_id then
- opts = opts or {}
opts.namespace = M.get_namespace(client_id)
end
- return vim.diagnostic.show_line_diagnostics(opts, buf_nr, line_nr)
+ return vim.diagnostic.open_float(buf_nr, opts)
end
--- Redraw diagnostics for the given buffer and client