aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/help.txt5
-rw-r--r--runtime/doc/lsp.txt12
-rw-r--r--runtime/lua/vim/lsp/util.lua54
-rw-r--r--src/nvim/help.c8
-rw-r--r--test/functional/plugin/lsp_spec.lua32
5 files changed, 91 insertions, 20 deletions
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index 68c886887f..a1550d5c8b 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -169,8 +169,8 @@ DEVELOPING NVIM
|dev-style| Development style guidelines
|debug.txt| Debugging Vim itself
- *standard-plugin-list*
Standard plugins ~
+ *standard-plugin-list*
|matchit.txt| Extended |%| matching
|pi_gzip.txt| Reading and writing compressed files
|pi_health.txt| Healthcheck framework
@@ -181,7 +181,8 @@ Standard plugins ~
|pi_tar.txt| Tar file explorer
|pi_zip.txt| Zip archive explorer
-LOCAL ADDITIONS: *local-additions*
+Local additions ~
+ *local-additions*
------------------------------------------------------------------------------
*bars* Bars example
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index ca65251a9f..25293eb9b2 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -137,7 +137,19 @@ FAQ *lsp-faq*
" Auto-format *.rs (rust) files prior to saving them
" (async = false is the default for format)
autocmd BufWritePre *.rs lua vim.lsp.buf.format({ async = false })
+<
+- Q: How can I disable LSP formatting when using the |gq| command?
+ A: To use the default internal formatting method and bypass the LSP client's
+ 'formatexpr', use |gw| instead.
+ Alternatively you can completely disable LSP formatting with gq by
+ unsetting 'formatexpr':
+>lua
+ vim.api.nvim_create_autocmd('LspAttach', {
+ callback = function(args)
+ vim.bo[args.buf].formatexpr = nil
+ end,
+ })
<
*lsp-vs-treesitter*
- Q: How do LSP and Treesitter compare?
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 342fad33c2..48faddfce1 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -436,7 +436,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
-- Some LSP servers are depending on the VSCode behavior.
-- The VSCode will re-locate the cursor position after applying TextEdit so we also do it.
- local is_current_buf = api.nvim_get_current_buf() == bufnr
+ local is_current_buf = api.nvim_get_current_buf() == bufnr or bufnr == 0
local cursor = (function()
if not is_current_buf then
return {
@@ -464,7 +464,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
start_col = get_line_byte_from_position(bufnr, text_edit.range.start, offset_encoding),
end_row = text_edit.range['end'].line,
end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], offset_encoding),
- text = split(text_edit.newText, '\n', true),
+ text = split(text_edit.newText, '\n', { plain = true }),
}
local max = api.nvim_buf_line_count(bufnr)
@@ -522,7 +522,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
if is_cursor_fixed then
local is_valid_cursor = true
is_valid_cursor = is_valid_cursor and cursor.row < max
- is_valid_cursor = is_valid_cursor and cursor.col <= #(get_line(bufnr, max - 1) or '')
+ is_valid_cursor = is_valid_cursor and cursor.col <= #(get_line(bufnr, cursor.row) or '')
if is_valid_cursor then
api.nvim_win_set_cursor(0, { cursor.row + 1, cursor.col })
end
@@ -743,6 +743,20 @@ local function bufwinid(bufnr)
end
end
+--- Get list of buffers for a directory
+---@private
+local function get_dir_bufs(path)
+ path = path:gsub('([^%w])', '%%%1')
+ local buffers = {}
+ for _, v in ipairs(vim.api.nvim_list_bufs()) do
+ local bufname = vim.api.nvim_buf_get_name(v):gsub('buffer://', '')
+ if bufname:find(path) then
+ table.insert(buffers, v)
+ end
+ end
+ return buffers
+end
+
--- Rename old_fname to new_fname
---
---@param opts (table)
@@ -755,12 +769,22 @@ function M.rename(old_fname, new_fname, opts)
vim.notify('Rename target already exists. Skipping rename.')
return
end
- local oldbuf = vim.fn.bufadd(old_fname)
- vim.fn.bufload(oldbuf)
- -- The there may be pending changes in the buffer
- if vim.fn.isdirectory(old_fname) == 0 then
- api.nvim_buf_call(oldbuf, function()
+ local oldbufs = {}
+ local win = nil
+
+ if vim.fn.isdirectory(old_fname) == 1 then
+ oldbufs = get_dir_bufs(old_fname)
+ else
+ local oldbuf = vim.fn.bufadd(old_fname)
+ table.insert(oldbufs, oldbuf)
+ win = bufwinid(oldbuf)
+ end
+
+ for _, b in ipairs(oldbufs) do
+ vim.fn.bufload(b)
+ -- The there may be pending changes in the buffer
+ api.nvim_buf_call(b, function()
vim.cmd('w!')
end)
end
@@ -768,12 +792,16 @@ function M.rename(old_fname, new_fname, opts)
local ok, err = os.rename(old_fname, new_fname)
assert(ok, err)
- local newbuf = vim.fn.bufadd(new_fname)
- local win = bufwinid(oldbuf)
- if win then
- api.nvim_win_set_buf(win, newbuf)
+ if vim.fn.isdirectory(new_fname) == 0 then
+ local newbuf = vim.fn.bufadd(new_fname)
+ if win then
+ api.nvim_win_set_buf(win, newbuf)
+ end
+ end
+
+ for _, b in ipairs(oldbufs) do
+ api.nvim_buf_delete(b, {})
end
- api.nvim_buf_delete(oldbuf, { force = true })
end
---@private
diff --git a/src/nvim/help.c b/src/nvim/help.c
index 968f0bc2f4..728c890da4 100644
--- a/src/nvim/help.c
+++ b/src/nvim/help.c
@@ -10,6 +10,7 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
+#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
#include "nvim/ex_cmds.h"
@@ -699,6 +700,8 @@ void fix_help_buffer(void)
continue;
}
+ int lnum_start = lnum;
+
// Go through all directories in 'runtimepath', skipping
// $VIMRUNTIME.
char *p = p_rtp;
@@ -829,6 +832,11 @@ void fix_help_buffer(void)
}
xfree(rt);
}
+ linenr_T appended = lnum - lnum_start;
+ if (appended) {
+ mark_adjust(lnum_start + 1, (linenr_T)MAXLNUM, appended, 0L, kExtmarkUndo);
+ changed_lines_buf(curbuf, lnum_start + 1, lnum_start + 1, appended);
+ }
break;
}
}
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index a6e50ac82c..8b5e7d56ac 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -1714,6 +1714,9 @@ describe('LSP', function()
end)
it('fix the cursor col', function()
+ -- append empty last line. See #22636
+ exec_lua('vim.api.nvim_buf_set_lines(...)', 1, -1, -1, true, {''})
+
funcs.nvim_win_set_cursor(0, { 2, 11 })
local edits = {
make_edit(1, 7, 1, 11, '')
@@ -1725,6 +1728,7 @@ describe('LSP', function()
'Third line of text';
'Fourth line of text';
'å å ɧ 汉语 ↥ 🤦 🦄';
+ '';
}, buf_lines(1))
eq({ 2, 7 }, funcs.nvim_win_get_cursor(0))
end)
@@ -2196,7 +2200,22 @@ describe('LSP', function()
eq(true, exists)
os.remove(new)
end)
- it('Can rename a direcory', function()
+ it("Kills old buffer after renaming an existing file", function()
+ local old = helpers.tmpname()
+ write_file(old, 'Test content')
+ local new = helpers.tmpname()
+ os.remove(new) -- only reserve the name, file must not exist for the test scenario
+ local lines = exec_lua([[
+ local old = select(1, ...)
+ local oldbufnr = vim.fn.bufadd(old)
+ local new = select(2, ...)
+ vim.lsp.util.rename(old, new)
+ return vim.fn.bufloaded(oldbufnr)
+ ]], old, new)
+ eq(0, lines)
+ os.remove(new)
+ end)
+ it('Can rename a directory', function()
-- only reserve the name, file must not exist for the test scenario
local old_dir = helpers.tmpname()
local new_dir = helpers.tmpname()
@@ -2205,16 +2224,19 @@ describe('LSP', function()
helpers.mkdir_p(old_dir)
- local file = "file"
+ local file = 'file.txt'
write_file(old_dir .. pathsep .. file, 'Test content')
- exec_lua([[
+ local lines = exec_lua([[
local old_dir = select(1, ...)
local new_dir = select(2, ...)
+ local pathsep = select(3, ...)
+ local oldbufnr = vim.fn.bufadd(old_dir .. pathsep .. 'file')
vim.lsp.util.rename(old_dir, new_dir)
- ]], old_dir, new_dir)
-
+ return vim.fn.bufloaded(oldbufnr)
+ ]], old_dir, new_dir, pathsep)
+ eq(0, lines)
eq(false, exec_lua('return vim.loop.fs_stat(...) ~= nil', old_dir))
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', new_dir))
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', new_dir .. pathsep .. file))