mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
Compare commits
1 Commits
d9b4d321d0
...
4f12cc58c8
Author | SHA1 | Date | |
---|---|---|---|
|
4f12cc58c8 |
@ -97,37 +97,13 @@ do
|
||||
|
||||
--- Map |gx| to call |vim.ui.open| on the <cfile> at cursor.
|
||||
do
|
||||
local function do_open(uri)
|
||||
local cmd, err = vim.ui.open(uri)
|
||||
local rv = cmd and cmd:wait(1000) or nil
|
||||
if cmd and rv and rv.code ~= 0 then
|
||||
err = ('vim.ui.open: command %s (%d): %s'):format(
|
||||
(rv.code == 124 and 'timeout' or 'failed'),
|
||||
rv.code,
|
||||
vim.inspect(cmd.cmd)
|
||||
)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
local gx_desc =
|
||||
'Opens filepath or URI under cursor with the system handler (file explorer, web browser, …)'
|
||||
vim.keymap.set({ 'n' }, 'gx', function()
|
||||
for _, url in ipairs(require('vim.ui')._get_urls()) do
|
||||
local err = do_open(url)
|
||||
if err then
|
||||
vim.notify(err, vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
vim.ui.open()
|
||||
end, { desc = gx_desc })
|
||||
vim.keymap.set({ 'x' }, 'gx', function()
|
||||
local lines =
|
||||
vim.fn.getregion(vim.fn.getpos('.'), vim.fn.getpos('v'), { type = vim.fn.mode() })
|
||||
-- Trim whitespace on each line and concatenate.
|
||||
local err = do_open(table.concat(vim.iter(lines):map(vim.trim):totable()))
|
||||
if err then
|
||||
vim.notify(err, vim.log.levels.ERROR)
|
||||
end
|
||||
vim.ui.open()
|
||||
end, { desc = gx_desc })
|
||||
end
|
||||
|
||||
|
@ -124,7 +124,7 @@ end
|
||||
--- end
|
||||
--- ```
|
||||
---
|
||||
---@param path string Path or URL to open
|
||||
---@param path? string Path or URL to open, or `nil` to get path or URL at cursor.
|
||||
---
|
||||
---@return vim.SystemObj|nil # Command object, or nil if not found.
|
||||
---@return nil|string # Error message on failure, or nil on success.
|
||||
@ -132,39 +132,78 @@ end
|
||||
---@see |vim.system()|
|
||||
function M.open(path)
|
||||
vim.validate({
|
||||
path = { path, 'string' },
|
||||
path = { path, 'string', true },
|
||||
})
|
||||
local is_uri = path:match('%w+:')
|
||||
if not is_uri then
|
||||
path = vim.fs.normalize(path)
|
||||
end
|
||||
|
||||
local cmd --- @type string[]
|
||||
local opts --- @type vim.SystemOpts
|
||||
local function do_open(uri)
|
||||
local cmd --- @type string[]
|
||||
local opts --- @type vim.SystemOpts
|
||||
|
||||
opts = { text = true, detach = true }
|
||||
opts = { text = true, detach = true }
|
||||
|
||||
if vim.fn.has('mac') == 1 then
|
||||
cmd = { 'open', path }
|
||||
elseif vim.fn.has('win32') == 1 then
|
||||
if vim.fn.executable('rundll32') == 1 then
|
||||
cmd = { 'rundll32', 'url.dll,FileProtocolHandler', path }
|
||||
if vim.fn.has('mac') == 1 then
|
||||
cmd = { 'open', uri }
|
||||
elseif vim.fn.has('win32') == 1 then
|
||||
if vim.fn.executable('rundll32') == 1 then
|
||||
cmd = { 'rundll32', 'url.dll,FileProtocolHandler', uri }
|
||||
else
|
||||
return nil, 'vim.ui.open: rundll32 not found'
|
||||
end
|
||||
elseif vim.fn.executable('wslview') == 1 then
|
||||
cmd = { 'wslview', uri }
|
||||
elseif vim.fn.executable('explorer.exe') == 1 then
|
||||
cmd = { 'explorer.exe', uri }
|
||||
elseif vim.fn.executable('xdg-open') == 1 then
|
||||
cmd = { 'xdg-open', uri }
|
||||
opts.stdout = false
|
||||
opts.stderr = false
|
||||
else
|
||||
return nil, 'vim.ui.open: rundll32 not found'
|
||||
return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)'
|
||||
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 }
|
||||
opts.stdout = false
|
||||
opts.stderr = false
|
||||
else
|
||||
return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)'
|
||||
|
||||
return vim.system(cmd, opts), nil
|
||||
end
|
||||
|
||||
return vim.system(cmd, opts), nil
|
||||
local function do_open2(uri)
|
||||
local cmd, err = do_open(uri)
|
||||
-- wait() terminates the process if necessary (avoids stale processes), and allows us to show an
|
||||
-- error message if needed.
|
||||
local rv = cmd and cmd:wait(1000) or nil
|
||||
if cmd and rv and rv.code ~= 0 then
|
||||
err = ('vim.ui.open: command %s (%d): %s'):format(
|
||||
(rv.code == 124 and 'timeout' or 'failed'),
|
||||
rv.code,
|
||||
vim.inspect(cmd.cmd)
|
||||
)
|
||||
end
|
||||
return err
|
||||
end
|
||||
|
||||
if path then
|
||||
local is_uri = path:match('%w+:')
|
||||
if not is_uri then
|
||||
path = vim.fs.normalize(path)
|
||||
end
|
||||
return do_open(path)
|
||||
else -- DWIM mode: get the URL or path from the cursor position, and show error.
|
||||
local visual = not not vim.fn.mode():match('[vV\22]')
|
||||
if visual then
|
||||
local lines =
|
||||
vim.fn.getregion(vim.fn.getpos('.'), vim.fn.getpos('v'), { type = vim.fn.mode() })
|
||||
-- Trim whitespace on each line and concatenate.
|
||||
local err = do_open2(table.concat(vim.iter(lines):map(vim.trim):totable()))
|
||||
if err then
|
||||
vim.notify(err, vim.log.levels.ERROR)
|
||||
end
|
||||
else
|
||||
for _, url in ipairs(M._get_urls()) do
|
||||
local err = do_open2(url)
|
||||
if err then
|
||||
vim.notify(err, vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns all URLs at cursor, if any.
|
||||
|
Loading…
Reference in New Issue
Block a user