refractor: Restructure project
lil better to work on now
This commit is contained in:
59
lua/symbols-outline/hover.lua
Normal file
59
lua/symbols-outline/hover.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
local vim = vim
|
||||
|
||||
local state = require('symbols-outline').state
|
||||
local util = vim.lsp.util
|
||||
|
||||
local M = {}
|
||||
|
||||
local function get_hover_params(node, winnr)
|
||||
local bufnr = vim.api.nvim_win_get_buf(winnr)
|
||||
local fn = "file://" .. vim.api.nvim_buf_get_name(bufnr)
|
||||
|
||||
return {
|
||||
textDocument = {uri = fn},
|
||||
position = {line = node.line, character = node.character},
|
||||
bufnr = bufnr
|
||||
}
|
||||
end
|
||||
|
||||
-- handler yoinked from the default implementation
|
||||
function M.show_hover()
|
||||
local current_line = vim.api.nvim_win_get_cursor(state.outline_win)[1]
|
||||
local node = state.flattened_outline_items[current_line]
|
||||
|
||||
local hover_params = get_hover_params(node, state.code_win)
|
||||
|
||||
vim.lsp.buf_request(hover_params.bufnr, "textDocument/hover", hover_params,
|
||||
function(_, method, result)
|
||||
|
||||
util.focusable_float(method, function()
|
||||
if not (result and result.contents) then
|
||||
-- return { 'No information available' }
|
||||
return
|
||||
end
|
||||
|
||||
local markdown_lines = util.convert_input_to_markdown_lines(
|
||||
result.contents)
|
||||
markdown_lines = util.trim_empty_lines(markdown_lines)
|
||||
if vim.tbl_isempty(markdown_lines) then
|
||||
-- return { 'No information available' }
|
||||
return
|
||||
end
|
||||
local bufnr, winnr = util.fancy_floating_markdown(markdown_lines, {
|
||||
border = {
|
||||
{"┌", "FloatBorder"}, {"─", "FloatBorder"},
|
||||
{"┐", "FloatBorder"}, {"│", "FloatBorder"},
|
||||
{"┘", "FloatBorder"}, {"─", "FloatBorder"},
|
||||
{"└", "FloatBorder"}, {"│", "FloatBorder"}
|
||||
}
|
||||
})
|
||||
util.close_preview_autocmd({
|
||||
"CursorMoved", "BufHidden", "InsertCharPre"
|
||||
}, winnr)
|
||||
|
||||
return bufnr, winnr
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
131
lua/symbols-outline/parser.lua
Normal file
131
lua/symbols-outline/parser.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
local symbols = require('symbols-outline.symbols')
|
||||
local ui = require('symbols-outline.ui')
|
||||
|
||||
local M = {}
|
||||
|
||||
-- copies an array and returns it because lua usually does references
|
||||
local function array_copy(t)
|
||||
local ret = {}
|
||||
for _, value in ipairs(t) do table.insert(ret, value) end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- parses result into a neat table
|
||||
function M.parse(result, depth, heirarchy)
|
||||
local ret = {}
|
||||
|
||||
for index, value in pairs(result) do
|
||||
-- the heirarchy is basically a table of booleans which tells whether
|
||||
-- the parent was the last in its group or not
|
||||
local hir = heirarchy or {}
|
||||
-- how many parents this node has, 1 is the lowest value because its
|
||||
-- easier to work it
|
||||
local level = depth or 1
|
||||
-- whether this node is the last in its group
|
||||
local isLast = index == #result
|
||||
|
||||
local children = nil
|
||||
if value.children ~= nil then
|
||||
-- copy by value because we dont want it messing with the hir table
|
||||
local child_hir = array_copy(hir)
|
||||
table.insert(child_hir, isLast)
|
||||
children = M.parse(value.children, level + 1, child_hir)
|
||||
end
|
||||
|
||||
table.insert(ret, {
|
||||
deprecated = value.deprecated,
|
||||
kind = value.kind,
|
||||
icon = symbols.icon_from_kind(value.kind),
|
||||
name = value.name,
|
||||
detail = value.detail,
|
||||
line = value.selectionRange.start.line,
|
||||
range_start = value.range.start.line,
|
||||
range_end = value.range["end"].line,
|
||||
character = value.selectionRange.start.character,
|
||||
children = children,
|
||||
depth = level,
|
||||
isLast = isLast,
|
||||
heirarchy = hir
|
||||
});
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function M.flatten(outline_items)
|
||||
local ret = {}
|
||||
for _, value in ipairs(outline_items) do
|
||||
table.insert(ret, value)
|
||||
if value.children ~= nil then
|
||||
local inner = M.flatten(value.children)
|
||||
for _, value_inner in ipairs(inner) do
|
||||
table.insert(ret, value_inner)
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
local function table_to_str(t)
|
||||
local ret = ""
|
||||
for _, value in ipairs(t) do ret = ret .. tostring(value) end
|
||||
return ret
|
||||
end
|
||||
|
||||
local function str_to_table(str)
|
||||
local t = {}
|
||||
for i = 1, #str do t[i] = str:sub(i, i) end
|
||||
return t
|
||||
end
|
||||
|
||||
function M.get_lines(flattened_outline_items)
|
||||
local lines = {}
|
||||
for _, value in ipairs(flattened_outline_items) do
|
||||
local line = str_to_table(string.rep(" ", value.depth))
|
||||
|
||||
-- makes the guides
|
||||
for index, _ in ipairs(line) do
|
||||
-- all items start with a space (or two)
|
||||
if index == 1 then
|
||||
line[index] = " "
|
||||
-- if index is last, add a bottom marker if current item is last,
|
||||
-- else add a middle marker
|
||||
elseif index == #line then
|
||||
if value.isLast then
|
||||
line[index] = ui.markers.bottom
|
||||
else
|
||||
line[index] = ui.markers.middle
|
||||
end
|
||||
-- else if the parent was not the last in its group, add a
|
||||
-- vertical marker because there are items under us and we need
|
||||
-- to point to those
|
||||
elseif not value.heirarchy[index] then
|
||||
line[index] = ui.markers.vertical
|
||||
end
|
||||
end
|
||||
|
||||
local final_prefix = {}
|
||||
-- Add 1 space between the guides
|
||||
for _, v in ipairs(line) do
|
||||
table.insert(final_prefix, v)
|
||||
table.insert(final_prefix, " ")
|
||||
end
|
||||
|
||||
table.insert(lines, table_to_str(final_prefix) .. value.icon .. " " ..
|
||||
value.name)
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
function M.get_details(outline_items, bufnr, winnr, lines)
|
||||
lines = lines or {}
|
||||
for _, value in ipairs(outline_items) do
|
||||
table.insert(lines, value.detail or "")
|
||||
|
||||
if value.children ~= nil then
|
||||
M.get_details(value.children, bufnr, winnr, lines)
|
||||
end
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
return M
|
||||
38
lua/symbols-outline/symbols.lua
Normal file
38
lua/symbols-outline/symbols.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
M = {}
|
||||
|
||||
M.File = {icon = "", hl = "TSURI"}
|
||||
M.Module = {icon = "", hl = "TSNamespace"}
|
||||
M.Namespace = {icon = "", hl = "TSNamespace"}
|
||||
M.Package = {icon = "", hl = "TSNamespace"}
|
||||
M.Class = {icon = "𝓒", hl = "TSType"}
|
||||
M.Method = {icon = "ƒ", hl = "TSMethod"}
|
||||
M.Property = {icon = "", hl = "TSMethod"}
|
||||
M.Field = {icon = "", hl = "TSField"}
|
||||
M.Constructor = {icon = "", hl = "TSConstructor"}
|
||||
M.Enum = {icon = "ℰ", hl = "TSType"}
|
||||
M.Interface = {icon = "ﰮ", hl = "TSType"}
|
||||
M.Function = {icon = "", hl = "TSFunction"}
|
||||
M.Variable = {icon = "", hl = "TSConstant"}
|
||||
M.Constant = {icon = "", hl = "TSConstant"}
|
||||
M.String = {icon = "𝓐", hl = "TSString"}
|
||||
M.Number = {icon = "#", hl = "TSNumber"}
|
||||
M.Boolean = {icon = "⊨", hl = "TSBoolean"}
|
||||
M.Array = {icon = "", hl = "TSConstant"}
|
||||
M.Object = {icon = "⦿", hl = "TSType"}
|
||||
M.Key = {icon = "🔐", hl = "TSType"}
|
||||
M.Null = {icon = "NULL", hl = "TSType"}
|
||||
M.EnumMember = {icon = "", hl = "TSField"}
|
||||
M.Struct = {icon = "𝓢", hl = "TSType"}
|
||||
M.Event = {icon = "🗲", hl = "TSType"}
|
||||
M.Operator = {icon = "𝒯", hl = "TSOperator"}
|
||||
|
||||
M.kinds = {
|
||||
"File", "Module", "Namespace", "Package", "Class", "Method", "Property",
|
||||
"Field", "Constructor", "Enum", "Interface", "Function", "Variable",
|
||||
"Constant", "String", "Number", "Boolean", "Array", "Object", "Key", "Null",
|
||||
"EnumMember", "Struct", "Event", "Operator"
|
||||
}
|
||||
|
||||
function M.icon_from_kind(kind) return M[M.kinds[kind]].icon end
|
||||
|
||||
return M
|
||||
43
lua/symbols-outline/ui.lua
Normal file
43
lua/symbols-outline/ui.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
local vim = vim
|
||||
local symbols = require('symbols-outline.symbols')
|
||||
local M = {}
|
||||
|
||||
M.markers = {
|
||||
bottom = "└",
|
||||
middle = "├",
|
||||
vertical = "│",
|
||||
horizontal = "─"
|
||||
}
|
||||
|
||||
M.hovered_hl_ns = vim.api.nvim_create_namespace("hovered_item")
|
||||
|
||||
function M.clear_hover_highlight(bufnr)
|
||||
vim.api.nvim_buf_clear_namespace(bufnr, M.hovered_hl_ns, 0, -1)
|
||||
end
|
||||
|
||||
function M.add_hover_highlight(bufnr, line, col_start)
|
||||
vim.api.nvim_buf_add_highlight(bufnr, M.hovered_hl_ns, "FocusedSymbol",
|
||||
line, col_start, -1)
|
||||
|
||||
end
|
||||
|
||||
local function highlight_text(name, text, hl_group)
|
||||
vim.cmd(string.format("syn match %s /%s/", name, text))
|
||||
vim.cmd(string.format("hi def link %s %s", name, hl_group))
|
||||
end
|
||||
|
||||
function M.setup_highlights()
|
||||
-- markers
|
||||
highlight_text("marker_middle", M.markers.middle, "Comment")
|
||||
highlight_text("marker_vertical", M.markers.vertical, "Comment")
|
||||
highlight_text("markers_horizontal", M.markers.horizontal, "Comment")
|
||||
highlight_text("markers_bottom", M.markers.bottom, "Comment")
|
||||
|
||||
for _, value in ipairs(symbols.kinds) do
|
||||
local symbol = symbols[value]
|
||||
highlight_text(value, symbol.icon, symbol.hl)
|
||||
end
|
||||
vim.cmd('hi FocusedSymbol guibg=#e50050')
|
||||
end
|
||||
|
||||
return M
|
||||
35
lua/symbols-outline/writer.lua
Normal file
35
lua/symbols-outline/writer.lua
Normal file
@@ -0,0 +1,35 @@
|
||||
local vim = vim
|
||||
|
||||
local parser = require('symbols-outline.parser')
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.write_outline(bufnr, lines)
|
||||
vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
|
||||
end
|
||||
|
||||
function M.write_details(bufnr, lines)
|
||||
for index, value in ipairs(lines) do
|
||||
vim.api.nvim_buf_set_virtual_text(bufnr, -1, index - 1,
|
||||
{{value, "Comment"}}, {})
|
||||
end
|
||||
end
|
||||
|
||||
local function clear_virt_text(bufnr)
|
||||
vim.api.nvim_buf_clear_namespace(bufnr, -1, 0, -1)
|
||||
end
|
||||
|
||||
-- runs the whole writing routine where the text is cleared, new data is parsed
|
||||
-- and then written
|
||||
function M.parse_and_write(bufnr, winnr, outline_items, flattened_outline_items)
|
||||
local lines = parser.get_lines(flattened_outline_items)
|
||||
M.write_outline(bufnr, lines)
|
||||
|
||||
clear_virt_text(bufnr)
|
||||
local details = parser.get_details(outline_items, bufnr, winnr)
|
||||
M.write_details(bufnr, details)
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user