aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp.lua3
-rw-r--r--runtime/lua/vim/lsp/buf.lua79
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua2
-rw-r--r--src/nvim/screen.c6
-rw-r--r--test/functional/ui/decorations_spec.lua63
-rw-r--r--test/functional/ui/diff_spec.lua26
-rw-r--r--test/functional/ui/highlight_spec.lua18
7 files changed, 158 insertions, 39 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index dbbfd7d1d8..95bc4635b0 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -489,7 +489,8 @@ local function text_document_did_open_handler(bufnr, client)
-- Protect against a race where the buffer disappears
-- between `did_open_handler` and the scheduled function firing.
if vim.api.nvim_buf_is_valid(bufnr) then
- vim.lsp.diagnostic.redraw(bufnr, client.id)
+ local namespace = vim.lsp.diagnostic.get_namespace(client.id)
+ vim.diagnostic.show(namespace, bufnr)
end
end)
end
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index f02ebfb9dc..8e3ed9b002 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -116,31 +116,30 @@ end
--- asks the user to select one.
--
---@returns The client that the user selected or nil
-local function select_client(method)
- local clients = vim.tbl_values(vim.lsp.buf_get_clients());
- clients = vim.tbl_filter(function (client)
+local function select_client(method, on_choice)
+ validate {
+ on_choice = { on_choice, 'function', false },
+ }
+ local clients = vim.tbl_values(vim.lsp.buf_get_clients())
+ clients = vim.tbl_filter(function(client)
return client.supports_method(method)
end, clients)
-- better UX when choices are always in the same order (between restarts)
- table.sort(clients, function (a, b) return a.name < b.name end)
+ table.sort(clients, function(a, b)
+ return a.name < b.name
+ end)
if #clients > 1 then
- local choices = {}
- for k,v in pairs(clients) do
- table.insert(choices, string.format("%d %s", k, v.name))
- end
- local user_choice = vim.fn.confirm(
- "Select a language server:",
- table.concat(choices, "\n"),
- 0,
- "Question"
- )
- if user_choice == 0 then return nil end
- return clients[user_choice]
+ vim.ui.select(clients, {
+ prompt = 'Select a language server:',
+ format_item = function(client)
+ return client.name
+ end,
+ }, on_choice)
elseif #clients < 1 then
- return nil
+ on_choice(nil)
else
- return clients[1]
+ on_choice(clients[1])
end
end
@@ -152,11 +151,15 @@ end
--
---@see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
function M.formatting(options)
- local client = select_client("textDocument/formatting")
- if client == nil then return end
-
local params = util.make_formatting_params(options)
- return client.request("textDocument/formatting", params, nil, vim.api.nvim_get_current_buf())
+ local bufnr = vim.api.nvim_get_current_buf()
+ select_client('textDocument/formatting', function(client)
+ if client == nil then
+ return
+ end
+
+ return client.request('textDocument/formatting', params, nil, bufnr)
+ end)
end
--- Performs |vim.lsp.buf.formatting()| synchronously.
@@ -172,17 +175,20 @@ end
---@param timeout_ms (number) Request timeout
---@see |vim.lsp.buf.formatting_seq_sync|
function M.formatting_sync(options, timeout_ms)
- local client = select_client("textDocument/formatting")
- if client == nil then return end
-
local params = util.make_formatting_params(options)
local bufnr = vim.api.nvim_get_current_buf()
- local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
- if result and result.result then
- util.apply_text_edits(result.result, bufnr)
- elseif err then
- vim.notify("vim.lsp.buf.formatting_sync: " .. err, vim.log.levels.WARN)
- end
+ select_client('textDocument/formatting', function(client)
+ if client == nil then
+ return
+ end
+
+ local result, err = client.request_sync('textDocument/formatting', params, timeout_ms, bufnr)
+ if result and result.result then
+ util.apply_text_edits(result.result, bufnr)
+ elseif err then
+ vim.notify('vim.lsp.buf.formatting_sync: ' .. err, vim.log.levels.WARN)
+ end
+ end)
end
--- Formats the current buffer by sequentially requesting formatting from attached clients.
@@ -238,12 +244,15 @@ end
---@param end_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection.
function M.range_formatting(options, start_pos, end_pos)
- local client = select_client("textDocument/rangeFormatting")
- if client == nil then return end
-
local params = util.make_given_range_params(start_pos, end_pos)
params.options = util.make_formatting_params(options).options
- return client.request("textDocument/rangeFormatting", params)
+ select_client('textDocument/rangeFormatting', function(client)
+ if client == nil then
+ return
+ end
+
+ return client.request('textDocument/rangeFormatting', params)
+ end)
end
--- Renames all references to the symbol under the cursor.
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 075da41b23..7c807d9b6f 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -565,7 +565,7 @@ end
--- Redraw diagnostics for the given buffer and client
---
----@deprecated Prefer |vim.diagnostic.redraw()|
+---@deprecated Prefer |vim.diagnostic.show()|
---
--- This calls the "textDocument/publishDiagnostics" handler manually using
--- the cached diagnostics already received from the server. This can be useful
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index d015ef110e..a666b9c8b0 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -451,9 +451,11 @@ int update_screen(int type)
// reset cmdline_row now (may have been changed temporarily)
compute_cmdrow();
+ bool hl_changed = false;
// Check for changed highlighting
if (need_highlight_changed) {
highlight_changed();
+ hl_changed = true;
}
if (type == CLEAR) { // first clear screen
@@ -554,7 +556,7 @@ int update_screen(int type)
* buffer. Each buffer must only be done once.
*/
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- update_window_hl(wp, type >= NOT_VALID);
+ update_window_hl(wp, type >= NOT_VALID || hl_changed);
buf_T *buf = wp->w_buffer;
if (buf->b_mod_set) {
@@ -1692,7 +1694,7 @@ static void win_update(win_T *wp, Providers *providers)
if (eof) { // we hit the end of the file
wp->w_botline = buf->b_ml.ml_line_count + 1;
j = win_get_fill(wp, wp->w_botline);
- if (j > 0 && !wp->w_botfill) {
+ if (j > 0 && !wp->w_botfill && row < wp->w_grid.Rows) {
// Display filler text below last line. win_line() will check
// for ml_line_count+1 and only draw filler lines
foldinfo_T info = FOLDINFO_INIT;
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index dce6384b9b..1575cab591 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -1031,6 +1031,69 @@ if (h->n_buckets < new_n_buckets) { // expand
|
]]}
+ screen:try_resize(50, 11)
+ feed('gg')
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+
+ feed('G<C-E>')
+ screen:expect{grid=[[
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ Grugg |
+ |
+ ]]}
+
+ feed('gg')
+ screen:expect{grid=[[
+ ^if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ } |
+ |
+ ]]}
+
+ screen:try_resize(50, 12)
+ feed('G')
+ screen:expect{grid=[[
+ if (h->n_buckets < new_n_buckets) { // expand |
+ khkey_t *new_keys = (khkey_t *)krealloc((void *)|
+ h->keys, new_n_buckets * sizeof(khkey_t)); |
+ h->keys = new_keys; |
+ if (kh_is_map && val_size) { |
+ char *new_vals = krealloc( h->vals_buf, new_n_|
+ buckets * val_size); |
+ h->vals_buf = new_vals; |
+ } |
+ ^} |
+ Grugg |
+ |
+ ]]}
+
meths.buf_del_extmark(0, ns, id)
screen:expect{grid=[[
if (h->n_buckets < new_n_buckets) { // expand |
diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua
index 13949b0756..bd2692d19a 100644
--- a/test/functional/ui/diff_spec.lua
+++ b/test/functional/ui/diff_spec.lua
@@ -186,6 +186,19 @@ describe('Diff mode screen', function()
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
+
+ screen:try_resize(40, 9)
+ screen:expect([[
+ {1:+ }{5:^+-- 4 lines: 1···}{3:│}{1:+ }{5:+-- 4 lines: 1··}|
+ {1: }5 {3:│}{1: }5 |
+ {1: }6 {3:│}{1: }6 |
+ {1: }7 {3:│}{1: }7 |
+ {1: }8 {3:│}{1: }8 |
+ {1: }9 {3:│}{1: }9 |
+ {1: }10 {3:│}{1: }10 |
+ {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
+ |
+ ]])
end)
it('Add a line at the end of file 1', function()
@@ -232,6 +245,19 @@ describe('Diff mode screen', function()
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
+
+ screen:try_resize(40, 9)
+ screen:expect([[
+ {1:+ }{5:^+-- 4 lines: 1···}{3:│}{1:+ }{5:+-- 4 lines: 1··}|
+ {1: }5 {3:│}{1: }5 |
+ {1: }6 {3:│}{1: }6 |
+ {1: }7 {3:│}{1: }7 |
+ {1: }8 {3:│}{1: }8 |
+ {1: }9 {3:│}{1: }9 |
+ {1: }10 {3:│}{1: }10 |
+ {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
+ |
+ ]])
end)
it('Add a line in the middle of file 2, remove on at the end of file 1', function()
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index c00d30fe32..0983d0d4ad 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -276,6 +276,24 @@ describe('highlight defaults', function()
]], {[0] = {bold=true, foreground=Screen.colors.Blue}})
end)
+ it('linking updates window highlight immediately #16552', function()
+ screen:try_resize(53, 4)
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ |
+ ]], {[0] = {bold=true, foreground=Screen.colors.Blue}})
+ feed_command("hi NonTextAlt guifg=Red")
+ feed_command("hi! link NonText NonTextAlt")
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ :hi! link NonText NonTextAlt |
+ ]], {[0] = {foreground=Screen.colors.Red}})
+ end)
+
it('Cursor after `:hi clear|syntax reset` #6508', function()
command('highlight clear|syntax reset')
eq('guifg=bg guibg=fg', eval([[matchstr(execute('hi Cursor'), '\v(gui|cterm).*$')]]))