MAJOR: Refactor configuration structure

The details of the change is documented in the readme.

If your config stops working, I'm fully responsible :)
This commit is contained in:
hedy
2023-11-08 13:56:09 +08:00
parent 04f9d4ad26
commit 29ed132f07
11 changed files with 388 additions and 277 deletions

View File

@@ -3,9 +3,6 @@ local vim = vim
local M = {}
M.defaults = {
position = 'right',
width = 25,
highlight_hovered_item = true,
guides = {
enabled = true,
markers = {
@@ -15,24 +12,39 @@ M.defaults = {
horizontal = '',
},
},
border = 'single',
relative_width = true,
auto_close = false,
auto_goto = false,
auto_preview = false,
open_hover_on_preview = true,
show_numbers = false,
show_relative_numbers = false,
show_cursorline = true,
show_symbol_details = true,
show_symbol_lineno = false,
preview_bg_highlight = 'Pmenu',
winblend = 0,
autofold_depth = nil,
auto_unfold_hover = true,
fold_markers = { '', '' },
wrap = false,
focus_on_open = true,
outline_items = {
show_symbol_details = true,
show_symbol_lineno = false,
highlight_hovered_item = true,
},
outline_window = {
position = 'right',
width = 25,
relative_width = true,
wrap = false,
focus_on_open = true,
auto_close = false,
auto_goto = false,
show_numbers = false,
show_relative_numbers = false,
show_cursorline = true,
},
preview_window = {
auto_preview = false,
width = 50,
min_width = 100,
relative_width = true,
bg_hl = 'Pmenu',
border = 'single',
border_hl = 'Pmenu',
open_hover_on_preview = true,
winblend = 0,
},
symbol_folding = {
autofold_depth = nil,
auto_unfold_hover = true,
markers = { '', '' },
},
keymaps = {
show_help = '?',
close = { '<Esc>', 'q' },
@@ -53,53 +65,59 @@ M.defaults = {
down_and_goto = '<C-j>',
up_and_goto = '<C-k>',
},
lsp_blacklist = {},
symbol_blacklist = {},
symbols = {
File = { icon = '󰈔', hl = '@text.uri' },
Module = { icon = '󰆧', hl = '@namespace' },
Namespace = { icon = '󰅪', hl = '@namespace' },
Package = { icon = '󰏗', hl = '@namespace' },
Class = { icon = '𝓒', hl = '@type' },
Method = { icon = 'ƒ', hl = '@method' },
Property = { icon = '', hl = '@method' },
Field = { icon = '󰆨', hl = '@field' },
Constructor = { icon = '', hl = '@constructor' },
Enum = { icon = '', hl = '@type' },
Interface = { icon = '󰜰', hl = '@type' },
Function = { icon = '', hl = '@function' },
Variable = { icon = '', hl = '@constant' },
Constant = { icon = '', hl = '@constant' },
String = { icon = '𝓐', hl = '@string' },
Number = { icon = '#', hl = '@number' },
Boolean = { icon = '', hl = '@boolean' },
Array = { icon = '󰅪', hl = '@constant' },
Object = { icon = '⦿', hl = '@type' },
Key = { icon = '🔐', hl = '@type' },
Null = { icon = 'NULL', hl = '@type' },
EnumMember = { icon = '', hl = '@field' },
Struct = { icon = '𝓢', hl = '@type' },
Event = { icon = '🗲', hl = '@type' },
Operator = { icon = '+', hl = '@operator' },
TypeParameter = { icon = '𝙏', hl = '@parameter' },
Component = { icon = '󰅴', hl = '@function' },
Fragment = { icon = '󰅴', hl = '@constant' },
-- ccls
TypeAlias = { icon = '', hl = '@type' },
Parameter = { icon = '', hl = '@parameter' },
StaticMethod = { icon = '', hl = '@function' },
Macro = { icon = '', hl = '@macro' },
providers = {
lsp = {
blacklist_clients = {},
},
},
symbols = {
blacklist = {},
icons = {
File = { icon = '󰈔', hl = '@text.uri' },
Module = { icon = '󰆧', hl = '@namespace' },
Namespace = { icon = '󰅪', hl = '@namespace' },
Package = { icon = '󰏗', hl = '@namespace' },
Class = { icon = '𝓒', hl = '@type' },
Method = { icon = 'ƒ', hl = '@method' },
Property = { icon = '', hl = '@method' },
Field = { icon = '󰆨', hl = '@field' },
Constructor = { icon = '', hl = '@constructor' },
Enum = { icon = '', hl = '@type' },
Interface = { icon = '󰜰', hl = '@type' },
Function = { icon = '', hl = '@function' },
Variable = { icon = '', hl = '@constant' },
Constant = { icon = '', hl = '@constant' },
String = { icon = '𝓐', hl = '@string' },
Number = { icon = '#', hl = '@number' },
Boolean = { icon = '', hl = '@boolean' },
Array = { icon = '󰅪', hl = '@constant' },
Object = { icon = '⦿', hl = '@type' },
Key = { icon = '🔐', hl = '@type' },
Null = { icon = 'NULL', hl = '@type' },
EnumMember = { icon = '', hl = '@field' },
Struct = { icon = '𝓢', hl = '@type' },
Event = { icon = '🗲', hl = '@type' },
Operator = { icon = '+', hl = '@operator' },
TypeParameter = { icon = '𝙏', hl = '@parameter' },
Component = { icon = '󰅴', hl = '@function' },
Fragment = { icon = '󰅴', hl = '@constant' },
-- ccls
TypeAlias = { icon = '', hl = '@type' },
Parameter = { icon = '', hl = '@parameter' },
StaticMethod = { icon = '', hl = '@function' },
Macro = { icon = '', hl = '@macro' },
},
},
}
M.options = {}
M.o = {}
function M.has_numbers()
return M.options.show_numbers or M.options.show_relative_numbers
return M.o.outline_window.show_numbers or M.o.outline_window.show_relative_numbers
end
function M.get_position_navigation_direction()
if M.options.position == 'left' then
if M.o.outline_window.position == 'left' then
return 'h'
else
return 'l'
@@ -107,15 +125,15 @@ function M.get_position_navigation_direction()
end
function M.get_window_width()
if M.options.relative_width then
return math.ceil(vim.o.columns * (M.options.width / 100))
if M.o.outline_window.relative_width then
return math.ceil(vim.o.columns * (M.o.outline_window.width / 100))
else
return M.options.width
return M.o.outline_window.width
end
end
function M.get_split_command()
if M.options.position == 'left' then
if M.o.outline_window.position == 'left' then
return 'topleft vs'
else
return 'botright vs'
@@ -136,7 +154,7 @@ function M.is_symbol_blacklisted(kind)
if kind == nil then
return false
end
return has_value(M.options.symbol_blacklist, kind)
return has_value(M.o.symbols.blacklist, kind)
end
function M.is_client_blacklisted(client_id)
@@ -144,17 +162,21 @@ function M.is_client_blacklisted(client_id)
if not client then
return false
end
return has_value(M.options.lsp_blacklist, client.name)
return has_value(M.o.providers.lsp.blacklist_clients, client.name)
end
function M.show_help()
print 'Current keymaps:'
print(vim.inspect(M.options.keymaps))
print(vim.inspect(M.o.keymaps))
end
function M.setup(options)
vim.g.symbols_outline_loaded = 1
M.options = vim.tbl_deep_extend('force', {}, M.defaults, options or {})
M.o = vim.tbl_deep_extend('force', {}, M.defaults, options or {})
local guides = M.o.guides
if type(guides) == 'boolean' and guides then
M.o.guides = M.defaults.guides
end
end
return M

View File

@@ -1,12 +1,12 @@
local M = {}
local config = require 'symbols-outline.config'
local cfg = require 'symbols-outline.config'
M.is_foldable = function(node)
return node.children and #node.children > 0
end
local get_default_folded = function(depth)
local fold_past = config.options.autofold_depth
local fold_past = cfg.o.symbol_folding.autofold_depth
if not fold_past then
return false
else
@@ -17,7 +17,7 @@ end
M.is_folded = function(node)
if node.folded ~= nil then
return node.folded
elseif node.hovered and config.options.auto_unfold_hover then
elseif node.hovered and cfg.o.symbol_folding.auto_unfold_hover then
return false
else
return get_default_folded(node.depth)

View File

@@ -1,5 +1,5 @@
local so = require 'symbols-outline'
local soconfig = require 'symbols-outline.config'
local cfg = require 'symbols-outline.config'
local util = vim.lsp.util
local M = {}
@@ -40,7 +40,7 @@ function M.show_hover()
end
-- FIXME
local bufnr, winnr = util.open_floating_preview(markdown_lines, 'markdown', config)
local winhi = 'Normal:' .. soconfig.options.preview_bg_highlight
local winhi = 'Normal:' .. cfg.o.preview_window.bg_hl
vim.api.nvim_win_set_option(winnr, 'winhighlight', winhi)
end
)

View File

@@ -2,7 +2,7 @@ local parser = require 'symbols-outline.parser'
local providers = require 'symbols-outline.providers.init'
local ui = require 'symbols-outline.ui'
local writer = require 'symbols-outline.writer'
local config = require 'symbols-outline.config'
local cfg = require 'symbols-outline.config'
local utils = require 'symbols-outline.utils.init'
local View = require 'symbols-outline.view'
local folding = require 'symbols-outline.folding'
@@ -11,7 +11,7 @@ local M = {}
local function setup_global_autocmd()
if
config.options.highlight_hovered_item or config.options.auto_unfold_hover
cfg.o.outline_items.highlight_hovered_item or cfg.o.symbol_folding.auto_unfold_hover
then
vim.api.nvim_create_autocmd('CursorHold', {
pattern = '*',
@@ -107,7 +107,7 @@ end
-- Wraps __goto_location and handles auto_close
function M._goto_location(change_focus)
M.__goto_location(change_focus)
if change_focus and config.options.auto_close then
if change_focus and cfg.o.outline_window.auto_close then
M.close_outline()
end
end
@@ -130,7 +130,7 @@ function M._toggle_fold(move_cursor, node_index)
end
local function setup_buffer_autocmd()
if config.options.auto_preview then
if cfg.o.preview_window.auto_preview then
vim.api.nvim_create_autocmd('CursorMoved', {
buffer = 0,
callback = require('symbols-outline.preview').show,
@@ -141,7 +141,7 @@ local function setup_buffer_autocmd()
callback = require('symbols-outline.preview').close,
})
end
if config.options.auto_goto then
if cfg.o.outline_window.auto_goto then
vim.api.nvim_create_autocmd('CursorMoved', {
buffer = 0,
callback = function()
@@ -261,76 +261,76 @@ local function setup_keymaps(bufnr)
utils.nmap(bufnr, ...)
end
-- goto_location of symbol and focus that window
map(config.options.keymaps.goto_location, function()
map(cfg.o.keymaps.goto_location, function()
M._goto_location(true)
end)
-- goto_location of symbol but stay in outline
map(config.options.keymaps.peek_location, function()
map(cfg.o.keymaps.peek_location, function()
M._goto_location(false)
end)
-- Navigate to corresponding outline location for current code location
map(config.options.keymaps.restore_location, function()
map(cfg.o.keymaps.restore_location, function()
M._map_follow_cursor()
end)
-- Move down/up in outline and peek that location in code
map(config.options.keymaps.down_and_goto, function()
map(cfg.o.keymaps.down_and_goto, function()
M._move_and_goto('down')
end)
-- Move down/up in outline and peek that location in code
map(config.options.keymaps.up_and_goto, function()
map(cfg.o.keymaps.up_and_goto, function()
M._move_and_goto('up')
end)
-- hover symbol
map(
config.options.keymaps.hover_symbol,
cfg.o.keymaps.hover_symbol,
require('symbols-outline.hover').show_hover
)
-- preview symbol
map(
config.options.keymaps.toggle_preview,
cfg.o.keymaps.toggle_preview,
require('symbols-outline.preview').toggle
)
-- rename symbol
map(
config.options.keymaps.rename_symbol,
cfg.o.keymaps.rename_symbol,
require('symbols-outline.rename').rename
)
-- code actions
map(
config.options.keymaps.code_actions,
cfg.o.keymaps.code_actions,
require('symbols-outline.code_action').show_code_actions
)
-- show help
map(
config.options.keymaps.show_help,
cfg.o.keymaps.show_help,
require('symbols-outline.config').show_help
)
-- close outline
map(config.options.keymaps.close, function()
map(cfg.o.keymaps.close, function()
M.view:close()
end)
-- toggle fold selection
map(config.options.keymaps.fold_toggle, M._toggle_fold)
map(cfg.o.keymaps.fold_toggle, M._toggle_fold)
-- fold selection
map(config.options.keymaps.fold, function()
map(cfg.o.keymaps.fold, function()
M._set_folded(true)
end)
-- unfold selection
map(config.options.keymaps.unfold, function()
map(cfg.o.keymaps.unfold, function()
M._set_folded(false)
end)
-- toggle fold all
map(config.options.keymaps.fold_toggle_all, M._toggle_all_fold)
map(cfg.o.keymaps.fold_toggle_all, M._toggle_all_fold)
-- fold all
map(config.options.keymaps.fold_all, function()
map(cfg.o.keymaps.fold_all, function()
M._set_all_folded(true)
end)
-- unfold all
map(config.options.keymaps.unfold_all, function()
map(cfg.o.keymaps.unfold_all, function()
M._set_all_folded(false)
end)
-- fold reset
map(config.options.keymaps.fold_reset, function()
map(cfg.o.keymaps.fold_reset, function()
M._set_all_folded(nil)
end)
end
@@ -362,7 +362,7 @@ local function handler(response, opts)
M._highlight_current_item(M.state.code_win)
if not config.options.focus_on_open or (opts and not opts.focus_outline) then
if not cfg.o.outline_window.focus_on_open or (opts and not opts.focus_outline) then
vim.fn.win_gotoid(M.state.code_win)
end
end
@@ -561,7 +561,7 @@ end
---Set up configuration options for symbols-outline.
function M.setup(opts)
config.setup(opts)
cfg.setup(opts)
ui.setup_highlights()
M.view = View:new()

View File

@@ -1,6 +1,6 @@
local symbols = require 'symbols-outline.symbols'
local ui = require 'symbols-outline.ui'
local config = require 'symbols-outline.config'
local cfg = require 'symbols-outline.config'
local t_utils = require 'symbols-outline.utils.table'
local lsp_utils = require 'symbols-outline.utils.lsp_utils'
local folding = require 'symbols-outline.folding'
@@ -17,7 +17,7 @@ local function parse_result(result, depth, hierarchy, parent)
local ret = {}
for index, value in pairs(result) do
if not config.is_symbol_blacklisted(symbols.kinds[value.kind]) then
if not cfg.is_symbol_blacklisted(symbols.kinds[value.kind]) then
-- the hierarchy is basically a table of booleans which tells whether
-- the parent was the last in its group or not
local hir = hierarchy or {}
@@ -99,7 +99,7 @@ function M.get_lines(flattened_outline_items)
for node_line, node in ipairs(flattened_outline_items) do
local depth = node.depth
local marker_space = (config.options.fold_markers and 1) or 0
local marker_space = (cfg.o.symbol_folding.markers and 1) or 0
local line = t_utils.str_to_table(string.rep(' ', depth + marker_space))
local running_length = 1
@@ -118,15 +118,15 @@ function M.get_lines(flattened_outline_items)
end
for index, _ in ipairs(line) do
if config.options.guides.enabled then
local guide_markers = config.options.guides.markers
if cfg.o.guides.enabled then
local guide_markers = cfg.o.guides.markers
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
-- add fold markers
local fold_markers = config.options.fold_markers
local fold_markers = cfg.o.symbol_folding.markers
if fold_markers and folding.is_foldable(node) then
if folding.is_folded(node) then
line[index] = fold_markers[1]
@@ -184,14 +184,14 @@ function M.get_lines(flattened_outline_items)
local hl_start = #string_prefix
local hl_end = #string_prefix + #node.icon
local hl_type = config.options.symbols[symbols.kinds[node.kind]].hl
local hl_type = cfg.o.symbols.icons[symbols.kinds[node.kind]].hl
table.insert(hl_info, { node_line, hl_start, hl_end, hl_type })
node.prefix_length = #string_prefix + #node.icon + 1
end
local final_hl = {}
if config.options.show_symbol_lineno then
if cfg.o.outline_items.show_symbol_lineno then
-- Width of the highest lineno value
local max_width = #tostring(lineno_max)
-- Padded prefix to the right of lineno for better readability if linenos
@@ -209,7 +209,7 @@ function M.get_lines(flattened_outline_items)
})
node.prefix_length = node.prefix_length + total_offset
end
if config.options.guides.enabled then
if cfg.o.guides.enabled then
for _, hl in ipairs(guide_hl_info) do
table.insert(final_hl, {
hl[1],
@@ -222,7 +222,7 @@ function M.get_lines(flattened_outline_items)
else
-- Merge lists hl_info and guide_hl_info
final_hl = hl_info
if config.options.guides.enabled then
if cfg.o.guides.enabled then
for _, hl in ipairs(guide_hl_info) do
table.insert(final_hl, hl)
end

View File

@@ -1,5 +1,5 @@
local so = require 'symbols-outline'
local config = require 'symbols-outline.config'
local cfg = require 'symbols-outline.config'
local hover = require 'symbols-outline.hover'
local M = {}
@@ -31,11 +31,11 @@ local function get_offset()
local width = 53
local height = 0
if config.has_numbers() then
if cfg.has_numbers() then
width = width + 4
end
if config.options.position == 'right' then
if cfg.o.outline_window.position == 'right' then
width = 0 - width
else
width = vim.api.nvim_win_get_width(outline_winnr) + 1
@@ -91,10 +91,10 @@ local function setup_preview_buf()
end
local function set_bg_hl()
local winhi = 'Normal:' .. config.options.preview_bg_highlight
local winhi = 'Normal:' .. cfg.o.preview_window.bg_hl
vim.api.nvim_win_set_option(state.preview_win, 'winhighlight', winhi)
-- vim.api.nvim_win_set_option(state.hover_win, 'winhighlight', winhi)
local winblend = config.options.winblend
local winblend = cfg.o.preview_window.winblend
vim.api.nvim_win_set_option(state.preview_win, 'winblend', winblend)
-- vim.api.nvim_win_set_option(state.hover_win, 'winblend', winblend)
end
@@ -119,7 +119,7 @@ local function show_preview()
col = offsets[2],
-- Position preview window middle-aligned vertically
row = math.ceil((height - winheight) / 2),
border = config.options.border,
border = cfg.o.preview_window.border,
})
setup_preview_buf()
else
@@ -134,7 +134,7 @@ function M.show()
show_preview()
set_bg_hl()
if config.options.open_hover_on_preview then
if cfg.o.preview_window.open_hover_on_preview then
hover.show_hover()
end
end

View File

@@ -19,7 +19,7 @@ function M.rename()
local params = get_rename_params(node, so.state.code_win)
local new_name = vim.fn.input('New Name: ', node.name)
local new_name = vim.fn.input({ prompt = 'New Name: ', default = node.name })
if not new_name or new_name == '' or new_name == node.name then
return
end

View File

@@ -40,7 +40,7 @@ M.kinds = {
}
function M.icon_from_kind(kind)
local symbols = config.options.symbols
local symbols = config.o.symbols.icons
if type(kind) == 'string' then
return symbols[kind].icon

View File

@@ -1,4 +1,4 @@
local config = require 'symbols-outline.config'
local cfg = require('symbols-outline.config')
local View = {}
@@ -14,9 +14,9 @@ function View:setup_view()
-- delete buffer when window is closed / buffer is hidden
vim.api.nvim_buf_set_option(self.bufnr, 'bufhidden', 'delete')
-- create a split
vim.cmd(config.get_split_command())
vim.cmd(cfg.get_split_command())
-- resize to a % of the current window size
vim.cmd('vertical resize ' .. config.get_window_width())
vim.cmd('vertical resize ' .. cfg.get_window_width())
-- get current (outline) window and attach our buffer to it
self.winnr = vim.api.nvim_get_current_win()
@@ -30,7 +30,7 @@ function View:setup_view()
vim.api.nvim_win_set_option(self.winnr, 'relativenumber', false)
vim.api.nvim_win_set_option(self.winnr, 'winfixwidth', true)
vim.api.nvim_win_set_option(self.winnr, 'list', false)
vim.api.nvim_win_set_option(self.winnr, 'wrap', config.options.wrap)
vim.api.nvim_win_set_option(self.winnr, 'wrap', cfg.o.outline_window.wrap)
vim.api.nvim_win_set_option(self.winnr, 'linebreak', true) -- only has effect when wrap=true
vim.api.nvim_win_set_option(self.winnr, 'breakindent', true) -- only has effect when wrap=true
-- Would be nice to use guides.markers.vertical as part of showbreak to keep
@@ -43,15 +43,15 @@ function View:setup_view()
vim.api.nvim_buf_set_option(self.bufnr, 'filetype', 'Outline')
vim.api.nvim_buf_set_option(self.bufnr, 'modifiable', false)
if config.options.show_numbers or config.options.show_relative_numbers then
if cfg.o.outline_window.show_numbers or cfg.o.outline_window.show_relative_numbers then
vim.api.nvim_win_set_option(self.winnr, 'nu', true)
end
if config.options.show_relative_numbers then
if cfg.o.outline_window.show_relative_numbers then
vim.api.nvim_win_set_option(self.winnr, 'rnu', true)
end
if config.options.show_cursorline then
if cfg.o.outline_window.show_cursorline then
vim.api.nvim_win_set_option(self.winnr, 'cursorline', true)
end
end

View File

@@ -1,5 +1,5 @@
local parser = require 'symbols-outline.parser'
local config = require 'symbols-outline.config'
local cfg = require('symbols-outline.config')
local ui = require 'symbols-outline.ui'
local M = {}
@@ -52,7 +52,7 @@ function M.write_details(bufnr, lines)
if not is_buffer_outline(bufnr) then
return
end
if not config.options.show_symbol_details then
if not cfg.o.outline_items.show_symbol_details then
return
end
@@ -69,7 +69,7 @@ function M.write_lineno(bufnr, lines, max)
if not is_buffer_outline(bufnr) then
return
end
if not config.options.show_symbol_lineno then
if not cfg.o.outline_items.show_symbol_lineno then
return
end
local maxwidth = #tostring(max)
@@ -90,7 +90,7 @@ local function clear_virt_text(bufnr)
end
M.add_hover_highlights = function(bufnr, nodes)
if not config.options.highlight_hovered_item then
if not cfg.o.outline_items.highlight_hovered_item then
return
end
@@ -101,7 +101,7 @@ M.add_hover_highlights = function(bufnr, nodes)
goto continue
end
local marker_fac = (config.options.fold_markers and 1) or 0
local marker_fac = (cfg.o.symbol_folding.markers and 1) or 0
if node.prefix_length then
ui.add_hover_highlight(
bufnr,