1

Regenerate nvim config

This commit is contained in:
2024-06-02 03:29:20 +02:00
parent 75eea0c030
commit ef2e28883d
5576 changed files with 604886 additions and 503 deletions

View File

@ -0,0 +1,137 @@
local M = {}
local config = {
providers = {
'lsp',
'treesitter',
'regex',
},
delay = 100,
filetype_overrides = {},
filetypes_denylist = {
'dirbuf',
'dirvish',
'fugitive',
},
filetypes_allowlist = {},
modes_denylist = {},
modes_allowlist = {},
providers_regex_syntax_denylist = {},
providers_regex_syntax_allowlist = {},
under_cursor = true,
max_file_lines = nil,
large_file_cutoff = nil,
large_file_config = nil,
min_count_to_highlight = 1,
should_enable = nil,
case_insensitive_regex = false,
}
function M.set(config_overrides)
config = vim.tbl_extend('force', config, config_overrides or {})
end
function M.get_raw()
return config
end
function M.get()
return (
M.large_file_cutoff() == nil
or vim.fn.line('$') <= M.large_file_cutoff()
or M.large_file_overrides() == nil
)
and config
or M.large_file_overrides()
end
function M.filetype_override(bufnr)
local ft = vim.api.nvim_buf_get_option(bufnr, 'filetype')
return M.get()['filetype_overrides'] and M.get()['filetype_overrides'][ft] or {}
end
function M.providers(bufnr)
return M.filetype_override(bufnr)['providers'] or M.get()['providers']
end
function M.filetypes_denylist()
return M.get()['filetypes_denylist'] or {}
end
function M.filetypes_allowlist()
return M.get()['filetypes_allowlist'] or {}
end
function M.modes_denylist(bufnr)
return M.filetype_override(bufnr)['modes_denylist'] or M.get()['modes_denylist'] or {}
end
function M.modes_allowlist(bufnr)
return M.filetype_override(bufnr)['modes_allowlist'] or M.get()['modes_allowlist'] or {}
end
function M.provider_regex_syntax_denylist(bufnr)
return M.filetype_override(bufnr)['providers_regex_syntax_denylist']
or M.get()['providers_regex_syntax_denylist']
or {}
end
function M.provider_regex_syntax_allowlist(bufnr)
return M.filetype_override(bufnr)['providers_regex_syntax_allowlist']
or M.get()['providers_regex_syntax_allowlist']
or {}
end
function M.under_cursor(bufnr)
if M.filetype_override(bufnr)['under_cursor'] ~= nil then
return M.filetype_override(bufnr)['under_cursor'] ~= nil
end
return M.get()['under_cursor']
end
function M.delay(bufnr)
local delay = M.filetype_override(bufnr)['delay'] or M.get()['delay'] or 17
if string.sub(vim.api.nvim_get_mode().mode, 1, 1) == 'i' then
delay = delay + 100
end
if delay < 17 then
return 17
end
return delay
end
function M.max_file_lines()
return M.get()['max_file_lines']
end
function M.large_file_cutoff()
return config['large_file_cutoff']
end
function M.large_file_overrides()
if config['large_file_overrides'] ~= nil then
if config['large_file_overrides']['under_cursor'] == nil then
config['large_file_overrides']['under_cursor'] = true
end
return config['large_file_overrides']
end
return {
filetypes_allowlist = { '_none' }
}
end
function M.min_count_to_highlight()
return M.get()['min_count_to_highlight'] or 1
end
function M.should_enable()
return M.get()['should_enable'] or function(_)
return true
end
end
function M.case_insensitive_regex()
return M.get()['case_insensitive_regex']
end
return M

View File

@ -0,0 +1,267 @@
local hl = require('illuminate.highlight')
local ref = require('illuminate.reference')
local config = require('illuminate.config')
local util = require('illuminate.util')
local M = {}
local AUGROUP = 'vim_illuminate_v2_augroup'
local timers = {}
local paused_bufs = {}
local stopped_bufs = {}
local is_paused = false
local written = {}
local error_timestamps = {}
local frozen_bufs = {}
local invisible_bufs = {}
local started = false
local function buf_should_illuminate(bufnr)
if is_paused or paused_bufs[bufnr] or stopped_bufs[bufnr] then
return false
end
return config.should_enable()(bufnr)
and (config.max_file_lines() == nil or vim.fn.line('$') <= config.max_file_lines())
and util.is_allowed(
config.modes_allowlist(bufnr),
config.modes_denylist(bufnr),
vim.api.nvim_get_mode().mode
) and util.is_allowed(
config.filetypes_allowlist(),
config.filetypes_denylist(),
vim.api.nvim_buf_get_option(bufnr, 'filetype')
)
end
local function stop_timer(timer)
if vim.loop.is_active(timer) then
vim.loop.timer_stop(timer)
vim.loop.close(timer)
end
end
function M.start()
started = true
vim.api.nvim_create_augroup(AUGROUP, { clear = true })
vim.api.nvim_create_autocmd({ 'VimEnter', 'CursorMoved', 'CursorMovedI', 'ModeChanged', 'TextChanged' }, {
group = AUGROUP,
callback = function()
M.refresh_references()
end,
})
-- If vim.lsp.buf.format is called, this will call vim.api.nvim_buf_set_text which messes up extmarks.
-- By using this `written` variable, we can ensure refresh_references doesn't terminate early based on
-- ref.buf_cursor_in_references being incorrect (we have references but they're not actually showing
-- as illuminated). vim.lsp.buf.format will trigger CursorMoved so we don't need to do it here.
vim.api.nvim_create_autocmd({ 'BufWritePost' }, {
group = AUGROUP,
callback = function()
written[vim.api.nvim_get_current_buf()] = true
end,
})
vim.api.nvim_create_autocmd({ 'VimLeave' }, {
group = AUGROUP,
callback = function()
for _, timer in pairs(timers) do
stop_timer(timer)
end
end,
})
end
function M.stop()
started = false
vim.api.nvim_create_augroup(AUGROUP, { clear = true })
end
--- Get the highlighted references for the item under the cursor for
--- @bufnr and clears any old reference highlights
---
--- @bufnr (number)
function M.refresh_references(bufnr, winid)
bufnr = bufnr or vim.api.nvim_get_current_buf()
winid = winid or vim.api.nvim_get_current_win()
if frozen_bufs[bufnr] then
return
end
if not buf_should_illuminate(bufnr) then
hl.buf_clear_references(bufnr)
ref.buf_set_references(bufnr, {})
return
end
-- We might want to optimize here by returning early if cursor is in references.
-- The downside is that LSP servers can sometimes return a different list of references
-- as you move around an existing reference (like return statements).
if written[bufnr] or not ref.buf_cursor_in_references(bufnr, util.get_cursor_pos(winid)) then
hl.buf_clear_references(bufnr)
ref.buf_set_references(bufnr, {})
elseif config.large_file_cutoff() ~= nil and vim.fn.line('$') > config.large_file_cutoff() then
return
end
written[bufnr] = nil
if timers[bufnr] then
stop_timer(timers[bufnr])
end
local provider = M.get_provider(bufnr)
if not provider then return end
pcall(provider['initiate_request'], bufnr, winid)
local changedtick = vim.api.nvim_buf_get_changedtick(bufnr)
local timer = vim.loop.new_timer()
timers[bufnr] = timer
timer:start(config.delay(bufnr), 17, vim.schedule_wrap(function()
local ok, err = pcall(function()
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
stop_timer(timer)
return
end
hl.buf_clear_references(bufnr)
ref.buf_set_references(bufnr, {})
if vim.api.nvim_buf_get_changedtick(bufnr) ~= changedtick
or vim.api.nvim_get_current_win() ~= winid
or bufnr ~= vim.api.nvim_win_get_buf(0) then
stop_timer(timer)
return
end
provider = M.get_provider(bufnr)
if not provider then
stop_timer(timer)
return
end
local references = provider.get_references(bufnr, util.get_cursor_pos(winid))
if references ~= nil then
ref.buf_set_references(bufnr, references)
if ref.buf_cursor_in_references(bufnr, util.get_cursor_pos(winid)) then
if not invisible_bufs[bufnr] == true then
hl.buf_highlight_references(bufnr, ref.buf_get_references(bufnr))
end
else
ref.buf_set_references(bufnr, {})
end
stop_timer(timer)
end
end)
if not ok then
local time = vim.loop.hrtime()
if #error_timestamps == 5 then
vim.notify(
'vim-illuminate: An internal error has occured: ' .. vim.inspect(ok) .. vim.inspect(err),
vim.log.levels.ERROR,
{}
)
M.stop()
stop_timer(timer)
elseif #error_timestamps == 0 or time - error_timestamps[#error_timestamps] < 500000000 then
table.insert(error_timestamps, time)
else
error_timestamps = { time }
end
end
end))
end
function M.get_provider(bufnr)
for _, provider in ipairs(config.providers(bufnr) or {}) do
local ok, providerModule = pcall(require, string.format('illuminate.providers.%s', provider))
if ok and providerModule.is_ready(bufnr) then
return providerModule, provider
end
end
return nil
end
function M.pause()
is_paused = true
M.refresh_references()
end
function M.resume()
is_paused = false
M.refresh_references()
end
function M.toggle()
is_paused = not is_paused
M.refresh_references()
end
function M.toggle_buf(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
if paused_bufs[bufnr] then
paused_bufs[bufnr] = nil
else
paused_bufs[bufnr] = true
end
M.refresh_references()
end
function M.pause_buf(bufnr)
paused_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
M.refresh_references()
end
function M.resume_buf(bufnr)
paused_bufs[bufnr or vim.api.nvim_get_current_buf()] = nil
M.refresh_references()
end
function M.stop_buf(bufnr)
stopped_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
M.refresh_references()
end
function M.freeze_buf(bufnr)
frozen_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
end
function M.unfreeze_buf(bufnr)
frozen_bufs[bufnr or vim.api.nvim_get_current_buf()] = nil
end
function M.toggle_freeze_buf(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
frozen_bufs[bufnr] = not frozen_bufs[bufnr]
end
function M.invisible_buf(bufnr)
invisible_bufs[bufnr or vim.api.nvim_get_current_buf()] = true
M.refresh_references()
end
function M.visible_buf(bufnr)
invisible_bufs[bufnr or vim.api.nvim_get_current_buf()] = nil
M.refresh_references()
end
function M.toggle_visibility_buf(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
invisible_bufs[bufnr] = not invisible_bufs[bufnr]
M.refresh_references()
end
function M.debug()
local bufnr = vim.api.nvim_get_current_buf()
print('buf_should_illuminate', bufnr, buf_should_illuminate(bufnr))
print('config', vim.inspect(config.get_raw()))
print('started', started)
print('provider', M.get_provider(bufnr))
print('`termguicolors`', vim.opt.termguicolors:get())
end
function M.is_paused()
return is_paused
end
return M

View File

@ -0,0 +1,63 @@
local util = require('illuminate.util')
local ref = require('illuminate.reference')
local engine = require('illuminate.engine')
local M = {}
function M.goto_next_reference(wrap)
local bufnr = vim.api.nvim_get_current_buf()
local winid = vim.api.nvim_get_current_win()
local cursor_pos = util.get_cursor_pos(winid)
if #ref.buf_get_references(bufnr) == 0 then
return
end
local i = ref.bisect_left(ref.buf_get_references(bufnr), cursor_pos)
i = i + 1
if i > #ref.buf_get_references(bufnr) then
if wrap then
i = 1
else
vim.api.nvim_err_writeln("E384: vim-illuminate: goto_next_reference hit BOTTOM of the references")
return
end
end
local pos, _ = unpack(ref.buf_get_references(bufnr)[i])
local new_cursor_pos = { pos[1] + 1, pos[2] }
vim.cmd('normal! m`')
engine.freeze_buf(bufnr)
vim.api.nvim_win_set_cursor(winid, new_cursor_pos)
engine.unfreeze_buf(bufnr)
end
function M.goto_prev_reference(wrap)
local bufnr = vim.api.nvim_get_current_buf()
local winid = vim.api.nvim_get_current_win()
local cursor_pos = util.get_cursor_pos(winid)
if #ref.buf_get_references(bufnr) == 0 then
return
end
local i = ref.bisect_left(ref.buf_get_references(bufnr), cursor_pos)
i = i - 1
if i == 0 then
if wrap then
i = #ref.buf_get_references(bufnr)
else
vim.api.nvim_err_writeln("E384: vim-illuminate: goto_prev_reference hit TOP of the references")
return
end
end
local pos, _ = unpack(ref.buf_get_references(bufnr)[i])
local new_cursor_pos = { pos[1] + 1, pos[2] }
vim.cmd('normal! m`')
engine.freeze_buf(bufnr)
vim.api.nvim_win_set_cursor(winid, new_cursor_pos)
engine.unfreeze_buf(bufnr)
end
return M

View File

@ -0,0 +1,59 @@
local util = require('illuminate.util')
local config = require('illuminate.config')
local ref = require('illuminate.reference')
local M = {}
local HL_NAMESPACE = vim.api.nvim_create_namespace('illuminate.highlight')
local function kind_to_hl_group(kind)
return kind == vim.lsp.protocol.DocumentHighlightKind.Text and 'IlluminatedWordText'
or kind == vim.lsp.protocol.DocumentHighlightKind.Read and 'IlluminatedWordRead'
or kind == vim.lsp.protocol.DocumentHighlightKind.Write and 'IlluminatedWordWrite'
or 'IlluminatedWordText'
end
function M.buf_highlight_references(bufnr, references)
if config.min_count_to_highlight() > #references then
return
end
local cursor_pos = util.get_cursor_pos()
for _, reference in ipairs(references) do
if config.under_cursor(bufnr) or not ref.is_pos_in_ref(cursor_pos, reference) then
M.range(
bufnr,
reference[1],
reference[2],
reference[3]
)
end
end
end
function M.range(bufnr, start, finish, kind)
local region = vim.region(bufnr, start, finish, 'v', false)
for linenr, cols in pairs(region) do
if linenr == -1 then
linenr = 0
end
local end_row
if cols[2] == -1 then
end_row = linenr + 1
cols[2] = 0
end
vim.api.nvim_buf_set_extmark(bufnr, HL_NAMESPACE, linenr, cols[1], {
hl_group = kind_to_hl_group(kind),
end_row = end_row,
end_col = cols[2],
priority = 199,
strict = false,
})
end
end
function M.buf_clear_references(bufnr)
vim.api.nvim_buf_clear_namespace(bufnr, HL_NAMESPACE, 0, -1)
end
return M

View File

@ -0,0 +1,130 @@
local M = {}
local bufs = {}
local function _str_byteindex_enc(line, col, encoding)
if not encoding then
encoding = 'utf-16'
end
if encoding == 'utf-8' then
if col then
return col
else
return #line
end
elseif encoding == 'utf-16' then
return vim.str_byteindex(line, col, true)
elseif encoding == 'utf-32' then
return vim.str_byteindex(line, col)
else
return col
end
end
local function get_line_byte_from_position(bufnr, line, col, offset_encoding)
if col == 0 then
return col
end
local lines = vim.api.nvim_buf_get_lines(bufnr, line, line + 1, false)
if not lines or #lines == 0 then
return col
end
local ok, result = pcall(_str_byteindex_enc, lines[1], col, offset_encoding)
if ok then
return result
end
return math.min(#(lines[1]), col)
end
function M.get_references(bufnr)
if not bufs[bufnr] or not bufs[bufnr][3] then
return nil
end
return bufs[bufnr][3]
end
function M.is_ready(bufnr)
local supported = false
-- For nvim 0.10+
if vim.lsp.get_clients then
supported = false
for _, client in ipairs(vim.lsp.get_clients({bufnr = bufnr})) do
if client and client.supports_method('textDocument/documentHighlight') then
supported = true
end
end
-- For older versions
elseif vim.lsp.for_each_buffer_client then
supported = false
vim.lsp.for_each_buffer_client(bufnr, function(client)
if client and client.supports_method('textDocument/documentHighlight') then
supported = true
end
end)
end
return supported
end
function M.initiate_request(bufnr, winid)
local id = 1
if bufs[bufnr] then
local prev_id, cancel_fn, references = unpack(bufs[bufnr])
if references == nil then
pcall(cancel_fn)
end
id = prev_id + 1
end
local cancel_fn = vim.lsp.buf_request_all(
bufnr,
'textDocument/documentHighlight',
vim.lsp.util.make_position_params(winid),
function(client_results)
if bufs[bufnr][1] ~= id then
return
end
if not vim.api.nvim_buf_is_valid(bufnr) then
bufs[bufnr][3] = {}
return
end
local references = {}
for client_id, results in pairs(client_results) do
local client = vim.lsp.get_client_by_id(client_id)
if client and results['result'] then
for _, res in ipairs(results['result']) do
local start_col = get_line_byte_from_position(
bufnr,
res['range']['start']['line'],
res['range']['start']['character'],
res['offset_encoding']
)
local end_col = get_line_byte_from_position(
bufnr,
res['range']['end']['line'],
res['range']['end']['character'],
res['offset_encoding']
)
table.insert(references, {
{ res['range']['start']['line'], start_col },
{ res['range']['end']['line'], end_col },
res['kind'],
})
end
end
end
bufs[bufnr][3] = references
end
)
bufs[bufnr] = {
id,
cancel_fn,
}
end
return M

View File

@ -0,0 +1,74 @@
local config = require('illuminate.config')
local util = require('illuminate.util')
local M = {}
local START_WORD_REGEX = vim.regex([[^\k*]])
local END_WORD_REGEX = vim.regex([[\k*$]])
-- foo
-- foo
-- Foo
-- fOo
local function get_cur_word(bufnr, cursor)
local line = vim.api.nvim_buf_get_lines(bufnr, cursor[1], cursor[1] + 1, false)[1]
local left_part = string.sub(line, 0, cursor[2] + 1)
local right_part = string.sub(line, cursor[2] + 1)
local start_idx, _ = END_WORD_REGEX:match_str(left_part)
local _, end_idx = START_WORD_REGEX:match_str(right_part)
local word = string.format('%s%s', string.sub(left_part, start_idx + 1), string.sub(right_part, 2, end_idx))
local modifiers = [[\V]]
if config.case_insensitive_regex() then
modifiers = modifiers .. [[\c]]
end
local ok, escaped = pcall(vim.fn.escape, word, [[/\]])
if ok then
return modifiers .. [[\<]] .. escaped .. [[\>]]
end
end
function M.get_references(bufnr, cursor)
local refs = {}
local ok, re = pcall(vim.regex, get_cur_word(bufnr, cursor))
if not ok then
return refs
end
local line_count = vim.api.nvim_buf_line_count(bufnr)
for i = 0, line_count - 1 do
local start_byte, end_byte = 0, 0
while true do
local start_offset, end_offset = re:match_line(bufnr, i, end_byte)
if not start_offset then break end
start_byte = end_byte + start_offset
end_byte = end_byte + end_offset
table.insert(refs, {
{ i, start_byte },
{ i, end_byte },
vim.lsp.protocol.DocumentHighlightKind.Text,
})
end
end
return refs
end
function M.is_ready(bufnr)
local name = vim.fn.synIDattr(
vim.fn.synIDtrans(
vim.fn.synID(vim.fn.line('.'), vim.fn.col('.'), 1)
),
'name'
)
if util.is_allowed(
config.provider_regex_syntax_allowlist(bufnr),
config.provider_regex_syntax_denylist(bufnr),
name
) then
return true
end
return false
end
return M

View File

@ -0,0 +1,51 @@
local ts_utils = require('nvim-treesitter.ts_utils')
local locals = require('nvim-treesitter.locals')
local M = {}
local buf_attached = {}
function M.get_references(bufnr)
local node_at_point = ts_utils.get_node_at_cursor()
if not node_at_point then
return
end
local refs = {}
local def_node, scope = locals.find_definition(node_at_point, bufnr)
if def_node ~= node_at_point then
local range = { def_node:range() }
table.insert(refs, {
{ range[1], range[2] },
{ range[3], range[4] },
vim.lsp.protocol.DocumentHighlightKind.Write,
})
end
local usages = locals.find_usages(def_node, scope, bufnr)
for _, node in ipairs(usages) do
local range = { node:range() }
table.insert(refs, {
{ range[1], range[2] },
{ range[3], range[4] },
vim.lsp.protocol.DocumentHighlightKind.Read,
})
end
return refs
end
function M.is_ready(bufnr)
return buf_attached[bufnr] and vim.api.nvim_buf_get_option(bufnr, 'filetype') ~= 'yaml'
end
function M.attach(bufnr)
buf_attached[bufnr] = true
end
function M.detach(bufnr)
buf_attached[bufnr] = nil
end
return M

View File

@ -0,0 +1,91 @@
local M = {}
-- @table pos
-- @field 1 (number) line (0-indexed)
-- @field 2 (number) col (0-indexed)
--
-- @table ref
-- @field 1 (table) start pos
-- @field 2 (table) end pos
local buf_references = {}
local function get_references(bufnr)
return buf_references[bufnr] or {}
end
local function pos_before(pos1, pos2)
if pos1[1] < pos2[1] then return true end
if pos1[1] > pos2[1] then return false end
if pos1[2] < pos2[2] then return true end
return false
end
local function pos_equal(pos1, pos2)
return pos1[1] == pos2[1] and pos1[2] == pos2[2]
end
local function ref_before(ref1, ref2)
return pos_before(ref1[1], ref2[1]) or pos_equal(ref1[1], ref2[1]) and pos_before(ref1[2], ref2[2])
end
local function buf_sort_references(bufnr)
local should_sort = false
for i, ref in ipairs(get_references(bufnr)) do
if i > 1 then
if not ref_before(get_references(bufnr)[i - 1], ref) then
should_sort = true
break
end
end
end
if should_sort then
table.sort(get_references(bufnr), ref_before)
end
end
function M.is_pos_in_ref(pos, ref)
return (pos_before(ref[1], pos) or pos_equal(ref[1], pos)) and (pos_before(pos, ref[2]) or pos_equal(pos, ref[2]))
end
function M.bisect_left(references, pos)
local l, r = 1, #references + 1
while l < r do
local m = l + math.floor((r - l) / 2)
if pos_before(references[m][2], pos) then
l = m + 1
else
r = m
end
end
return l
end
function M.buf_get_references(bufnr)
return get_references(bufnr)
end
function M.buf_set_references(bufnr, references)
buf_references[bufnr] = references
buf_sort_references(bufnr)
end
function M.buf_cursor_in_references(bufnr, cursor_pos)
if not get_references(bufnr) then
return false
end
local i = M.bisect_left(get_references(bufnr), cursor_pos)
if i > #get_references(bufnr) then
return false
end
if not M.is_pos_in_ref(cursor_pos, get_references(bufnr)[i]) then
return false
end
return true
end
return M

View File

@ -0,0 +1,42 @@
local util = require('illuminate.util')
local ref = require('illuminate.reference')
local M = {}
local visual_modes = {
['v'] = true,
['vs'] = true,
['V'] = true,
['Vs'] = true,
['CTRL-V'] = true,
['CTRL-Vs'] = true,
['s'] = true,
['S'] = true,
['CTRL-S'] = true,
}
function M.select()
local bufnr = vim.api.nvim_get_current_buf()
local winid = vim.api.nvim_get_current_win()
local cursor_pos = util.get_cursor_pos(winid)
if #ref.buf_get_references(bufnr) == 0 then
return
end
local i = ref.bisect_left(ref.buf_get_references(bufnr), cursor_pos)
if i > #ref.buf_get_references(bufnr) then
return
end
local reference = ref.buf_get_references(bufnr)[i]
vim.api.nvim_win_set_cursor(winid, { reference[1][1] + 1, reference[1][2] })
if not visual_modes[vim.api.nvim_get_mode().mode] then
vim.cmd('normal! v')
else
vim.cmd('normal! o')
end
vim.api.nvim_win_set_cursor(winid, { reference[2][1] + 1, reference[2][2] - 1 })
end
return M

View File

@ -0,0 +1,51 @@
local M = {}
function M.get_cursor_pos(winid)
winid = winid or vim.api.nvim_get_current_win()
local cursor = vim.api.nvim_win_get_cursor(winid)
cursor[1] = cursor[1] - 1 -- we always want line to be 0-indexed
return cursor
end
function M.list_to_set(list)
if list == nil then
return nil
end
local set = {}
for _, v in pairs(list) do
set[v] = true
end
return set
end
function M.is_allowed(allow_list, deny_list, thing)
if #allow_list == 0 and #deny_list == 0 then
return true
end
if #deny_list > 0 then
return not vim.tbl_contains(deny_list, thing)
end
return vim.tbl_contains(allow_list, thing)
end
function M.tbl_get(tbl, expected_type, ...)
local cur = tbl
for _, key in ipairs({ ... }) do
if type(cur) ~= 'table' or cur[key] == nil then
return nil
end
cur = cur[key]
end
return type(cur) == expected_type and cur or nil
end
function M.has_keymap(mode, lhs)
return vim.fn.mapcheck(lhs, mode) ~= ''
end
return M