mirror of
https://git.alemi.dev/neo-tree-symbolmap.git
synced 2024-11-23 16:14:48 +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