mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 02:34:59 -07:00
feat(ui): gx: use url extmark attribute and tree-sitter directive (#30192)
Use the "url" extmark attribute as well as the "url" tree-sitter metadata key to determine if the cursor is over something Nvim considers a URL.
This commit is contained in:
parent
808d73b5df
commit
9762c5e340
@ -113,9 +113,11 @@ do
|
|||||||
local gx_desc =
|
local gx_desc =
|
||||||
'Opens filepath or URI under cursor with the system handler (file explorer, web browser, …)'
|
'Opens filepath or URI under cursor with the system handler (file explorer, web browser, …)'
|
||||||
vim.keymap.set({ 'n' }, 'gx', function()
|
vim.keymap.set({ 'n' }, 'gx', function()
|
||||||
local err = do_open(require('vim.ui')._get_url())
|
for _, url in ipairs(require('vim.ui')._get_urls()) do
|
||||||
if err then
|
local err = do_open(url)
|
||||||
vim.notify(err, vim.log.levels.ERROR)
|
if err then
|
||||||
|
vim.notify(err, vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end, { desc = gx_desc })
|
end, { desc = gx_desc })
|
||||||
vim.keymap.set({ 'x' }, 'gx', function()
|
vim.keymap.set({ 'x' }, 'gx', function()
|
||||||
|
@ -167,29 +167,63 @@ function M.open(path)
|
|||||||
return vim.system(cmd, opts), nil
|
return vim.system(cmd, opts), nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets the URL at cursor, if any.
|
--- Returns all URLs at cursor, if any.
|
||||||
function M._get_url()
|
--- @return string[]
|
||||||
if vim.bo.filetype == 'markdown' then
|
function M._get_urls()
|
||||||
local range = vim.api.nvim_win_get_cursor(0)
|
local urls = {}
|
||||||
vim.treesitter.get_parser():parse(range)
|
|
||||||
-- marking the node as `markdown_inline` is required. Setting it to `markdown` does not
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
-- work.
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
local current_node = vim.treesitter.get_node { lang = 'markdown_inline' }
|
local row = cursor[1] - 1
|
||||||
while current_node do
|
local col = cursor[2]
|
||||||
local type = current_node:type()
|
local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, { row, col }, { row, col }, {
|
||||||
if type == 'inline_link' or type == 'image' then
|
details = true,
|
||||||
local child = assert(current_node:named_child(1))
|
type = 'highlight',
|
||||||
return vim.treesitter.get_node_text(child, 0)
|
overlap = true,
|
||||||
end
|
})
|
||||||
current_node = current_node:parent()
|
for _, v in ipairs(extmarks) do
|
||||||
|
local details = v[4]
|
||||||
|
if details.url then
|
||||||
|
urls[#urls + 1] = details.url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local url = vim._with({ go = { isfname = vim.o.isfname .. ',@-@' } }, function()
|
local highlighter = vim.treesitter.highlighter.active[bufnr]
|
||||||
return vim.fn.expand('<cfile>')
|
if highlighter then
|
||||||
end)
|
local range = { row, col, row, col }
|
||||||
|
local ltree = highlighter.tree:language_for_range(range)
|
||||||
|
local lang = ltree:lang()
|
||||||
|
local query = vim.treesitter.query.get(lang, 'highlights')
|
||||||
|
if query then
|
||||||
|
local tree = ltree:tree_for_range(range)
|
||||||
|
for _, match, metadata in query:iter_matches(tree:root(), bufnr, row, row + 1, { all = true }) do
|
||||||
|
for id, nodes in pairs(match) do
|
||||||
|
for _, node in ipairs(nodes) do
|
||||||
|
if vim.treesitter.node_contains(node, range) then
|
||||||
|
local url = metadata[id] and metadata[id].url
|
||||||
|
if url and match[url] then
|
||||||
|
for _, n in ipairs(match[url]) do
|
||||||
|
urls[#urls + 1] = vim.treesitter.get_node_text(n, bufnr, metadata[url])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return url
|
if #urls == 0 then
|
||||||
|
-- If all else fails, use the filename under the cursor
|
||||||
|
table.insert(
|
||||||
|
urls,
|
||||||
|
vim._with({ go = { isfname = vim.o.isfname .. ',@-@' } }, function()
|
||||||
|
return vim.fn.expand('<cfile>')
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
return urls
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
Loading…
Reference in New Issue
Block a user