From 57adf8c6e01d9395eb52fe03571c535571efdc4b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 15 Apr 2024 04:33:09 -0700 Subject: fix(vim.ui): open() may wait indefinitely #28325 Problem: vim.ui.open "locks up" Nvim if the spawned process does not terminate. #27986 Solution: - Change `vim.ui.open()`: - Do not call `wait()`. - Return a `SystemObj`. The caller can decide if it wants to `wait()`. - Change `gx` to `wait()` only a short time. - Allows `gx` to show a message if the command fails, without the risk of waiting forever. --- runtime/lua/vim/ui.lua | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'runtime/lua/vim/ui.lua') diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index b0e7ca1a35..b6695734a3 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -114,14 +114,19 @@ end --- Examples: --- --- ```lua +--- -- Asynchronous. --- vim.ui.open("https://neovim.io/") --- vim.ui.open("~/path/to/file") ---- vim.ui.open("$VIMRUNTIME") +--- -- Synchronous (wait until the process exits). +--- local cmd, err = vim.ui.open("$VIMRUNTIME") +--- if cmd then +--- cmd:wait() +--- end --- ``` --- ---@param path string Path or URL to open --- ----@return vim.SystemCompleted|nil # Command result, or nil if not found. +---@return vim.SystemObj|nil # Command object, or nil if not found. ---@return string|nil # Error message on failure --- ---@see |vim.system()| @@ -152,13 +157,7 @@ function M.open(path) return nil, 'vim.ui.open: no handler found (tried: explorer.exe, xdg-open)' end - local rv = vim.system(cmd, { text = true, detach = true }):wait() - if rv.code ~= 0 then - local msg = ('vim.ui.open: command failed (%d): %s'):format(rv.code, vim.inspect(cmd)) - return rv, msg - end - - return rv, nil + return vim.system(cmd, { text = true, detach = true }), nil end return M -- cgit From fd085d90820149caecf213b299f19e46305043ee Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 20 Apr 2024 05:47:08 -0700 Subject: fix(vim.ui.open): try wslview before explorer.exe #28424 Problem: explorer.exe is unreliable on WSL. Solution: Try wslview before explorer.exe. fix #28410 --- runtime/lua/vim/ui.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/ui.lua') diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index b6695734a3..e02acaf25c 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -149,12 +149,14 @@ function M.open(path) else return nil, 'vim.ui.open: rundll32 not found' end + elseif vim.fn.executable('wslview') == 1 then + cmd = { 'wslview', path } elseif vim.fn.executable('explorer.exe') == 1 then cmd = { 'explorer.exe', path } elseif vim.fn.executable('xdg-open') == 1 then cmd = { 'xdg-open', path } else - return nil, 'vim.ui.open: no handler found (tried: explorer.exe, xdg-open)' + return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' end return vim.system(cmd, { text = true, detach = true }), nil -- cgit From e0d92b9cc20b58179599f53dfa74ca821935a539 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 25 Apr 2024 04:15:58 -0700 Subject: fix(vim.ui)!: change open() to return pcall-like values #28502 Problem: `vim.ui.open` unnecessarily invents a different success/failure convention. Its return type was changed in 57adf8c6e01d, so we might as well change it to have a more conventional form. Solution: Change the signature to use the `pcall` convention of `status, result`. --- runtime/lua/vim/ui.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'runtime/lua/vim/ui.lua') diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index e02acaf25c..b8323efa66 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -118,16 +118,16 @@ end --- vim.ui.open("https://neovim.io/") --- vim.ui.open("~/path/to/file") --- -- Synchronous (wait until the process exits). ---- local cmd, err = vim.ui.open("$VIMRUNTIME") ---- if cmd then +--- local ok, cmd = vim.ui.open("$VIMRUNTIME") +--- if ok then --- cmd:wait() --- end --- ``` --- ---@param path string Path or URL to open --- ----@return vim.SystemObj|nil # Command object, or nil if not found. ----@return string|nil # Error message on failure +---@return boolean # false if command not found, else true. +---@return vim.SystemObj|string # Command object, or error message on failure --- ---@see |vim.system()| function M.open(path) @@ -147,7 +147,7 @@ function M.open(path) if vim.fn.executable('rundll32') == 1 then cmd = { 'rundll32', 'url.dll,FileProtocolHandler', path } else - return nil, 'vim.ui.open: rundll32 not found' + return false, 'vim.ui.open: rundll32 not found' end elseif vim.fn.executable('wslview') == 1 then cmd = { 'wslview', path } @@ -156,10 +156,10 @@ function M.open(path) elseif vim.fn.executable('xdg-open') == 1 then cmd = { 'xdg-open', path } else - return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' + return false, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' end - return vim.system(cmd, { text = true, detach = true }), nil + return true, vim.system(cmd, { text = true, detach = true }) end return M -- cgit From 40ce8577977fcdce8ad76863c70eb522e4cefd4d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 3 May 2024 03:20:03 -0700 Subject: fix(vim.ui)!: change open() to return `result|nil, errmsg|nil` #28612 reverts e0d92b9cc20b58179599f53dfa74ca821935a539 #28502 Problem: `vim.ui.open()` has a `pcall()` like signature, under the assumption that this is the Lua idiom for returning result-or-error. However, the `result|nil, errmsg|nil` pattern: - has precedent in: - `io.open` - `vim.uv` (`:help luv-error-handling`) - has these advantages: - Can be used with `assert()`: ``` local result, err = assert(foobar()) ``` - Allows LuaLS to infer the type of `result`: ``` local result, err = foobar() if err then ... elseif result then ... end ``` Solution: - Revert to the `result|nil, errmsg|nil` pattern. - Document the pattern in our guidelines. --- runtime/lua/vim/ui.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'runtime/lua/vim/ui.lua') diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index b8323efa66..3c947c51b0 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -118,16 +118,16 @@ end --- vim.ui.open("https://neovim.io/") --- vim.ui.open("~/path/to/file") --- -- Synchronous (wait until the process exits). ---- local ok, cmd = vim.ui.open("$VIMRUNTIME") ---- if ok then +--- local cmd, err = vim.ui.open("$VIMRUNTIME") +--- if cmd then --- cmd:wait() --- end --- ``` --- ---@param path string Path or URL to open --- ----@return boolean # false if command not found, else true. ----@return vim.SystemObj|string # Command object, or error message on failure +---@return vim.SystemObj|nil # Command object, or nil if not found. +---@return nil|string # Error message on failure, or nil on success. --- ---@see |vim.system()| function M.open(path) @@ -147,7 +147,7 @@ function M.open(path) if vim.fn.executable('rundll32') == 1 then cmd = { 'rundll32', 'url.dll,FileProtocolHandler', path } else - return false, 'vim.ui.open: rundll32 not found' + return nil, 'vim.ui.open: rundll32 not found' end elseif vim.fn.executable('wslview') == 1 then cmd = { 'wslview', path } @@ -156,10 +156,10 @@ function M.open(path) elseif vim.fn.executable('xdg-open') == 1 then cmd = { 'xdg-open', path } else - return false, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' + return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' end - return true, vim.system(cmd, { text = true, detach = true }) + return vim.system(cmd, { text = true, detach = true }), nil end return M -- cgit From f864b68c5b0fe1482249167712cd16ff2b50ec45 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 3 May 2024 20:32:06 +0200 Subject: feat: allow gx to function for markdown links In other words, `gx` works regardless of where it was used in `[...](https://...)`. This only works on markdown buffers. Co-authored-by: ribru17 --- runtime/lua/vim/ui.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'runtime/lua/vim/ui.lua') diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index 3c947c51b0..99b9b78e2a 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -162,4 +162,24 @@ function M.open(path) return vim.system(cmd, { text = true, detach = true }), nil end +--- Gets the URL at cursor, if any. +function M._get_url() + if vim.bo.filetype == 'markdown' then + local range = vim.api.nvim_win_get_cursor(0) + vim.treesitter.get_parser():parse(range) + -- marking the node as `markdown_inline` is required. Setting it to `markdown` does not + -- work. + local current_node = vim.treesitter.get_node { lang = 'markdown_inline' } + while current_node do + local type = current_node:type() + if type == 'inline_link' or type == 'image' then + local child = assert(current_node:named_child(1)) + return vim.treesitter.get_node_text(child, 0) + end + current_node = current_node:parent() + end + end + return vim.fn.expand('') +end + return M -- cgit