mirror of
https://git.alemi.dev/neo-tree-symbolmap.git
synced 2024-11-14 12:19:19 +01:00
feat: initial PoC
This commit is contained in:
parent
1b4aa93f08
commit
f285844ff0
3 changed files with 243 additions and 0 deletions
102
lua/neo-tree-symbolmap/commands.lua
Normal file
102
lua/neo-tree-symbolmap/commands.lua
Normal file
|
@ -0,0 +1,102 @@
|
|||
local cc = require("neo-tree.sources.common.commands")
|
||||
local vim = vim
|
||||
|
||||
local M = {}
|
||||
|
||||
local function kind_to_str(kind)
|
||||
return string.format("%s", vim.lsp.protocol.SymbolKind[kind])
|
||||
end
|
||||
|
||||
local function parse_tree(tree, id, name)
|
||||
if tree.name ~= nil then
|
||||
return {
|
||||
id = id .. math.random(0, bit.lshift(1, 30)),
|
||||
name = tree.name,
|
||||
type = 'file',
|
||||
extra = { kind = kind_to_str(tree.kind) },
|
||||
path = tree.location.uri,
|
||||
}
|
||||
end
|
||||
local children = {}
|
||||
for key, val in pairs(tree) do
|
||||
table.insert(children, parse_tree(val, id .. '.' .. key, key))
|
||||
end
|
||||
table.sort(children, function(a, b)
|
||||
if a.type == 'directory' and b.type ~= 'directory' then
|
||||
return true
|
||||
end
|
||||
if a.type ~= 'directory' and b.type == 'directory' then
|
||||
return false
|
||||
end
|
||||
return a.name < b.name
|
||||
end)
|
||||
return {
|
||||
id = id,
|
||||
name = name,
|
||||
type = 'directory',
|
||||
children = children
|
||||
}
|
||||
end
|
||||
|
||||
local function array_to_tree(array)
|
||||
local root = {}
|
||||
for _, node in pairs(array) do
|
||||
local fragments = {}
|
||||
if node.containerName ~= nil then
|
||||
fragments = vim.fn.split(node.containerName, "\\.")
|
||||
end
|
||||
local target = root
|
||||
for _, x in pairs(fragments) do
|
||||
if target[x] == nil then
|
||||
target[x] = {}
|
||||
end
|
||||
target = target[x]
|
||||
end
|
||||
target[node.name] = node
|
||||
end
|
||||
return root
|
||||
end
|
||||
|
||||
M.refresh = require("neo-tree.utils").wrap(require("neo-tree.sources.manager").refresh, "symbolmap")
|
||||
|
||||
local function find_last_buffer()
|
||||
local cur = vim.api.nvim_get_current_buf()
|
||||
local tabpage = vim.api.nvim_win_get_tabpage(0)
|
||||
local winlist = vim.api.nvim_tabpage_list_wins(tabpage)
|
||||
for _, win in ipairs(winlist) do
|
||||
local buf = vim.api.nvim_win_get_buf(win)
|
||||
if (buf ~= cur) then
|
||||
return buf
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
M.add = function(state)
|
||||
vim.ui.input({ prompt = "query" }, function(input)
|
||||
local buf = find_last_buffer()
|
||||
local _ = vim.lsp.buf_request(buf, 'workspace/symbol', { query = input }, function(err, data, _, _)
|
||||
local root = {
|
||||
id = "root",
|
||||
name = "no workspace symbols loaded",
|
||||
type = "directory",
|
||||
children = {}
|
||||
}
|
||||
if data ~= nil then
|
||||
local map = array_to_tree(data)
|
||||
root = parse_tree(map, 'root', 'workspace symbols')
|
||||
end
|
||||
state.symboltree = { root }
|
||||
require("neo-tree.sources.manager").refresh("symbolmap")
|
||||
end)
|
||||
state.symboltree = { {
|
||||
id = "root",
|
||||
name = "reloading workspace symbols",
|
||||
type = "directory",
|
||||
children = {}
|
||||
} }
|
||||
end)
|
||||
end
|
||||
|
||||
cc._add_common_commands(M)
|
||||
return M
|
94
lua/neo-tree-symbolmap/components.lua
Normal file
94
lua/neo-tree-symbolmap/components.lua
Normal file
|
@ -0,0 +1,94 @@
|
|||
-- This file contains the built-in components. Each componment is a function
|
||||
-- that takes the following arguments:
|
||||
-- config: A table containing the configuration provided by the user
|
||||
-- when declaring this component in their renderer config.
|
||||
-- node: A NuiNode object for the currently focused node.
|
||||
-- state: The current state of the source providing the items.
|
||||
--
|
||||
-- The function should return either a table, or a list of tables, each of which
|
||||
-- contains the following keys:
|
||||
-- text: The text to display for this item.
|
||||
-- highlight: The highlight group to apply to this text.
|
||||
|
||||
local highlights = require("neo-tree.ui.highlights")
|
||||
local common = require("neo-tree.sources.common.components")
|
||||
local lspkind = require('lspkind')
|
||||
|
||||
local lsp_highlights = {
|
||||
Text = highlights.NORMAL,
|
||||
Method = highlights.GIT_STAGED,
|
||||
Function = highlights.GIT_STAGED,
|
||||
Constructor = highlights.GIT_STAGED,
|
||||
Field = highlights.GIT_ADDED,
|
||||
Variable = highlights.GIT_ADDED,
|
||||
Class = highlights.GIT_CONFLICT,
|
||||
Interface = highlights.GIT_CONFLICT,
|
||||
Module = highlights.GIT_UNTRACKED,
|
||||
Property = highlights.GIT_ADDED,
|
||||
Unit = highlights.GIT_CONFLICT,
|
||||
Value = highlights.GIT_CONFLICT,
|
||||
Enum = highlights.GIT_CONFLICT,
|
||||
Keyword = highlights.GIT_DELETED,
|
||||
Snippet = highlights.GIT_IGNORED,
|
||||
Color = highlights.GIT_IGNORED,
|
||||
File = highlights.GIT_RENAMED,
|
||||
Reference = highlights.GIT_IGNORED,
|
||||
Folder = highlights.DIRECTORY_ICON,
|
||||
EnumMember = highlights.GIT_CONFLICT,
|
||||
Constant = highlights.GIT_DELETED,
|
||||
Struct = highlights.GIT_RENAMED,
|
||||
Event = highlights.GIT_UNSTAGED,
|
||||
Operator = highlights.GIT_DELETED,
|
||||
TypeParameter = highlights.GIT_UNSTAGED,
|
||||
}
|
||||
|
||||
local M = {}
|
||||
|
||||
M.icon = function(config, node, state)
|
||||
local icon = config.default or " "
|
||||
local padding = config.padding or " "
|
||||
local highlight = config.highlight or highlights.FILE_ICON
|
||||
if node.type == "directory" then
|
||||
highlight = highlights.DIRECTORY_ICON
|
||||
if node:is_expanded() then
|
||||
icon = config.folder_open or "-"
|
||||
else
|
||||
icon = config.folder_closed or "+"
|
||||
end
|
||||
elseif node.type == "file" then
|
||||
if node.extra.kind ~= nil then
|
||||
icon = lspkind.symbolic(node.extra.kind, { mode = "symbol" })
|
||||
if #icon == 0 then
|
||||
icon = '?'
|
||||
end
|
||||
highlight = lsp_highlights[node.extra.kind] or highlights.DIM_TEXT
|
||||
else
|
||||
local success, web_devicons = pcall(require, "nvim-web-devicons")
|
||||
if success then
|
||||
local devicon, hl = web_devicons.get_icon(node.name, node.ext)
|
||||
icon = devicon or icon
|
||||
highlight = hl or highlight
|
||||
end
|
||||
end
|
||||
end
|
||||
return {
|
||||
text = icon .. padding,
|
||||
highlight = highlight,
|
||||
}
|
||||
end
|
||||
|
||||
M.name = function(config, node, state)
|
||||
local highlight = config.highlight or highlights.FILE_NAME
|
||||
if node.type == "directory" then
|
||||
highlight = highlights.DIRECTORY_NAME
|
||||
end
|
||||
if node:get_depth() == 1 then
|
||||
highlight = highlights.ROOT_NAME
|
||||
end
|
||||
return {
|
||||
text = node.name,
|
||||
highlight = highlight,
|
||||
}
|
||||
end
|
||||
|
||||
return vim.tbl_deep_extend("force", common, M)
|
47
lua/neo-tree-symbolmap/init.lua
Normal file
47
lua/neo-tree-symbolmap/init.lua
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
--This file should have all functions that are in the public api and either set
|
||||
--or read the state of this source.
|
||||
|
||||
-- local vim = vim
|
||||
local renderer = require("neo-tree.ui.renderer")
|
||||
local manager = require("neo-tree.sources.manager")
|
||||
local events = require("neo-tree.events")
|
||||
|
||||
local M = { name = "symbolmap" }
|
||||
|
||||
---Navigate to the given path.
|
||||
---@param path string Path to navigate to. If empty, will navigate to the cwd.
|
||||
M.navigate = function(state, path)
|
||||
if path == nil then
|
||||
path = vim.fn.getcwd()
|
||||
end
|
||||
state.path = path
|
||||
|
||||
if state.symboltree == nil then
|
||||
state.symboltree = { {
|
||||
id = "root",
|
||||
name = "symbols",
|
||||
type = "directory",
|
||||
children = {}
|
||||
} }
|
||||
end
|
||||
|
||||
renderer.show_nodes(state.symboltree, state)
|
||||
end
|
||||
|
||||
---Configures the plugin, should be called before the plugin is used.
|
||||
---@param config table Configuration table containing any keys that the user
|
||||
--wants to change from the defaults. May be empty to accept default values.
|
||||
M.setup = function(config, global_config)
|
||||
-- You most likely want to use this function to subscribe to events
|
||||
if config.use_libuv_file_watcher then
|
||||
-- manager.subscribe(M.name, {
|
||||
-- event = events.FS_EVENT,
|
||||
-- handler = function(args)
|
||||
-- manager.refresh(M.name)
|
||||
-- end,
|
||||
-- })
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in a new issue