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

Code before:

  local items = {} --- @type vim.quickfix.entry[]
  for _, symbol in ipairs(symbols) do
    --- @type string?, lsp.Range?
    local filename, range

    if symbol.location then
      --- @cast symbol lsp.SymbolInformation
      filename = vim.uri_to_fname(symbol.location.uri)
      range = symbol.location.range
    elseif symbol.selectionRange then
      --- @cast symbol lsp.DocumentSymbol
      filename = api.nvim_buf_get_name(bufnr)
      range = symbol.selectionRange
    end

    if filename and range then
      local kind = protocol.SymbolKind[symbol.kind] or 'Unknown'

      local lnum = range['start'].line + 1
      local col = get_line_byte_from_position(bufnr, range['start'], position_encoding) + 1
      local end_lnum = range['end'].line + 1
      local end_col = get_line_byte_from_position(bufnr, range['end'], position_encoding) + 1

      items[#items + 1] = {
        filename = filename,
        lnum = lnum,
        col = col,
        end_lnum = end_lnum,
        end_col = end_col,
        kind = kind,
        text = '[' .. kind .. '] ' .. symbol.name,
      }
    end

    if symbol.children then
      list_extend(items, M.symbols_to_items(symbol.children, bufnr, position_encoding))
    end
  end

  return items
end

--- Removes empty lines from the beginning and end.
---@deprecated use `vim.split()` with `trimempty` instead
---@param lines table list of lines to trim
---@return table trimmed list of lines
function M.trim_empty_lines(lines)
  vim.deprecate('vim.lsp.util.trim_empty_lines()', 'vim.split() with `trimempty`', '0.12')
  local start = 1
  for i = 1, #lines do

Review comment (suggestion):
The spec says that we "should handle unknown tags gracefully".

Code after:

  local items = {} --- @type vim.quickfix.entry[]
  for _, symbol in ipairs(symbols) do
    --- @type string?, lsp.Range?
    local filename, range

    if symbol.location then
      --- @cast symbol lsp.SymbolInformation
      filename = vim.uri_to_fname(symbol.location.uri)
      range = symbol.location.range
    elseif symbol.selectionRange then
      --- @cast symbol lsp.DocumentSymbol
      filename = api.nvim_buf_get_name(bufnr)
      range = symbol.selectionRange
    end

    if filename and range then
      local kind = protocol.SymbolKind[symbol.kind] or 'Unknown'

      local lnum = range['start'].line + 1
      local col = get_line_byte_from_position(bufnr, range['start'], position_encoding) + 1
      local end_lnum = range['end'].line + 1
      local end_col = get_line_byte_from_position(bufnr, range['end'], position_encoding) + 1

      local is_deprecated = symbol.deprecated
        or (symbol.tags and vim.tbl_contains(symbol.tags, protocol.SymbolTag.Deprecated))
      local text =
        string.format('[%s] %s%s', kind, symbol.name, is_deprecated and ' (deprecated)' or '')

      items[#items + 1] = {
        filename = filename,
        lnum = lnum,
        col = col,
        end_lnum = end_lnum,
        end_col = end_col,
        kind = kind,
        text = text,
      }
    end

    if symbol.children then
      list_extend(items, M.symbols_to_items(symbol.children, bufnr, position_encoding))
    end
  end

  return items
end

--- Removes empty lines from the beginning and end.
---@deprecated use `vim.split()` with `trimempty` instead
---@param lines table list of lines to trim