update: updates
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
local M = {}
|
||||
|
||||
function M.input_args()
|
||||
local argument_string = vim.fn.input("Program arg(s) (enter nothing to leave it null): ")
|
||||
return vim.fn.split(argument_string, " ", true)
|
||||
end
|
||||
|
||||
function M.input_exec_path()
|
||||
return vim.fn.input('Path to executable (default to "a.out"): ', vim.fn.expand("%:p:h") .. "/a.out", "file")
|
||||
end
|
||||
|
||||
function M.input_file_path()
|
||||
return vim.fn.input("Path to debuggee (default to the current file): ", vim.fn.expand("%:p"), "file")
|
||||
end
|
||||
|
||||
function M.get_env()
|
||||
local variables = {}
|
||||
for k, v in pairs(vim.fn.environ()) do
|
||||
table.insert(variables, string.format("%s=%s", k, v))
|
||||
end
|
||||
return variables
|
||||
end
|
||||
|
||||
return setmetatable({}, {
|
||||
__index = function(_, key)
|
||||
return function()
|
||||
return function()
|
||||
return M[key]()
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
@@ -0,0 +1,240 @@
|
||||
local icons = {}
|
||||
|
||||
local data = {
|
||||
kind = {
|
||||
Break = "",
|
||||
Call = "",
|
||||
Case = "",
|
||||
Class = "",
|
||||
Color = "",
|
||||
Constant = "",
|
||||
Constructor = "",
|
||||
Continue = "",
|
||||
Declaration = "",
|
||||
Delete = "",
|
||||
Enum = "",
|
||||
EnumMember = "",
|
||||
Event = "",
|
||||
Field = "",
|
||||
File = "",
|
||||
Folder = "",
|
||||
Fragment = "",
|
||||
Function = "",
|
||||
Implementation = "",
|
||||
Interface = "",
|
||||
Keyword = "",
|
||||
List = "",
|
||||
Loop = "",
|
||||
Method = "",
|
||||
Module = "",
|
||||
Namespace = "",
|
||||
Operator = "",
|
||||
Package = "",
|
||||
Property = "",
|
||||
Reference = "",
|
||||
Regex = "",
|
||||
Snippet = "",
|
||||
Statement = "",
|
||||
Struct = "",
|
||||
Switch = "",
|
||||
Text = "",
|
||||
TypeParameter = "",
|
||||
Undefined = "",
|
||||
Unit = "",
|
||||
Value = "",
|
||||
Variable = "",
|
||||
-- ccls-specific icons
|
||||
Macro = "",
|
||||
Parameter = "",
|
||||
StaticMethod = "",
|
||||
Terminal = "",
|
||||
TypeAlias = "",
|
||||
},
|
||||
type = {
|
||||
Array = "",
|
||||
Boolean = "",
|
||||
Null = "",
|
||||
Number = "",
|
||||
Object = "",
|
||||
String = "",
|
||||
},
|
||||
documents = {
|
||||
Default = "",
|
||||
File = "",
|
||||
Files = "",
|
||||
FileFind = "",
|
||||
FileTree = "",
|
||||
Import = "",
|
||||
Symlink = "",
|
||||
Word = "",
|
||||
},
|
||||
git = {
|
||||
Add = "",
|
||||
Branch = "",
|
||||
Diff = "",
|
||||
Git = "",
|
||||
Ignore = "",
|
||||
Mod = "M",
|
||||
Mod_alt = "",
|
||||
Remove = "",
|
||||
Rename = "",
|
||||
Repo = "",
|
||||
Unmerged = "",
|
||||
Untracked = "",
|
||||
Unstaged = "",
|
||||
Staged = "",
|
||||
Conflict = "",
|
||||
},
|
||||
ui = {
|
||||
Accepted = "",
|
||||
ArrowClosed = "",
|
||||
ArrowOpen = "",
|
||||
BigCircle = "",
|
||||
BigUnfilledCircle = "",
|
||||
BookMark = "",
|
||||
Buffer = "",
|
||||
Bug = "",
|
||||
Calendar = "",
|
||||
Character = "",
|
||||
Check = "",
|
||||
ChevronRight = "",
|
||||
Circle = "",
|
||||
Close = "",
|
||||
Close_alt = "",
|
||||
CloudDownload = "",
|
||||
CodeAction = "",
|
||||
Comment = "",
|
||||
Dashboard = "",
|
||||
DoubleSeparator = "",
|
||||
Emoji = "",
|
||||
EmptyFolder = "",
|
||||
EmptyFolderOpen = "",
|
||||
File = "",
|
||||
Fire = "",
|
||||
Folder = "",
|
||||
FolderOpen = "",
|
||||
FolderWithHeart = "",
|
||||
Gear = "",
|
||||
History = "",
|
||||
Incoming = "",
|
||||
Indicator = "",
|
||||
Keyboard = "",
|
||||
Left = "",
|
||||
List = "",
|
||||
Lock = "",
|
||||
Modified = "✥",
|
||||
Modified_alt = "",
|
||||
NewFile = "",
|
||||
Newspaper = "",
|
||||
Note = "",
|
||||
Outgoing = "",
|
||||
Package = "",
|
||||
Pencil = "",
|
||||
Perf = "",
|
||||
Play = "",
|
||||
Project = "",
|
||||
Right = "",
|
||||
RootFolderOpened = "",
|
||||
Search = "",
|
||||
Separator = "",
|
||||
SignIn = "",
|
||||
SignOut = "",
|
||||
Sort = "",
|
||||
Spell = "",
|
||||
Square = "",
|
||||
Symlink = "",
|
||||
SymlinkFolder = "",
|
||||
Tab = "",
|
||||
Table = "",
|
||||
Telescope = "",
|
||||
Window = "",
|
||||
},
|
||||
diagnostics = {
|
||||
Error = "",
|
||||
Warning = "",
|
||||
Information = "",
|
||||
Question = "",
|
||||
Hint = "",
|
||||
-- Hollow version
|
||||
Error_alt = "",
|
||||
Warning_alt = "",
|
||||
Information_alt = "",
|
||||
Question_alt = "",
|
||||
Hint_alt = "",
|
||||
},
|
||||
misc = {
|
||||
Add = "+",
|
||||
Added = "",
|
||||
Campass = "",
|
||||
Code = "",
|
||||
Gavel = "",
|
||||
Ghost = "",
|
||||
Glass = "",
|
||||
Lego = "",
|
||||
LspAvailable = "",
|
||||
ManUp = "",
|
||||
Neovim = "",
|
||||
NoActiveLsp = "",
|
||||
PyEnv = "",
|
||||
Squirrel = "",
|
||||
Tag = "",
|
||||
Tree = "",
|
||||
Vbar = "│",
|
||||
Vim = "",
|
||||
Watch = "",
|
||||
},
|
||||
cmp = {
|
||||
buffer = "",
|
||||
latex_symbols = "",
|
||||
luasnip = "",
|
||||
nvim_lsp = "",
|
||||
nvim_lua = "",
|
||||
orgmode = "",
|
||||
path = "",
|
||||
spell = "",
|
||||
tmux = "",
|
||||
treesitter = "",
|
||||
undefined = "",
|
||||
-- Add source-specific icons here
|
||||
codeium = "",
|
||||
Codeium = "",
|
||||
copilot = "",
|
||||
copilot_alt = "",
|
||||
Copilot = "",
|
||||
Copilot_alt = "",
|
||||
TabNine = "",
|
||||
cmp_tabnine = "",
|
||||
},
|
||||
dap = {
|
||||
Breakpoint = "",
|
||||
BreakpointCondition = "",
|
||||
BreakpointRejected = "",
|
||||
LogPoint = "",
|
||||
Pause = "",
|
||||
Play = "",
|
||||
RunLast = "↻",
|
||||
StepBack = "",
|
||||
StepInto = "",
|
||||
StepOut = "",
|
||||
StepOver = "",
|
||||
Stopped = "",
|
||||
Terminate = "",
|
||||
},
|
||||
}
|
||||
|
||||
---Get a specific icon set.
|
||||
---@param category "kind"|"type"|"documents"|"git"|"ui"|"diagnostics"|"misc"|"cmp"|"dap"
|
||||
---@param add_space? boolean @Add trailing whitespace after the icon.
|
||||
function icons.get(category, add_space)
|
||||
if add_space then
|
||||
return setmetatable({}, {
|
||||
__index = function(_, key)
|
||||
return data[category][key] .. " "
|
||||
end,
|
||||
})
|
||||
else
|
||||
return data[category]
|
||||
end
|
||||
end
|
||||
|
||||
return icons
|
||||
@@ -0,0 +1,370 @@
|
||||
local M = {}
|
||||
|
||||
---@class palette
|
||||
---@field rosewater string
|
||||
---@field flamingo string
|
||||
---@field mauve string
|
||||
---@field pink string
|
||||
---@field red string
|
||||
---@field maroon string
|
||||
---@field peach string
|
||||
---@field yellow string
|
||||
---@field green string
|
||||
---@field sapphire string
|
||||
---@field blue string
|
||||
---@field sky string
|
||||
---@field teal string
|
||||
---@field lavender string
|
||||
---@field text string
|
||||
---@field subtext1 string
|
||||
---@field subtext0 string
|
||||
---@field overlay2 string
|
||||
---@field overlay1 string
|
||||
---@field overlay0 string
|
||||
---@field surface2 string
|
||||
---@field surface1 string
|
||||
---@field surface0 string
|
||||
---@field base string
|
||||
---@field mantle string
|
||||
---@field crust string
|
||||
---@field none "NONE"
|
||||
|
||||
---@type nil|palette
|
||||
local palette = nil
|
||||
|
||||
-- Indicates if autocmd for refreshing the builtin palette has already been registered
|
||||
---@type boolean
|
||||
local _has_autocmd = false
|
||||
|
||||
---Initialize the palette
|
||||
---@return palette
|
||||
local function init_palette()
|
||||
-- Reinitialize the palette on event `ColorScheme`
|
||||
if not _has_autocmd then
|
||||
_has_autocmd = true
|
||||
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||
group = vim.api.nvim_create_augroup("__builtin_palette", { clear = true }),
|
||||
pattern = "*",
|
||||
callback = function()
|
||||
palette = nil
|
||||
init_palette()
|
||||
-- Also refresh hard-coded hl groups
|
||||
M.gen_alpha_hl()
|
||||
M.gen_lspkind_hl()
|
||||
pcall(vim.cmd.AlphaRedraw)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
if not palette then
|
||||
palette = vim.g.colors_name:find("catppuccin") and require("catppuccin.palettes").get_palette()
|
||||
or {
|
||||
rosewater = "#DC8A78",
|
||||
flamingo = "#DD7878",
|
||||
mauve = "#CBA6F7",
|
||||
pink = "#F5C2E7",
|
||||
red = "#E95678",
|
||||
maroon = "#B33076",
|
||||
peach = "#FF8700",
|
||||
yellow = "#F7BB3B",
|
||||
green = "#AFD700",
|
||||
sapphire = "#36D0E0",
|
||||
blue = "#61AFEF",
|
||||
sky = "#04A5E5",
|
||||
teal = "#B5E8E0",
|
||||
lavender = "#7287FD",
|
||||
|
||||
text = "#F2F2BF",
|
||||
subtext1 = "#BAC2DE",
|
||||
subtext0 = "#A6ADC8",
|
||||
overlay2 = "#C3BAC6",
|
||||
overlay1 = "#988BA2",
|
||||
overlay0 = "#6E6B6B",
|
||||
surface2 = "#6E6C7E",
|
||||
surface1 = "#575268",
|
||||
surface0 = "#302D41",
|
||||
|
||||
base = "#1D1536",
|
||||
mantle = "#1C1C19",
|
||||
crust = "#161320",
|
||||
}
|
||||
|
||||
palette = vim.tbl_extend("force", { none = "NONE" }, palette, require("core.settings").palette_overwrite)
|
||||
end
|
||||
|
||||
return palette
|
||||
end
|
||||
|
||||
---@param c string @The color in hexadecimal.
|
||||
local function hex_to_rgb(c)
|
||||
c = string.lower(c)
|
||||
return { tonumber(c:sub(2, 3), 16), tonumber(c:sub(4, 5), 16), tonumber(c:sub(6, 7), 16) }
|
||||
end
|
||||
|
||||
-- NOTE: If the active colorscheme isn't `catppuccin`, this function won't overwrite existing definitions
|
||||
---Sets a global highlight group.
|
||||
---@param name string @Highlight group name, e.g. "ErrorMsg"
|
||||
---@param foreground string @The foreground color
|
||||
---@param background? string @The background color
|
||||
---@param italic? boolean
|
||||
local function set_global_hl(name, foreground, background, italic)
|
||||
vim.api.nvim_set_hl(0, name, {
|
||||
fg = foreground,
|
||||
bg = background,
|
||||
italic = italic == true,
|
||||
default = not vim.g.colors_name:find("catppuccin"),
|
||||
})
|
||||
end
|
||||
|
||||
---Blend foreground with background
|
||||
---@param foreground string @The foreground color
|
||||
---@param background string @The background color to blend with
|
||||
---@param alpha number|string @Number between 0 and 1 for blending amount.
|
||||
function M.blend(foreground, background, alpha)
|
||||
alpha = type(alpha) == "string" and (tonumber(alpha, 16) / 0xff) or alpha
|
||||
local bg = hex_to_rgb(background)
|
||||
local fg = hex_to_rgb(foreground)
|
||||
|
||||
local blend_channel = function(i)
|
||||
local ret = (alpha * fg[i] + ((1 - alpha) * bg[i]))
|
||||
return math.floor(math.min(math.max(0, ret), 255) + 0.5)
|
||||
end
|
||||
|
||||
return string.format("#%02x%02x%02x", blend_channel(1), blend_channel(2), blend_channel(3))
|
||||
end
|
||||
|
||||
---Get RGB highlight by highlight group
|
||||
---@param hl_group string @Highlight group name
|
||||
---@param use_bg boolean @Returns background or not
|
||||
---@param fallback_hl? string @Fallback value if the hl group is not defined
|
||||
---@return string
|
||||
function M.hl_to_rgb(hl_group, use_bg, fallback_hl)
|
||||
local hex = fallback_hl or "#000000"
|
||||
local hlexists = pcall(vim.api.nvim_get_hl, 0, { name = hl_group, link = false })
|
||||
|
||||
if hlexists then
|
||||
local result = vim.api.nvim_get_hl(0, { name = hl_group, link = false })
|
||||
if use_bg then
|
||||
hex = result.bg and string.format("#%06x", result.bg) or "NONE"
|
||||
else
|
||||
hex = result.fg and string.format("#%06x", result.fg) or "NONE"
|
||||
end
|
||||
end
|
||||
|
||||
return hex
|
||||
end
|
||||
|
||||
---Extend a highlight group
|
||||
---@param name string @Target highlight group name
|
||||
---@param def table @Attributes to be extended
|
||||
function M.extend_hl(name, def)
|
||||
local hlexists = pcall(vim.api.nvim_get_hl, 0, { name = name, link = false })
|
||||
if not hlexists then
|
||||
-- Do nothing if highlight group not found
|
||||
return
|
||||
end
|
||||
local current_def = vim.api.nvim_get_hl(0, { name = name, link = false })
|
||||
local combined_def = vim.tbl_deep_extend("force", current_def, def)
|
||||
|
||||
vim.api.nvim_set_hl(0, name, combined_def)
|
||||
end
|
||||
|
||||
---Generate universal highlight groups
|
||||
---@param overwrite palette? @The color to be overwritten | highest priority
|
||||
---@return palette
|
||||
function M.get_palette(overwrite)
|
||||
if not overwrite then
|
||||
return vim.deepcopy(init_palette())
|
||||
else
|
||||
return vim.tbl_extend("force", init_palette(), overwrite)
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate highlight groups for lspsaga. Existing attributes will NOT be overwritten
|
||||
function M.gen_lspkind_hl()
|
||||
local colors = M.get_palette()
|
||||
local dat = {
|
||||
Class = colors.yellow,
|
||||
Constant = colors.peach,
|
||||
Constructor = colors.sapphire,
|
||||
Enum = colors.yellow,
|
||||
EnumMember = colors.teal,
|
||||
Event = colors.yellow,
|
||||
Field = colors.teal,
|
||||
File = colors.rosewater,
|
||||
Function = colors.blue,
|
||||
Interface = colors.yellow,
|
||||
Key = colors.red,
|
||||
Method = colors.blue,
|
||||
Module = colors.blue,
|
||||
Namespace = colors.blue,
|
||||
Number = colors.peach,
|
||||
Operator = colors.sky,
|
||||
Package = colors.blue,
|
||||
Property = colors.teal,
|
||||
Struct = colors.yellow,
|
||||
TypeParameter = colors.blue,
|
||||
Variable = colors.peach,
|
||||
Array = colors.peach,
|
||||
Boolean = colors.peach,
|
||||
Null = colors.yellow,
|
||||
Object = colors.yellow,
|
||||
String = colors.green,
|
||||
TypeAlias = colors.green,
|
||||
Parameter = colors.blue,
|
||||
StaticMethod = colors.peach,
|
||||
Text = colors.green,
|
||||
Snippet = colors.mauve,
|
||||
Folder = colors.blue,
|
||||
Unit = colors.green,
|
||||
Value = colors.peach,
|
||||
}
|
||||
|
||||
for kind, color in pairs(dat) do
|
||||
set_global_hl("LspKind" .. kind, color)
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate highlight groups for alpha. Existing attributes will NOT be overwritten
|
||||
function M.gen_alpha_hl()
|
||||
local colors = M.get_palette()
|
||||
|
||||
set_global_hl("AlphaHeader", colors.blue)
|
||||
set_global_hl("AlphaButtons", colors.green)
|
||||
set_global_hl("AlphaShortcut", colors.pink, nil, true)
|
||||
set_global_hl("AlphaFooter", colors.yellow)
|
||||
end
|
||||
|
||||
-- Generate blend_color for neodim.
|
||||
function M.gen_neodim_blend_attr()
|
||||
local trans_bg = require("core.settings").transparent_background
|
||||
local appearance = require("core.settings").background
|
||||
|
||||
if trans_bg and appearance == "dark" then
|
||||
return "#000000"
|
||||
elseif trans_bg and appearance == "light" then
|
||||
return "#FFFFFF"
|
||||
else
|
||||
return M.hl_to_rgb("Normal", true)
|
||||
end
|
||||
end
|
||||
|
||||
---Convert number (0/1) to boolean
|
||||
---@param value number @The value to check
|
||||
---@return boolean|nil @Returns nil if failed
|
||||
function M.tobool(value)
|
||||
if value == 0 then
|
||||
return false
|
||||
elseif value == 1 then
|
||||
return true
|
||||
else
|
||||
vim.notify(
|
||||
"Attempting to convert data of type '" .. type(value) .. "' [other than 0 or 1] to boolean",
|
||||
vim.log.levels.ERROR,
|
||||
{ title = "[utils] Runtime Error" }
|
||||
)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Function to recursively merge src into dst
|
||||
--- Unlike vim.tbl_deep_extend(), this function extends if the original value is a list
|
||||
---@paramm dst table @Table which will be modified and appended to
|
||||
---@paramm src table @Table from which values will be inserted
|
||||
---@return table @Modified table
|
||||
local function tbl_recursive_merge(dst, src)
|
||||
for key, value in pairs(src) do
|
||||
if type(dst[key]) == "table" and type(value) == "function" then
|
||||
dst[key] = value(dst[key])
|
||||
elseif type(dst[key]) == "table" and vim.islist(dst[key]) and key ~= "dashboard_image" then
|
||||
vim.list_extend(dst[key], value)
|
||||
elseif type(dst[key]) == "table" and type(value) == "table" and not vim.islist(dst[key]) then
|
||||
tbl_recursive_merge(dst[key], value)
|
||||
else
|
||||
dst[key] = value
|
||||
end
|
||||
end
|
||||
return dst
|
||||
end
|
||||
|
||||
-- Function to extend existing core configs (settings, events, etc.)
|
||||
---@param config table @The default config to be merged with
|
||||
---@param user_config string @The module name used to require user config
|
||||
---@return table @Extended config
|
||||
function M.extend_config(config, user_config)
|
||||
local ok, extras = pcall(require, user_config)
|
||||
if ok and type(extras) == "table" then
|
||||
config = tbl_recursive_merge(config, extras)
|
||||
end
|
||||
return config
|
||||
end
|
||||
|
||||
---@param plugin_name string @Module name of the plugin (used to setup itself)
|
||||
---@param opts nil|table @The default config to be merged with
|
||||
---@param vim_plugin? boolean @If this plugin is written in vimscript or not
|
||||
---@param setup_callback? function @Add new callback if the plugin needs unusual setup function
|
||||
function M.load_plugin(plugin_name, opts, vim_plugin, setup_callback)
|
||||
vim_plugin = vim_plugin or false
|
||||
|
||||
-- Get the file name of the default config
|
||||
local fname = debug.getinfo(2, "S").source:match("[^@/\\]*.lua$")
|
||||
local ok, user_config = pcall(require, "user.configs." .. fname:sub(0, #fname - 4))
|
||||
if ok and vim_plugin then
|
||||
if user_config == false then
|
||||
-- Return early if the user explicitly requires disabling plugin setup
|
||||
return
|
||||
elseif type(user_config) == "function" then
|
||||
-- OK, setup as instructed by the user
|
||||
user_config()
|
||||
else
|
||||
vim.notify(
|
||||
string.format(
|
||||
"<%s> is not a typical Lua plugin, please return a function with\nthe corresponding options defined instead (usually via `vim.g.*`)",
|
||||
plugin_name
|
||||
),
|
||||
vim.log.levels.ERROR,
|
||||
{ title = "[utils] Runtime Error (User Config)" }
|
||||
)
|
||||
end
|
||||
elseif not vim_plugin then
|
||||
if user_config == false then
|
||||
-- Return early if the user explicitly requires disabling plugin setup
|
||||
return
|
||||
else
|
||||
setup_callback = setup_callback or require(plugin_name).setup
|
||||
-- User config exists?
|
||||
if ok then
|
||||
-- Extend base config if the returned user config is a table
|
||||
if type(user_config) == "table" then
|
||||
opts = tbl_recursive_merge(opts, user_config)
|
||||
setup_callback(opts)
|
||||
-- Replace base config if the returned user config is a function
|
||||
elseif type(user_config) == "function" then
|
||||
local user_opts = user_config(opts)
|
||||
if type(user_opts) == "table" then
|
||||
setup_callback(user_opts)
|
||||
end
|
||||
else
|
||||
vim.notify(
|
||||
string.format(
|
||||
[[
|
||||
Please return a `table` if you want to override some of the default options OR a
|
||||
`function` returning a `table` if you want to replace the default options completely.
|
||||
|
||||
We received a `%s` for plugin <%s>.]],
|
||||
type(user_config),
|
||||
plugin_name
|
||||
),
|
||||
vim.log.levels.ERROR,
|
||||
{ title = "[utils] Runtime Error (User Config)" }
|
||||
)
|
||||
end
|
||||
else
|
||||
-- Nothing provided... Fallback as default setup of the plugin
|
||||
setup_callback(opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,205 @@
|
||||
local M = {}
|
||||
|
||||
---Shortcut for `nvim_replace_termcodes`.
|
||||
---@param keys string
|
||||
---@return string
|
||||
local function termcodes(keys)
|
||||
return vim.api.nvim_replace_termcodes(keys, true, true, true)
|
||||
end
|
||||
|
||||
---Returns if two key sequence are equal or not.
|
||||
---@param a string
|
||||
---@param b string
|
||||
---@return boolean
|
||||
local function keymap_equals(a, b)
|
||||
return termcodes(a) == termcodes(b)
|
||||
end
|
||||
|
||||
---Get map
|
||||
---@param mode string
|
||||
---@param lhs string
|
||||
---@return table
|
||||
local function get_map(mode, lhs)
|
||||
for _, map in ipairs(vim.api.nvim_buf_get_keymap(0, mode)) do
|
||||
if keymap_equals(map.lhs, lhs) then
|
||||
vim.api.nvim_buf_del_keymap(0, mode, lhs)
|
||||
return {
|
||||
lhs = map.lhs,
|
||||
rhs = map.rhs or "",
|
||||
expr = map.expr == 1,
|
||||
callback = map.callback,
|
||||
noremap = map.noremap == 1,
|
||||
script = map.script == 1,
|
||||
silent = map.silent == 1,
|
||||
nowait = map.nowait == 1,
|
||||
buffer = true,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
for _, map in ipairs(vim.api.nvim_get_keymap(mode)) do
|
||||
if keymap_equals(map.lhs, lhs) then
|
||||
vim.api.nvim_del_keymap(mode, lhs)
|
||||
return {
|
||||
lhs = map.lhs,
|
||||
rhs = map.rhs or "",
|
||||
expr = map.expr == 1,
|
||||
callback = map.callback,
|
||||
noremap = map.noremap == 1,
|
||||
script = map.script == 1,
|
||||
silent = map.silent == 1,
|
||||
nowait = map.nowait == 1,
|
||||
buffer = false,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
lhs = lhs,
|
||||
rhs = lhs,
|
||||
expr = false,
|
||||
callback = nil,
|
||||
noremap = true,
|
||||
script = false,
|
||||
silent = true,
|
||||
nowait = false,
|
||||
buffer = false,
|
||||
}
|
||||
end
|
||||
|
||||
---Returns the function constructed from the passed keymap object on call of
|
||||
---which the original keymapping will be executed.
|
||||
---@param map table keymap object
|
||||
---@return function
|
||||
local function get_fallback(map)
|
||||
return function()
|
||||
local keys, fmode
|
||||
if map.expr then
|
||||
if map.callback then
|
||||
keys = map.callback()
|
||||
else
|
||||
keys = vim.api.nvim_eval(map.rhs)
|
||||
end
|
||||
elseif map.callback then
|
||||
map.callback()
|
||||
return
|
||||
else
|
||||
keys = map.rhs
|
||||
end
|
||||
keys = termcodes(keys)
|
||||
fmode = map.noremap and "in" or "im"
|
||||
vim.api.nvim_feedkeys(keys, fmode, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Amends a mapping (i.e., allows fallback when certain conditions are met)
|
||||
---@param cond string
|
||||
---@param mode string
|
||||
---@param lhs string
|
||||
---@param rhs function
|
||||
---@param opts? table
|
||||
local function amend(cond, mode, lhs, rhs, opts)
|
||||
local map = get_map(mode, lhs)
|
||||
local fallback = get_fallback(map)
|
||||
local options = vim.deepcopy(opts) or {}
|
||||
options.desc = table.concat({
|
||||
"[" .. cond,
|
||||
(options.desc and ": " .. options.desc or ""),
|
||||
"]",
|
||||
(map.desc and " / " .. map.desc or ""),
|
||||
})
|
||||
vim.keymap.set(mode, lhs, function()
|
||||
rhs(fallback)
|
||||
end, options)
|
||||
end
|
||||
|
||||
-- Completely replace a mapping
|
||||
---@param mode string
|
||||
---@param lhs string
|
||||
---@param rhs string
|
||||
---@param opts? table
|
||||
---@param buf? boolean|number
|
||||
local function replace(mode, lhs, rhs, opts, buf)
|
||||
get_map(mode, lhs)
|
||||
|
||||
local options = vim.deepcopy(opts) or {}
|
||||
if buf and type(buf) == "number" then
|
||||
vim.api.nvim_buf_set_keymap(buf, mode, lhs, rhs, options)
|
||||
else
|
||||
vim.api.nvim_set_keymap(mode, lhs, rhs, options)
|
||||
end
|
||||
end
|
||||
|
||||
---Amend the existing keymap.
|
||||
---@param cond string
|
||||
---@param mode string | string[]
|
||||
---@param lhs string
|
||||
---@param rhs function
|
||||
---@param opts? table
|
||||
local function modes_amend(cond, mode, lhs, rhs, opts)
|
||||
if type(mode) == "table" then
|
||||
for _, m in ipairs(mode) do
|
||||
amend(cond, m, lhs, rhs, opts)
|
||||
end
|
||||
else
|
||||
amend(cond, mode, lhs, rhs, opts)
|
||||
end
|
||||
end
|
||||
|
||||
---Replace the existing keymap.
|
||||
---@param mode string | string[]
|
||||
---@param lhs string
|
||||
---@param rhs string
|
||||
---@param opts? table
|
||||
---@param buf? boolean|number
|
||||
local function modes_replace(mode, lhs, rhs, opts, buf)
|
||||
if type(mode) == "table" then
|
||||
for _, m in ipairs(mode) do
|
||||
replace(m, lhs, rhs, opts, buf)
|
||||
end
|
||||
else
|
||||
replace(mode, lhs, rhs, opts, buf)
|
||||
end
|
||||
end
|
||||
|
||||
---Amend the existing keymap.
|
||||
---@param cond string
|
||||
---@param global_flag string
|
||||
---@param mapping table<string, map_rhs>
|
||||
function M.amend(cond, global_flag, mapping)
|
||||
for key, value in pairs(mapping) do
|
||||
local modes, keymap = key:match("([^|]*)|?(.*)")
|
||||
if type(value) == "table" then
|
||||
local rhs = value.cmd
|
||||
local options = value.options
|
||||
modes_amend(cond, vim.split(modes, ""), keymap, function(fallback)
|
||||
if _G[global_flag] then
|
||||
local fmode = options.noremap and "in" or "im"
|
||||
vim.api.nvim_feedkeys(termcodes(rhs), fmode, false)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Replace the existing keymap.
|
||||
---@param mapping table<string, map_rhs>
|
||||
function M.replace(mapping)
|
||||
for key, value in pairs(mapping) do
|
||||
local modes, keymap = key:match("([^|]*)|?(.*)")
|
||||
if type(value) == "table" then
|
||||
local rhs = value.cmd
|
||||
local options = value.options
|
||||
local buffer = value.buffer
|
||||
modes_replace(vim.split(modes, ""), keymap, rhs, options, buffer)
|
||||
elseif value == "" or value == false then
|
||||
for _, m in ipairs(vim.split(modes, "")) do
|
||||
get_map(m, keymap)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user