feat: initial PoC

This commit is contained in:
əlemi 2023-04-15 18:53:48 +02:00
parent 1b4aa93f08
commit f285844ff0
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 243 additions and 0 deletions

View 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

View 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)

View 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