aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/api.txt36
-rw-r--r--runtime/doc/lsp.txt89
-rw-r--r--runtime/doc/options.txt10
-rw-r--r--runtime/doc/treesitter.txt14
-rw-r--r--runtime/filetype.vim5
-rw-r--r--runtime/lua/vim/lsp/util.lua52
-rw-r--r--src/nvim/lua/stdlib.c6
-rw-r--r--src/nvim/quickfix.c3
-rw-r--r--src/nvim/terminal.c13
-rw-r--r--src/nvim/testdir/test_filetype.vim3
-rw-r--r--test/functional/terminal/scrollback_spec.lua70
11 files changed, 244 insertions, 57 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index d2d010882e..8fb6290e50 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -1018,7 +1018,7 @@ nvim_get_mode() *nvim_get_mode()*
{fast}
nvim_get_option({name}) *nvim_get_option()*
- Gets an option value string.
+ Gets the global value of an option.
Parameters: ~
{name} Option name
@@ -1049,6 +1049,24 @@ nvim_get_option_info({name}) *nvim_get_option_info()*
Return: ~
Option Information
+nvim_get_option_value({name}, {*opts}) *nvim_get_option_value()*
+ Gets the value of an option. The behavior of this function
+ matches that of |:set|: the local value of an option is
+ returned if it exists; otherwise, the global value is
+ returned. Local values always correspond to the current buffer
+ or window. To get a buffer-local or window-local option for a
+ specific buffer or window, use |nvim_buf_get_option()| or
+ |nvim_win_get_option()|.
+
+ Parameters: ~
+ {name} Option name
+ {opts} Optional parameters
+ • scope: One of 'global' or 'local'. Analagous to
+ |:setglobal| and |:setlocal|, respectively.
+
+ Return: ~
+ Option value
+
nvim_get_proc({pid}) *nvim_get_proc()*
Gets info describing process `pid` .
@@ -1510,11 +1528,25 @@ nvim_set_keymap({mode}, {lhs}, {rhs}, {*opts}) *nvim_set_keymap()*
key is an error.
nvim_set_option({name}, {value}) *nvim_set_option()*
- Sets an option value.
+ Sets the global value of an option.
+
+ Parameters: ~
+ {name} Option name
+ {value} New option value
+
+ *nvim_set_option_value()*
+nvim_set_option_value({name}, {value}, {*opts})
+ Sets the value of an option. The behavior of this function
+ matches that of |:set|: for global-local options, both the
+ global and local value are set unless otherwise specified with
+ {scope}.
Parameters: ~
{name} Option name
{value} New option value
+ {opts} Optional parameters
+ • scope: One of 'global' or 'local'. Analagous to
+ |:setglobal| and |:setlocal|, respectively.
nvim_set_var({name}, {value}) *nvim_set_var()*
Sets a global (g:) variable.
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 11f9d62e69..3793a21f36 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -630,6 +630,12 @@ client() *vim.lsp.client*
server.
• {handlers} (table): The handlers used by the client as
described in |lsp-handler|.
+ • {requests} (table): The current pending requests in flight
+ to the server. Entries are key-value pairs with the key
+ being the request ID while the value is a table with
+ `type` , `bufnr` , and `method` key-value pairs. `type` is
+ either "pending" for an active request, or "cancel" for a
+ cancel request.
• {config} (table): copy of the table that was passed by the
user to |vim.lsp.start_client()|.
• {server_capabilities} (table): Response from the server
@@ -1326,12 +1332,14 @@ apply_text_document_edit({text_document_edit}, {index})
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit
*vim.lsp.util.apply_text_edits()*
-apply_text_edits({text_edits}, {bufnr})
+apply_text_edits({text_edits}, {bufnr}, {offset_encoding})
Applies a list of text edits to a buffer.
Parameters: ~
- {text_edits} table list of `TextEdit` objects
- {bufnr} number Buffer id
+ {text_edits} table list of `TextEdit` objects
+ {bufnr} number Buffer id
+ {offset_encoding} string utf-8|utf-16|utf-32|nil defaults
+ to encoding of first client of `bufnr`
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
@@ -1358,37 +1366,30 @@ buf_highlight_references({bufnr}, {references}, {offset_encoding})
{references} table List of `DocumentHighlight`
objects to highlight
{offset_encoding} string One of "utf-8", "utf-16",
- "utf-32", or nil. Defaults to utf-16
+ "utf-32", or nil. Defaults to
+ `offset_encoding` of first client of
+ `bufnr`
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#documentHighlight
*vim.lsp.util.character_offset()*
-character_offset({bufnr}, {row}, {col})
+character_offset({buf}, {row}, {col}, {offset_encoding})
Returns the UTF-32 and UTF-16 offsets for a position in a
certain buffer.
Parameters: ~
- {buf} buffer id (0 for current)
- {row} 0-indexed line
- {col} 0-indexed byte offset in line
+ {buf} buffer id (0 for current)
+ {row} 0-indexed line
+ {col} 0-indexed byte offset in line
+ {offset_encoding} string utf-8|utf-16|utf-32|nil defaults
+ to `offset_encoding` of first client of
+ `buf`
Return: ~
- (number, number) UTF-32 and UTF-16 index of the character
+ (number, number) `offset_encoding` index of the character
in line {row} column {col} in buffer {buf}
- *vim.lsp.util.close_preview_autocmd()*
-close_preview_autocmd({events}, {winnr})
- Creates autocommands to close a preview window when events
- happen.
-
- Parameters: ~
- {events} (table) list of events
- {winnr} (number) window id of preview window
-
- See also: ~
- |autocmd-events|
-
*vim.lsp.util.convert_input_to_markdown_lines()*
convert_input_to_markdown_lines({input}, {contents})
Converts any of `MarkedString` | `MarkedString[]` |
@@ -1528,47 +1529,73 @@ make_formatting_params({options})
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting
*vim.lsp.util.make_given_range_params()*
-make_given_range_params({start_pos}, {end_pos})
+make_given_range_params({start_pos}, {end_pos}, {bufnr}, {offset_encoding})
Using the given range in the current buffer, creates an object
that is similar to |vim.lsp.util.make_range_params()|.
Parameters: ~
- {start_pos} ({number, number}, optional) mark-indexed
- position. Defaults to the start of the last
- visual selection.
- {end_pos} ({number, number}, optional) mark-indexed
- position. Defaults to the end of the last
- visual selection.
+ {start_pos} ({number, number}, optional)
+ mark-indexed position. Defaults to the
+ start of the last visual selection.
+ {end_pos} ({number, number}, optional)
+ mark-indexed position. Defaults to the
+ end of the last visual selection.
+ {bufnr} (optional, number): buffer handle or 0
+ for current, defaults to current
+ {offset_encoding} string utf-8|utf-16|utf-32|nil defaults
+ to `offset_encoding` of first client of
+ `bufnr`
Return: ~
{ textDocument = { uri = `current_file_uri` }, range = {
start = `start_position` , end = `end_position` } }
-make_position_params() *vim.lsp.util.make_position_params()*
+ *vim.lsp.util.make_position_params()*
+make_position_params({window}, {offset_encoding})
Creates a `TextDocumentPositionParams` object for the current
buffer and cursor position.
+ Parameters: ~
+ {window} (optional, number): window handle or 0
+ for current, defaults to current
+ {offset_encoding} string utf-8|utf-16|utf-32|nil defaults
+ to `offset_encoding` of first client of
+ buffer of `window`
+
Return: ~
`TextDocumentPositionParams` object
See also: ~
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
-make_range_params() *vim.lsp.util.make_range_params()*
+ *vim.lsp.util.make_range_params()*
+make_range_params({window}, {offset_encoding})
Using the current position in the current buffer, creates an
object that can be used as a building block for several LSP
requests, such as `textDocument/codeAction` ,
`textDocument/colorPresentation` ,
`textDocument/rangeFormatting` .
+ Parameters: ~
+ {window} (optional, number): window handle or 0
+ for current, defaults to current
+ {offset_encoding} string utf-8|utf-16|utf-32|nil defaults
+ to `offset_encoding` of first client of
+ buffer of `window`
+
Return: ~
{ textDocument = { uri = `current_file_uri` }, range = {
start = `current_position` , end = `current_position` } }
-make_text_document_params() *vim.lsp.util.make_text_document_params()*
+ *vim.lsp.util.make_text_document_params()*
+make_text_document_params({bufnr})
Creates a `TextDocumentIdentifier` object for the current
buffer.
+ Parameters: ~
+ {bufnr} (optional, number): Buffer handle, defaults to
+ current
+
Return: ~
`TextDocumentIdentifier`
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 47633c750c..097cd38400 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3229,10 +3229,14 @@ A jump table for the options with a short description can be found at |Q_op|.
'inccommand' 'icm' string (default "nosplit")
global
- "nosplit": Shows the effects of a command incrementally, as you type.
- "split" : Also shows partial off-screen results in a preview window.
+ When nonempty, shows the effects of |:substitute|, |:smagic|, and
+ |:snomagic| as you type.
- Works for |:substitute|, |:smagic|, |:snomagic|. |hl-Substitute|
+ Possible values:
+ nosplit Shows the effects of a command incrementally in the
+ buffer.
+ split Like "nosplit", but also shows partial off-screen
+ results in a preview window.
If the preview is too slow (exceeds 'redrawtime') then 'inccommand' is
automatically disabled until |Command-line-mode| is done.
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index 08dc0583ac..8f7241dd46 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -421,9 +421,9 @@ get_node_text({node}, {source}) *get_node_text()*
Gets the text corresponding to a given node
Parameters: ~
- {node} the node
- {bsource} The buffer or string from which the node is
- extracted
+ {node} the node
+ {source} The buffer or string from which the node is
+ extracted
get_query({lang}, {query_name}) *get_query()*
Returns the runtime query {query_name} for {lang}.
@@ -530,11 +530,9 @@ Query:iter_matches({self}, {node}, {source}, {start}, {stop})
for id, node in pairs(match) do
local name = query.captures[id]
-- `node` was captured by the `name` capture in the match
-<
->
- local node_data = metadata[id] -- Node level metadata
-<
->
+
+ local node_data = metadata[id] -- Node level metadata
+
... use the info here ...
end
end
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index b93263eb6d..806748b7cb 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -256,7 +256,7 @@ au BufNewFile,BufRead *.lpc,*.ulpc setf lpc
au BufNewFile,BufRead calendar setf calendar
" C#
-au BufNewFile,BufRead *.cs setf cs
+au BufNewFile,BufRead *.cs,*.csx setf cs
" CSDL
au BufNewFile,BufRead *.csdl setf csdl
@@ -1739,6 +1739,9 @@ au BufNewFile,BufRead *.speedup,*.spdata,*.spd setf spup
" Slice
au BufNewFile,BufRead *.ice setf slice
+" Microsoft Visual Studio Solution
+au BufNewFile,BufRead *.sln setf solution
+
" Spice
au BufNewFile,BufRead *.sp,*.spice setf spice
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index b11925df53..68a030d50b 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1253,17 +1253,57 @@ function M.stylize_markdown(bufnr, contents, opts)
return stripped
end
+---@private
--- Creates autocommands to close a preview window when events happen.
---
----@param events (table) list of events
----@param winnr (number) window id of preview window
+---@param events table list of events
+---@param winnr number window id of preview window
+---@param bufnrs table list of buffers where the preview window will remain visible
---@see |autocmd-events|
-function M.close_preview_autocmd(events, winnr)
+local function close_preview_autocmd(events, winnr, bufnrs)
+ local augroup = 'preview_window_'..winnr
+
+ -- close the preview window when entered a buffer that is not
+ -- the floating window buffer or the buffer that spawned it
+ vim.cmd(string.format([[
+ augroup %s
+ autocmd!
+ autocmd BufEnter * lua vim.lsp.util._close_preview_window(%d, {%s})
+ augroup end
+ ]], augroup, winnr, table.concat(bufnrs, ',')))
+
if #events > 0 then
- api.nvim_command("autocmd "..table.concat(events, ',').." <buffer> ++once lua pcall(vim.api.nvim_win_close, "..winnr..", true)")
+ vim.cmd(string.format([[
+ augroup %s
+ autocmd %s <buffer> lua vim.lsp.util._close_preview_window(%d)
+ augroup end
+ ]], augroup, table.concat(events, ','), winnr))
end
end
+---@private
+--- Closes the preview window
+---
+---@param winnr number window id of preview window
+---@param bufnrs table|nil optional list of ignored buffers
+function M._close_preview_window(winnr, bufnrs)
+ vim.schedule(function()
+ -- exit if we are in one of ignored buffers
+ if bufnrs and vim.tbl_contains(bufnrs, api.nvim_get_current_buf()) then
+ return
+ end
+
+ local augroup = 'preview_window_'..winnr
+ vim.cmd(string.format([[
+ augroup %s
+ autocmd!
+ augroup end
+ augroup! %s
+ ]], augroup, augroup))
+ pcall(vim.api.nvim_win_close, winnr, true)
+ end)
+end
+
---@internal
--- Computes size of float needed to show contents (with optional wrapping)
---
@@ -1370,7 +1410,7 @@ function M.open_floating_preview(contents, syntax, opts)
opts.wrap = opts.wrap ~= false -- wrapping by default
opts.stylize_markdown = opts.stylize_markdown ~= false
opts.focus = opts.focus ~= false
- opts.close_events = opts.close_events or {"CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre"}
+ opts.close_events = opts.close_events or {"CursorMoved", "CursorMovedI", "InsertCharPre"}
local bufnr = api.nvim_get_current_buf()
@@ -1439,7 +1479,7 @@ function M.open_floating_preview(contents, syntax, opts)
api.nvim_buf_set_option(floating_bufnr, 'modifiable', false)
api.nvim_buf_set_option(floating_bufnr, 'bufhidden', 'wipe')
api.nvim_buf_set_keymap(floating_bufnr, "n", "q", "<cmd>bdelete<cr>", {silent = true, noremap = true, nowait = true})
- M.close_preview_autocmd(opts.close_events, floating_winnr)
+ close_preview_autocmd(opts.close_events, floating_winnr, {floating_bufnr, bufnr})
-- save focus_id
if opts.focus_id then
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index b746e03625..0d6789317c 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -230,8 +230,8 @@ static int nlua_str_utf_start(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
if (offset < 0 || offset > (intptr_t)s1_len) {
return luaL_error(lstate, "index out of range");
}
- int tail_offset = mb_head_off((char_u *)s1, (char_u *)s1 + (char_u)offset - 1);
- lua_pushinteger(lstate, tail_offset);
+ int head_offset = mb_head_off((char_u *)s1, (char_u *)s1 + offset - 1);
+ lua_pushinteger(lstate, head_offset);
return 1;
}
@@ -250,7 +250,7 @@ static int nlua_str_utf_end(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
if (offset < 0 || offset > (intptr_t)s1_len) {
return luaL_error(lstate, "index out of range");
}
- int tail_offset = mb_tail_off((char_u *)s1, (char_u *)s1 + (char_u)offset - 1);
+ int tail_offset = mb_tail_off((char_u *)s1, (char_u *)s1 + offset - 1);
lua_pushinteger(lstate, tail_offset);
return 1;
}
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 2204e2a62a..32d0ebe8eb 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -657,7 +657,8 @@ static int qf_get_next_str_line(qfstate_T *state)
state->linebuf = IObuff;
state->linelen = len;
}
- STRLCPY(state->linebuf, p_str, state->linelen + 1);
+ memcpy(state->linebuf, p_str, state->linelen);
+ state->linebuf[state->linelen] = '\0';
// Increment using len in order to discard the rest of the line if it
// exceeds LINE_MAXLEN.
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 04068a3cb8..d97c24dcf7 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1466,6 +1466,17 @@ static void refresh_scrollback(Terminal *term, buf_T *buf)
int width, height;
vterm_get_size(term->vt, &height, &width);
+ // May still have pending scrollback after increase in terminal height if the
+ // scrollback wasn't refreshed in time; append these to the top of the buffer.
+ int row_offset = term->sb_pending;
+ while (term->sb_pending > 0 && buf->b_ml.ml_line_count < height) {
+ fetch_row(term, term->sb_pending - row_offset - 1, width);
+ ml_append(0, (uint8_t *)term->textbuf, 0, false);
+ appended_lines(0, 1);
+ term->sb_pending--;
+ }
+
+ row_offset -= term->sb_pending;
while (term->sb_pending > 0) {
// This means that either the window height has decreased or the screen
// became full and libvterm had to push all rows up. Convert the first
@@ -1476,7 +1487,7 @@ static void refresh_scrollback(Terminal *term, buf_T *buf)
ml_delete(1, false);
deleted_lines(1, 1);
}
- fetch_row(term, -term->sb_pending, width);
+ fetch_row(term, -term->sb_pending - row_offset, width);
int buf_index = (int)buf->b_ml.ml_line_count - height;
ml_append(buf_index, (uint8_t *)term->textbuf, 0, false);
appended_lines(buf_index, 1);
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 5d77db6c21..7ed9c68c96 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -117,7 +117,7 @@ let s:filename_checks = {
\ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'],
\ 'crm': ['file.crm'],
\ 'crontab': ['crontab', 'crontab.file', '/etc/cron.d/file', 'any/etc/cron.d/file'],
- \ 'cs': ['file.cs'],
+ \ 'cs': ['file.cs', 'file.csx'],
\ 'csc': ['file.csc'],
\ 'csdl': ['file.csdl'],
\ 'csp': ['file.csp', 'file.fdr'],
@@ -456,6 +456,7 @@ let s:filename_checks = {
\ 'skill': ['file.il', 'file.ils', 'file.cdf'],
\ 'slang': ['file.sl'],
\ 'slice': ['file.ice'],
+ \ 'solution': ['file.sln'],
\ 'slpconf': ['/etc/slp.conf', 'any/etc/slp.conf'],
\ 'slpreg': ['/etc/slp.reg', 'any/etc/slp.reg'],
\ 'slpspi': ['/etc/slp.spi', 'any/etc/slp.spi'],
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index b932c58430..11bdc73a47 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -12,6 +12,8 @@ local curbufmeths = helpers.curbufmeths
local nvim = helpers.nvim
local feed_data = thelpers.feed_data
local pcall_err = helpers.pcall_err
+local exec_lua = helpers.exec_lua
+local assert_alive = helpers.assert_alive
describe(':terminal scrollback', function()
local screen
@@ -527,3 +529,71 @@ describe("'scrollback' option", function()
end)
end)
+
+describe("pending scrollback line handling", function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(30, 7)
+ screen:attach()
+ screen:set_default_attr_ids {
+ [1] = {foreground = Screen.colors.Brown},
+ [2] = {reverse = true},
+ [3] = {bold = true},
+ }
+ end)
+
+ it("does not crash after setting 'number' #14891", function()
+ exec_lua [[
+ local a = vim.api
+ local buf = a.nvim_create_buf(true, true)
+ local chan = a.nvim_open_term(buf, {})
+ a.nvim_win_set_option(0, "number", true)
+ a.nvim_chan_send(chan, ("a\n"):rep(11) .. "a")
+ a.nvim_win_set_buf(0, buf)
+ ]]
+ screen:expect [[
+ {1: 1 }^a |
+ {1: 2 } a |
+ {1: 3 } a |
+ {1: 4 } a |
+ {1: 5 } a |
+ {1: 6 } a |
+ |
+ ]]
+ feed('G')
+ screen:expect [[
+ {1: 7 } a |
+ {1: 8 } a |
+ {1: 9 } a |
+ {1: 10 } a |
+ {1: 11 } a |
+ {1: 12 } ^a |
+ |
+ ]]
+ assert_alive()
+ end)
+
+ it("does not crash after nvim_buf_call #14891", function()
+ exec_lua [[
+ local a = vim.api
+ local bufnr = a.nvim_create_buf(false, true)
+ a.nvim_buf_call(bufnr, function()
+ vim.fn.termopen({"echo", ("hi\n"):rep(11)})
+ end)
+ a.nvim_win_set_buf(0, bufnr)
+ vim.cmd("startinsert")
+ ]]
+ screen:expect [[
+ hi |
+ hi |
+ hi |
+ |
+ |
+ [Process exited 0]{2: } |
+ {3:-- TERMINAL --} |
+ ]]
+ assert_alive()
+ end)
+end)