Repository: neovim/neovim
File: runtime/lua/vim/ui.lua (Lua)

Code before:

  local params = { textDocument = vim.lsp.util.make_text_document_params(bufnr) }
  local results = vim.lsp.buf_request_sync(bufnr, 'textDocument/documentLink', params)

  for client_id, result in pairs(results or {}) do
    if result.error then
      vim.lsp.log.error(result.error)
    else
      local client = assert(vim.lsp.get_client_by_id(client_id))
      local position = vim.lsp.util.make_position_params(0, client.offset_encoding).position
      ---@param document_link lsp.DocumentLink
      local link = vim.iter(result.result):find(function(document_link)
        local range = document_link.range
        return (position.line > range.start.line and position.line < range['end'].line)
          or (position.line == range.start.line and position.character >= range.start.character)
          or (position.line == range['end'].line and position.character <= range['end'].character)
      end)

      if link and link.target then
        ---@type string
        local target = link.target
        if vim.startswith(target, 'file://') then
          target = vim.uri_to_fname(target)
        end
        table.insert(urls, target)
      end
    end
  end

  local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, { row, col }, { row, col }, {
    details = true,
    type = 'highlight',
    overlap = true,
  })
  for _, v in ipairs(extmarks) do
    local details = v[4]
    if details and details.url then
      urls[#urls + 1] = details.url
    end
  end

  local highlighter = vim.treesitter.highlighter.active[bufnr]
  if highlighter then
    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 = assert(ltree:tree_for_range(range))
      for _, match, metadata in query:iter_matches(tree:root(), bufnr, row, row + 1) do
        for id, nodes in pairs(match) do

Review comment (suggestion):
Given that `_get_urls()` returns a list of strings - shouldn't this return all matches instead of only the first (`:find`) ?

Could also consider using `vim.pos`/`vim.range` for the containment check.

Code after:

  -- Find LSP document links under the cursor.
  local params = { textDocument = vim.lsp.util.make_text_document_params(bufnr) }
  local results = vim.lsp.buf_request_sync(bufnr, 'textDocument/documentLink', params)

  for client_id, result in pairs(results or {}) do
    if result.error then
      vim.lsp.log.error(result.error)
    else
      local client = assert(vim.lsp.get_client_by_id(client_id))
      local lsp_position = vim.lsp.util.make_position_params(0, client.offset_encoding).position
      local position = vim.pos.lsp(bufnr, lsp_position, client.offset_encoding)

      local document_links = result.result or {} ---@type lsp.DocumentLink[]
      for _, document_link in ipairs(document_links) do
        local range = vim.range.lsp(bufnr, document_link.range, client.offset_encoding)
        if document_link.target and range:has(position) then
          local target = document_link.target ---@type string
          if vim.startswith(target, 'file://') then
            target = vim.uri_to_fname(target)
          end
          table.insert(urls, target)
        end
      end
    end
  end

  local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, { row, col }, { row, col }, {
    details = true,
    type = 'highlight',
    overlap = true,
  })
  for _, v in ipairs(extmarks) do
    local details = v[4]
    if details and details.url then
      urls[#urls + 1] = details.url
    end
  end

  local highlighter = vim.treesitter.highlighter.active[bufnr]
  if highlighter then
    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 = assert(ltree:tree_for_range(range))
      for _, match, metadata in query:iter_matches(tree:root(), bufnr, row, row + 1) do
        for id, nodes in pairs(match) do
          for _, node in ipairs(nodes) do
            if vim.treesitter.node_contains(node, range) then