diff options
| -rw-r--r-- | .github/scripts/labeler_configuration.yml | 20 | ||||
| -rw-r--r-- | .github/scripts/reviewers_add.js | 14 | ||||
| -rw-r--r-- | cmake.packaging/WixPatch.xml | 2 | ||||
| -rw-r--r-- | runtime/doc/deprecated.txt | 3 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp.lua | 18 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/_changetracking.lua | 3 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/client.lua | 5 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/completion.lua | 49 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/inlay_hint.lua | 4 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/semantic_tokens.lua | 6 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/util.lua | 16 | ||||
| -rw-r--r-- | src/nvim/search.h | 2 | ||||
| -rw-r--r-- | src/nvim/strings.c | 6 | ||||
| -rw-r--r-- | test/functional/fixtures/fake-lsp-server.lua | 14 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/completion_spec.lua | 110 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/semantic_tokens_spec.lua | 24 | ||||
| -rw-r--r-- | test/functional/plugin/lsp_spec.lua | 29 | ||||
| -rw-r--r-- | test/old/testdir/test_functions.vim | 48 | ||||
| -rw-r--r-- | test/old/testdir/test_options.vim | 29 | ||||
| -rw-r--r-- | test/old/testdir/test_shell.vim | 27 |
20 files changed, 233 insertions, 196 deletions
diff --git a/.github/scripts/labeler_configuration.yml b/.github/scripts/labeler_configuration.yml index ea670d1dd0..cf3b8f802b 100644 --- a/.github/scripts/labeler_configuration.yml +++ b/.github/scripts/labeler_configuration.yml @@ -2,6 +2,10 @@ build: - changed-files: - any-glob-to-any-file: [ CMakeLists.txt, "**/CMakeLists.txt", "**/Makefile", "**/*.cmake", cmake.deps/**/* ] +checkhealth: + - changed-files: + - any-glob-to-any-file: [ "**/health.lua" ] + ci: - changed-files: - any-glob-to-any-file: [ .github/actions/**, .github/workflows/**, .github/scripts/** ] @@ -14,6 +18,14 @@ column: - changed-files: - any-glob-to-any-file: [ src/nvim/sign* ] +comment: + - changed-files: + - any-glob-to-any-file: [ runtime/lua/vim/_comment.lua ] + +defaults: + - changed-files: + - any-glob-to-any-file: [ runtime/lua/vim/_defaults.lua ] + diagnostic: - changed-files: - any-glob-to-any-file: [ runtime/lua/vim/diagnostic.lua ] @@ -34,6 +46,10 @@ filetype: - changed-files: - any-glob-to-any-file: [ runtime/lua/vim/filetype.lua, runtime/lua/vim/filetype/detect.lua ] +filesystem: + - changed-files: + - any-glob-to-any-file: [ runtime/lua/vim/fs.lua ] + folds: - changed-files: - any-glob-to-any-file: [ src/nvim/fold* ] @@ -46,6 +62,10 @@ mouse: - changed-files: - any-glob-to-any-file: [ src/nvim/mouse* ] +netrw: + - changed-files: + - any-glob-to-any-file: [ runtime/autoload/netrw.vim, runtime/plugin/netrwPlugin.vim ] + snippet: - changed-files: - any-glob-to-any-file: [ runtime/lua/vim/snippet.lua ] diff --git a/.github/scripts/reviewers_add.js b/.github/scripts/reviewers_add.js index a7e0d2e47b..50195497af 100644 --- a/.github/scripts/reviewers_add.js +++ b/.github/scripts/reviewers_add.js @@ -23,6 +23,10 @@ module.exports = async ({ github, context }) => { reviewers.add("lewis6991"); } + if (labels.includes("comment")) { + reviewers.add("echasnovski"); + } + if (labels.includes("defaults")) { reviewers.add("gpanders"); } @@ -43,7 +47,7 @@ module.exports = async ({ github, context }) => { reviewers.add("gpanders"); } - if (labels.includes("extmarks")) { + if (labels.includes("marks")) { reviewers.add("bfredl"); } @@ -52,11 +56,19 @@ module.exports = async ({ github, context }) => { reviewers.add("gpanders"); } + if (labels.includes("inccommand")) { + reviewers.add("famiu"); + } + if (labels.includes("lsp")) { reviewers.add("MariaSolOs"); reviewers.add("mfussenegger"); } + if (labels.includes("netrw")) { + reviewers.add("justinmk"); + } + if (labels.includes("options")) { reviewers.add("famiu"); } diff --git a/cmake.packaging/WixPatch.xml b/cmake.packaging/WixPatch.xml index 1196f4f335..89c47753ce 100644 --- a/cmake.packaging/WixPatch.xml +++ b/cmake.packaging/WixPatch.xml @@ -6,7 +6,7 @@ Name='PATH' Action='set' Permanent='no' - System='no' + System='yes' Part='last' Value='[INSTALL_ROOT]bin' /> diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 6c6585d76e..3b3e6afa9e 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -22,6 +22,9 @@ API LUA - vim.region() Use |getregionpos()| instead. +LSP +- *vim.lsp.util.buf_versions* Use |b:changedtick| instead. + DIAGNOSTICS - *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count = 1}` instead. - *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count = -1}` instead. diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 94c31359da..c2deac0113 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -391,8 +391,8 @@ end local function on_client_exit(code, signal, client_id) local client = all_clients[client_id] - for bufnr in pairs(client.attached_buffers) do - vim.schedule(function() + vim.schedule(function() + for bufnr in pairs(client.attached_buffers) do if client and client.attached_buffers[bufnr] then api.nvim_exec_autocmds('LspDetach', { buffer = bufnr, @@ -401,15 +401,16 @@ local function on_client_exit(code, signal, client_id) }) end - local namespace = vim.lsp.diagnostic.get_namespace(client_id) - vim.diagnostic.reset(namespace, bufnr) client.attached_buffers[bufnr] = nil if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then reset_defaults(bufnr) end - end) - end + end + + local namespace = vim.lsp.diagnostic.get_namespace(client_id) + vim.diagnostic.reset(namespace) + end) local name = client.name or 'unknown' @@ -483,7 +484,6 @@ local function text_document_did_save_handler(bufnr) text = lsp._buf_get_full_text(bufnr), }, }) - util.buf_versions[bufnr] = 0 end local save_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'save') if save_capability then @@ -519,7 +519,6 @@ local function buf_detach_client(bufnr, client) end client.attached_buffers[bufnr] = nil - util.buf_versions[bufnr] = nil local namespace = lsp.diagnostic.get_namespace(client.id) vim.diagnostic.reset(namespace, bufnr) @@ -575,12 +574,11 @@ local function buf_attach(bufnr) }) -- First time, so attach and set up stuff. api.nvim_buf_attach(bufnr, false, { - on_lines = function(_, _, changedtick, firstline, lastline, new_lastline) + on_lines = function(_, _, _, firstline, lastline, new_lastline) if #lsp.get_clients({ bufnr = bufnr }) == 0 then -- detach if there are no clients return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 end - util.buf_versions[bufnr] = changedtick changetracking.send_changes(bufnr, firstline, lastline, new_lastline) end, diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index b2be53269f..ce701f0772 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -1,6 +1,5 @@ local protocol = require('vim.lsp.protocol') local sync = require('vim.lsp.sync') -local util = require('vim.lsp.util') local api = vim.api local uv = vim.uv @@ -277,7 +276,7 @@ local function send_changes(bufnr, sync_kind, state, buf_state) client.notify(protocol.Methods.textDocument_didChange, { textDocument = { uri = uri, - version = util.buf_versions[bufnr], + version = vim.b[bufnr].changedtick, }, contentChanges = changes, }) diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 327cd19125..b28fe2f797 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -673,8 +673,8 @@ function Client:_request(method, params, handler, bufnr) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) - local version = lsp.util.buf_versions[bufnr] bufnr = resolve_bufnr(bufnr) + local version = vim.b[bufnr].changedtick log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr) local success, request_id = self.rpc.request(method, params, function(err, result) local context = { @@ -922,14 +922,13 @@ function Client:_text_document_did_open_handler(bufnr) local params = { textDocument = { - version = 0, + version = vim.b[bufnr].changedtick, uri = vim.uri_from_bufnr(bufnr), languageId = self.get_language_id(bufnr, filetype), text = lsp._buf_get_full_text(bufnr), }, } self.notify(ms.textDocument_didOpen, params) - lsp.util.buf_versions[bufnr] = params.textDocument.version -- Next chance we get, we should re-do the diagnostics vim.schedule(function() diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 25b3d53c8c..39c0c5fa29 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -129,18 +129,33 @@ end --- @param item lsp.CompletionItem --- @return string local function get_completion_word(item) - if item.textEdit ~= nil and item.textEdit.newText ~= nil and item.textEdit.newText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.textEdit.newText - else - return parse_snippet(item.textEdit.newText) - end - elseif item.insertText ~= nil and item.insertText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.insertText - else + if item.insertTextFormat == protocol.InsertTextFormat.Snippet then + if item.textEdit then + -- Use label instead of text if text has different starting characters. + -- label is used as abbr (=displayed), but word is used for filtering + -- This is required for things like postfix completion. + -- E.g. in lua: + -- + -- local f = {} + -- f@| + -- ▲ + -- └─ cursor + -- + -- item.textEdit.newText: table.insert(f, $0) + -- label: insert + -- + -- Typing `i` would remove the candidate because newText starts with `t`. + local text = item.insertText or item.textEdit.newText + return #text < #item.label and text or item.label + elseif item.insertText and item.insertText ~= '' then return parse_snippet(item.insertText) + else + return item.label end + elseif item.textEdit then + return item.textEdit.newText + elseif item.insertText and item.insertText ~= '' then + return item.insertText end return item.label end @@ -201,11 +216,17 @@ function M._lsp_to_complete_items(result, prefix, client_id) return {} end - local function matches_prefix(item) - return vim.startswith(get_completion_word(item), prefix) - end + if prefix ~= '' then + ---@param item lsp.CompletionItem + local function match_prefix(item) + if item.filterText then + return next(vim.fn.matchfuzzy({ item.filterText }, prefix)) + end + return true + end - items = vim.tbl_filter(matches_prefix, items) --[[@as lsp.CompletionItem[]|]] + items = vim.tbl_filter(match_prefix, items) --[[@as lsp.CompletionItem[]|]] + end table.sort(items, function(a, b) return (a.sortText or a.label) < (b.sortText or b.label) end) diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index f98496456b..78f309abf7 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -43,7 +43,7 @@ function M.on_inlayhint(err, result, ctx, _) return end local bufnr = assert(ctx.bufnr) - if util.buf_versions[bufnr] ~= ctx.version then + if vim.b[bufnr].changedtick ~= ctx.version then return end local client_id = ctx.client_id @@ -324,7 +324,7 @@ api.nvim_set_decoration_provider(namespace, { return end - if bufstate.version ~= util.buf_versions[bufnr] then + if bufstate.version ~= vim.b[bufnr].changedtick then return end diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua index ef2502b12e..278014a4ea 100644 --- a/runtime/lua/vim/lsp/semantic_tokens.lua +++ b/runtime/lua/vim/lsp/semantic_tokens.lua @@ -116,7 +116,7 @@ local function tokens_to_ranges(data, bufnr, client, request) if elapsed_ns > yield_interval_ns then vim.schedule(function() - coroutine.resume(co, util.buf_versions[bufnr]) + coroutine.resume(co, vim.b[bufnr].changedtick) end) if request.version ~= coroutine.yield() then -- request became stale since the last time the coroutine ran. @@ -275,7 +275,7 @@ end --- ---@package function STHighlighter:send_request() - local version = util.buf_versions[self.bufnr] + local version = vim.b[self.bufnr].changedtick self:reset_timer() @@ -418,7 +418,7 @@ end function STHighlighter:on_win(topline, botline) for client_id, state in pairs(self.client_state) do local current_result = state.current_result - if current_result.version and current_result.version == util.buf_versions[self.bufnr] then + if current_result.version and current_result.version == vim.b[self.bufnr].changedtick then if not current_result.namespace_cleared then api.nvim_buf_clear_namespace(self.bufnr, state.namespace, 0, -1) current_result.namespace_cleared = true diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 0099e82f52..d1f0e97065 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -509,8 +509,7 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding) and ( text_document.version and text_document.version > 0 - and M.buf_versions[bufnr] - and M.buf_versions[bufnr] > text_document.version + and vim.b[bufnr].changedtick > text_document.version ) then print('Buffer ', text_document.uri, ' newer than edits.') @@ -2200,9 +2199,16 @@ function M._refresh(method, opts) end end -M._get_line_byte_from_position = get_line_byte_from_position - ---@nodoc -M.buf_versions = {} ---@type table<integer,integer> +---@deprecated +---@type table<integer,integer> +M.buf_versions = setmetatable({}, { + __index = function(_, bufnr) + vim.deprecate('vim.lsp.util.buf_versions', 'vim.b.changedtick', '0.13') + return vim.b[bufnr].changedtick + end, +}) + +M._get_line_byte_from_position = get_line_byte_from_position return M diff --git a/src/nvim/search.h b/src/nvim/search.h index 783756b781..92ee5d6854 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -84,7 +84,7 @@ typedef struct { /// Structure containing last search pattern and its attributes. typedef struct { char *pat; ///< The pattern (in allocated memory) or NULL. - size_t patlen; ///< The length of the patten (0 is pat is NULL). + size_t patlen; ///< The length of the pattern (0 if pat is NULL). bool magic; ///< Magicness of the pattern. bool no_scs; ///< No smartcase for this pattern. Timestamp timestamp; ///< Time of the last change. diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 16ae35272b..8fef4ba7fd 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -268,9 +268,9 @@ char *vim_strsave_shellescape(const char *string, bool do_special, bool do_newli } if (do_special && find_cmdline_var(p, &l) >= 0) { *d++ = '\\'; // insert backslash - while (--l != SIZE_MAX) { // copy the var - *d++ = *p++; - } + memcpy(d, p, l); // copy the var + d += l; + p += l; continue; } if (*p == '\\' && fish_like) { diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index f806869b40..9aafd38d4f 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -471,7 +471,7 @@ function tests.basic_check_buffer_open() languageId = '', text = table.concat({ 'testing', '123' }, '\n') .. '\n', uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('finish') @@ -498,7 +498,7 @@ function tests.basic_check_buffer_open_and_change() languageId = '', text = table.concat({ 'testing', '123' }, '\n') .. '\n', uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('textDocument/didChange', { @@ -534,7 +534,7 @@ function tests.basic_check_buffer_open_and_change_noeol() languageId = '', text = table.concat({ 'testing', '123' }, '\n'), uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('textDocument/didChange', { @@ -569,7 +569,7 @@ function tests.basic_check_buffer_open_and_change_multi() languageId = '', text = table.concat({ 'testing', '123' }, '\n') .. '\n', uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('textDocument/didChange', { @@ -614,7 +614,7 @@ function tests.basic_check_buffer_open_and_change_multi_and_close() languageId = '', text = table.concat({ 'testing', '123' }, '\n') .. '\n', uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('textDocument/didChange', { @@ -672,7 +672,7 @@ function tests.basic_check_buffer_open_and_change_incremental() languageId = '', text = table.concat({ 'testing', '123' }, '\n') .. '\n', uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('textDocument/didChange', { @@ -715,7 +715,7 @@ function tests.basic_check_buffer_open_and_change_incremental_editing() languageId = '', text = table.concat({ 'testing', '123' }, '\n'), uri = 'file://', - version = 0, + version = 2, }, }) expect_notification('textDocument/didChange', { diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index 5b7232ad7e..d7755dd0c4 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -78,32 +78,6 @@ describe('vim.lsp.completion: item conversion', function() textEdit = { newText = 'foobar', range = range0 }, }, { label = 'foocar', sortText = 'f', textEdit = { newText = 'foobar', range = range0 } }, - -- real-world snippet text - { - label = 'foocar', - sortText = 'g', - insertText = 'foodar', - insertTextFormat = 2, - textEdit = { - newText = 'foobar(${1:place holder}, ${2:more ...holder{\\}})', - range = range0, - }, - }, - { - label = 'foocar', - sortText = 'h', - insertText = 'foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', - insertTextFormat = 2, - }, - -- nested snippet tokens - { - label = 'foocar', - sortText = 'i', - insertText = 'foodar(${1:${2|typ1,typ2|}}) {$0\\}', - insertTextFormat = 2, - }, - -- braced tabstop - { label = 'foocar', sortText = 'j', insertText = 'foodar()${0}', insertTextFormat = 2 }, -- plain text { label = 'foocar', @@ -139,23 +113,87 @@ describe('vim.lsp.completion: item conversion', function() }, { abbr = 'foocar', - word = 'foobar(place holder, more ...holder{})', + word = 'foodar(${1:var1})', -- marked as PlainText, text is used as is + }, + } + local result = complete('|', completion_list) + result = vim.tbl_map(function(x) + return { + abbr = x.abbr, + word = x.word, + } + end, result.items) + eq(expected, result) + end) + + it('prefers wordlike components for snippets', function() + -- There are two goals here: + -- + -- 1. The `word` should match what the user started typing, so that vim.fn.complete() doesn't + -- filter it away, preventing snippet expansion + -- + -- For example, if they type `items@ins`, luals returns `table.insert(items, $0)` as + -- textEdit.newText and `insert` as label. + -- There would be no prefix match if textEdit.newText is used as `word` + -- + -- 2. If users do not expand a snippet, but continue typing, they should see a somewhat reasonable + -- `word` getting inserted. + -- + -- For example in: + -- + -- insertText: "testSuites ${1:Env}" + -- label: "testSuites" + -- + -- "testSuites" should have priority as `word`, as long as the full snippet gets expanded on accept (<c-y>) + local range0 = { + start = { line = 0, character = 0 }, + ['end'] = { line = 0, character = 0 }, + } + local completion_list = { + -- luals postfix snippet (typed text: items@ins|) + { + label = 'insert', + insertTextFormat = 2, + textEdit = { + newText = 'table.insert(items, $0)', + range = range0, + }, }, + + -- eclipse.jdt.ls `new` snippet { - abbr = 'foocar', - word = 'foodar(var1 typ1, var2 *typ2) {}', + label = 'new', + insertTextFormat = 2, + textEdit = { + newText = '${1:Object} ${2:foo} = new ${1}(${3});\n${0}', + range = range0, + }, + textEditText = '${1:Object} ${2:foo} = new ${1}(${3});\n${0}', }, + + -- eclipse.jdt.ls `List.copyO` function call completion { - abbr = 'foocar', - word = 'foodar(typ1) {}', + label = 'copyOf(Collection<? extends E> coll) : List<E>', + insertTextFormat = 2, + insertText = 'copyOf', + textEdit = { + newText = 'copyOf(${1:coll})', + range = range0, + }, }, + } + local expected = { { - abbr = 'foocar', - word = 'foodar()', + abbr = 'copyOf(Collection<? extends E> coll) : List<E>', + word = 'copyOf', }, { - abbr = 'foocar', - word = 'foodar(${1:var1})', + abbr = 'insert', + word = 'insert', + }, + { + abbr = 'new', + word = 'new', }, } local result = complete('|', completion_list) @@ -228,7 +266,7 @@ describe('vim.lsp.completion: item conversion', function() }, }, { - filterText = 'notthis_thread', + filterText = 'no_match', insertText = 'notthis_thread', insertTextFormat = 1, kind = 9, diff --git a/test/functional/plugin/lsp/semantic_tokens_spec.lua b/test/functional/plugin/lsp/semantic_tokens_spec.lua index 7908c5d2e7..9babb080e7 100644 --- a/test/functional/plugin/lsp/semantic_tokens_spec.lua +++ b/test/functional/plugin/lsp/semantic_tokens_spec.lua @@ -111,6 +111,7 @@ describe('semantic token highlighting', function() end) it('buffer is highlighted when attached', function() + insert(text) exec_lua([[ bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) @@ -118,8 +119,6 @@ describe('semantic token highlighting', function() client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) ]]) - insert(text) - screen:expect { grid = [[ #include <iostream> | @@ -141,6 +140,7 @@ describe('semantic token highlighting', function() end) it('use LspTokenUpdate and highlight_token', function() + insert(text) exec_lua([[ vim.api.nvim_create_autocmd("LspTokenUpdate", { callback = function(args) @@ -157,8 +157,6 @@ describe('semantic token highlighting', function() client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) ]]) - insert(text) - screen:expect { grid = [[ #include <iostream> | @@ -180,14 +178,17 @@ describe('semantic token highlighting', function() end) it('buffer is unhighlighted when client is detached', function() + insert(text) + exec_lua([[ bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) + vim.wait(1000, function() + return #server.messages > 1 + end) ]]) - insert(text) - exec_lua([[ vim.notify = function() end vim.lsp.buf_detach_client(bufnr, client_id) @@ -331,14 +332,13 @@ describe('semantic token highlighting', function() end) it('buffer is re-highlighted when force refreshed', function() + insert(text) exec_lua([[ bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) ]]) - insert(text) - screen:expect { grid = [[ #include <iostream> | @@ -412,13 +412,14 @@ describe('semantic token highlighting', function() end) it('updates highlights with delta request on buffer change', function() + insert(text) + exec_lua([[ bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) ]]) - insert(text) screen:expect { grid = [[ #include <iostream> | @@ -597,6 +598,7 @@ describe('semantic token highlighting', function() end) it('does not send delta requests if not supported by server', function() + insert(text) exec_lua( [[ local legend, response, edit_response = ... @@ -625,7 +627,6 @@ describe('semantic token highlighting', function() edit_response ) - insert(text) screen:expect { grid = [[ #include <iostream> | @@ -1449,6 +1450,7 @@ int main() }, }) do it(test.it, function() + insert(test.text1) exec_lua(create_server_definition) exec_lua( [[ @@ -1485,8 +1487,6 @@ int main() test.response2 ) - insert(test.text1) - test.expected_screen1() local highlights = exec_lua([[ diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 0cf84b50c2..85891e59b5 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -255,7 +255,7 @@ describe('LSP', function() return end local expected_handlers = { - { NIL, {}, { method = 'shutdown', bufnr = 1, client_id = 1 } }, + { NIL, {}, { method = 'shutdown', bufnr = 1, client_id = 1, version = 2 } }, { NIL, {}, { method = 'test', client_id = 1 } }, } test_rpc_server { @@ -948,7 +948,11 @@ describe('LSP', function() it('should forward ContentModified to callback', function() local expected_handlers = { { NIL, {}, { method = 'finish', client_id = 1 } }, - { { code = -32801 }, NIL, { method = 'error_code_test', bufnr = 1, client_id = 1 } }, + { + { code = -32801 }, + NIL, + { method = 'error_code_test', bufnr = 1, client_id = 1, version = 2 }, + }, } local client --- @type vim.lsp.Client test_rpc_server { @@ -978,7 +982,7 @@ describe('LSP', function() it('should track pending requests to the language server', function() local expected_handlers = { { NIL, {}, { method = 'finish', client_id = 1 } }, - { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } }, + { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1, version = 2 } }, } local client --- @type vim.lsp.Client test_rpc_server { @@ -1045,7 +1049,7 @@ describe('LSP', function() it('should clear pending and cancel requests on reply', function() local expected_handlers = { { NIL, {}, { method = 'finish', client_id = 1 } }, - { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } }, + { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1, version = 2 } }, } local client --- @type vim.lsp.Client test_rpc_server { @@ -1084,7 +1088,7 @@ describe('LSP', function() it('should trigger LspRequest autocmd when requests table changes', function() local expected_handlers = { { NIL, {}, { method = 'finish', client_id = 1 } }, - { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } }, + { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1, version = 2 } }, } local client --- @type vim.lsp.Client test_rpc_server { @@ -1364,6 +1368,7 @@ describe('LSP', function() }, bufnr = 2, client_id = 1, + version = 2, }, }, { NIL, {}, { method = 'start', client_id = 1 } }, @@ -2117,7 +2122,6 @@ describe('LSP', function() local args = {...} local bufnr = select(1, ...) local text_edit = select(2, ...) - vim.lsp.util.buf_versions[bufnr] = 10 vim.lsp.util.apply_text_document_edit(text_edit, nil, 'utf-16') ]], target_bufnr, @@ -2134,7 +2138,6 @@ describe('LSP', function() [[ local args = {...} local versionedBuf = args[2] - vim.lsp.util.buf_versions[versionedBuf.bufnr] = versionedBuf.currentVersion vim.lsp.util.apply_text_document_edit(args[1], nil, 'utf-16') ]], edit, @@ -2239,18 +2242,6 @@ describe('LSP', function() } vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) - - local update_changed_tick = function() - vim.lsp.util.buf_versions[bufnr] = vim.api.nvim_buf_get_var(bufnr, 'changedtick') - end - - update_changed_tick() - vim.api.nvim_buf_attach(bufnr, false, { - on_changedtick = function() - update_changed_tick() - end - }) - return {bufnr, vim.api.nvim_buf_get_var(bufnr, 'changedtick')} ]] diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index 18d0d9aa5d..fa9ae63381 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -2143,54 +2143,6 @@ func Test_balloon_show() endif endfunc -func Test_shellescape() - let save_shell = &shell - set shell=bash - call assert_equal("'text'", shellescape('text')) - call assert_equal("'te\"xt'", 'te"xt'->shellescape()) - call assert_equal("'te'\\''xt'", shellescape("te'xt")) - - call assert_equal("'te%xt'", shellescape("te%xt")) - call assert_equal("'te\\%xt'", shellescape("te%xt", 1)) - call assert_equal("'te#xt'", shellescape("te#xt")) - call assert_equal("'te\\#xt'", shellescape("te#xt", 1)) - call assert_equal("'te!xt'", shellescape("te!xt")) - call assert_equal("'te\\!xt'", shellescape("te!xt", 1)) - - call assert_equal("'te\nxt'", shellescape("te\nxt")) - call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1)) - set shell=tcsh - call assert_equal("'te\\!xt'", shellescape("te!xt")) - call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1)) - call assert_equal("'te\\\nxt'", shellescape("te\nxt")) - call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1)) - - set shell=fish - call assert_equal("'text'", shellescape('text')) - call assert_equal("'te\"xt'", shellescape('te"xt')) - call assert_equal("'te'\\''xt'", shellescape("te'xt")) - - call assert_equal("'te%xt'", shellescape("te%xt")) - call assert_equal("'te\\%xt'", shellescape("te%xt", 1)) - call assert_equal("'te#xt'", shellescape("te#xt")) - call assert_equal("'te\\#xt'", shellescape("te#xt", 1)) - call assert_equal("'te!xt'", shellescape("te!xt")) - call assert_equal("'te\\!xt'", shellescape("te!xt", 1)) - - call assert_equal("'te\\\\xt'", shellescape("te\\xt")) - call assert_equal("'te\\\\xt'", shellescape("te\\xt", 1)) - call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt")) - call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt", 1)) - call assert_equal("'te\\\\!xt'", shellescape("te\\!xt")) - call assert_equal("'te\\\\\\!xt'", shellescape("te\\!xt", 1)) - call assert_equal("'te\\\\%xt'", shellescape("te\\%xt")) - call assert_equal("'te\\\\\\%xt'", shellescape("te\\%xt", 1)) - call assert_equal("'te\\\\#xt'", shellescape("te\\#xt")) - call assert_equal("'te\\\\\\#xt'", shellescape("te\\#xt", 1)) - - let &shell = save_shell -endfunc - func Test_setbufvar_options() " This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the " window layout and cursor position. diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim index 7786f82af2..8ffd8f7ef8 100644 --- a/test/old/testdir/test_options.vim +++ b/test/old/testdir/test_options.vim @@ -1400,35 +1400,6 @@ func Test_buftype() bwipe! endfunc -" Test for the 'shell' option -func Test_shell() - throw 'Skipped: Nvim does not have :shell' - CheckUnix - let save_shell = &shell - set shell= - let caught_e91 = 0 - try - shell - catch /E91:/ - let caught_e91 = 1 - endtry - call assert_equal(1, caught_e91) - let &shell = save_shell -endfunc - -" Test for the 'shellquote' option -func Test_shellquote() - CheckUnix - set shellquote=# - set verbose=20 - redir => v - silent! !echo Hello - redir END - set verbose& - set shellquote& - call assert_match(': "#echo Hello#"', v) -endfunc - " Test for the 'rightleftcmd' option func Test_rightleftcmd() CheckFeature rightleft diff --git a/test/old/testdir/test_shell.vim b/test/old/testdir/test_shell.vim index c50161a8ed..c2320d8f39 100644 --- a/test/old/testdir/test_shell.vim +++ b/test/old/testdir/test_shell.vim @@ -119,6 +119,10 @@ func Test_shellescape() call assert_equal("'te\\#xt'", shellescape("te#xt", 1)) call assert_equal("'te!xt'", shellescape("te!xt")) call assert_equal("'te\\!xt'", shellescape("te!xt", 1)) + call assert_equal("'te<cword>xt'", shellescape("te<cword>xt")) + call assert_equal("'te\\<cword>xt'", shellescape("te<cword>xt", 1)) + call assert_equal("'te<cword>%xt'", shellescape("te<cword>%xt")) + call assert_equal("'te\\<cword>\\%xt'", shellescape("te<cword>%xt", 1)) call assert_equal("'te\nxt'", shellescape("te\nxt")) call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1)) @@ -128,6 +132,29 @@ func Test_shellescape() call assert_equal("'te\\\nxt'", shellescape("te\nxt")) call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1)) + set shell=fish + call assert_equal("'text'", shellescape('text')) + call assert_equal("'te\"xt'", shellescape('te"xt')) + call assert_equal("'te'\\''xt'", shellescape("te'xt")) + + call assert_equal("'te%xt'", shellescape("te%xt")) + call assert_equal("'te\\%xt'", shellescape("te%xt", 1)) + call assert_equal("'te#xt'", shellescape("te#xt")) + call assert_equal("'te\\#xt'", shellescape("te#xt", 1)) + call assert_equal("'te!xt'", shellescape("te!xt")) + call assert_equal("'te\\!xt'", shellescape("te!xt", 1)) + + call assert_equal("'te\\\\xt'", shellescape("te\\xt")) + call assert_equal("'te\\\\xt'", shellescape("te\\xt", 1)) + call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt")) + call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt", 1)) + call assert_equal("'te\\\\!xt'", shellescape("te\\!xt")) + call assert_equal("'te\\\\\\!xt'", shellescape("te\\!xt", 1)) + call assert_equal("'te\\\\%xt'", shellescape("te\\%xt")) + call assert_equal("'te\\\\\\%xt'", shellescape("te\\%xt", 1)) + call assert_equal("'te\\\\#xt'", shellescape("te\\#xt")) + call assert_equal("'te\\\\\\#xt'", shellescape("te\\#xt", 1)) + let &shell = save_shell endfunc |