diff options
-rw-r--r-- | runtime/lua/vim/lsp.lua | 39 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 7 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 15 |
5 files changed, 56 insertions, 8 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 9a008ac965..56ac1cbc66 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -644,7 +644,9 @@ end --- - debounce_text_changes (number, default nil): Debounce didChange --- notifications to the server by the given number in milliseconds. No debounce --- occurs if nil ---- +--- - exit_timeout (number, default 500): Milliseconds to wait for server to +-- exit cleanly after sending the 'shutdown' request before sending kill -15. +-- If set to false, nvim exits immediately after sending the 'shutdown' request to the server. ---@returns Client id. |vim.lsp.get_client_by_id()| Note: client may not be --- fully initialized. Use `on_init` to do any actions once --- the client has been initialized. @@ -1226,9 +1228,38 @@ function lsp._vim_exit_handler() client.stop() end - if not vim.wait(500, function() return tbl_isempty(active_clients) end, 50) then - for _, client in pairs(active_clients) do - client.stop(true) + local timeouts = {} + local max_timeout = 0 + local send_kill = false + + for client_id, client in pairs(active_clients) do + local timeout = if_nil(client.config.flags.exit_timeout, 500) + if timeout then + send_kill = true + timeouts[client_id] = timeout + max_timeout = math.max(timeout, max_timeout) + else + active_clients[client_id] = nil + end + end + + local poll_time = 50 + + local function check_clients_closed() + for client_id, _ in pairs(active_clients) do + timeouts[client_id] = timeouts[client_id] - poll_time + if timeouts[client_id] < 0 then + active_clients[client_id] = nil + end + end + return tbl_isempty(active_clients) + end + + if send_kill then + if not vim.wait(max_timeout, check_clients_closed, poll_time) then + for _, client in pairs(active_clients) do + client.stop(true) + end end end end diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 952926b67e..7a0ac458f3 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -226,9 +226,10 @@ function M.get_progress_messages() table.remove(client.messages, item.idx) end - for _, item in ipairs(progress_remove) do - client.messages.progress[item.token] = nil - end + end + + for _, item in ipairs(progress_remove) do + item.client.messages.progress[item.token] = nil end return new_messages diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 946bde060d..1c78e25639 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3359,7 +3359,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) expand_T xpc; bool filtered = false; int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH - | WILD_NO_BEEP; + | WILD_NO_BEEP | WILD_HOME_REPLACE; if (argvars[1].v_type != VAR_STRING) { EMSG2(_(e_invarg2), "type must be a string"); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4524026e3f..68dd4a22ff 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2915,6 +2915,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff) ExpandInit(xp); xp->xp_pattern = (char_u *)buff; + xp->xp_line = (char_u *)buff; xp->xp_context = EXPAND_COMMANDS; // Default until we get past command ea.argt = 0; diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index ffca415282..98340d0ac6 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -309,6 +309,11 @@ func Test_getcompletion() let l = getcompletion('NoMatch', 'dir') call assert_equal([], l) + if glob('~/*') !=# '' + let l = getcompletion('~/', 'dir') + call assert_true(l[0][0] ==# '~') + endif + let l = getcompletion('exe', 'expression') call assert_true(index(l, 'executable(') >= 0) let l = getcompletion('kill', 'expression') @@ -422,6 +427,16 @@ func Test_getcompletion() let l = getcompletion('call paint', 'cmdline') call assert_equal([], l) + func T(a, c, p) + return "oneA\noneB\noneC" + endfunc + command -nargs=1 -complete=custom,T MyCmd + let l = getcompletion('MyCmd ', 'cmdline') + call assert_equal(['oneA', 'oneB', 'oneC'], l) + + delcommand MyCmd + delfunc T + " For others test if the name is recognized. let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user'] if has('cmdline_hist') |