Muh dotfiles

This commit is contained in:
2025-05-10 10:18:28 +03:00
commit 0f4558597e
84 changed files with 4306 additions and 0 deletions

View File

@ -0,0 +1,21 @@
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function() vim.highlight.on_yank() end
})
-- Doesn't trigger for manpages
vim.api.nvim_create_autocmd({ "BufReadPost", "BufWritePost", "BufNewFile" }, {
callback = vim.schedule_wrap(function()
vim.api.nvim_exec_autocmds("User", { pattern = "LazyFile" })
vim.schedule_wrap(vim.api.nvim_exec_autocmds)("User", { pattern = "VeryLazyFile" })
end)
})
vim.api.nvim_create_autocmd("LspAttach", { -- Overrides the default keymaps
callback = function(args)
vim.bo[args.buf].omnifunc = "v:lua.vim.lsp.omnifunc" -- <c-x><c-o>
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { buffer = args.buf })
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { buffer = args.buf })
end
})
--vim.api.nvim_create_autocmd("CursorHold", { callback = lsp.document_highlight })
--vim.api.nvim_create_autocmd("CursorMoved", { callback = lsp.clear_references })

View File

@ -0,0 +1,191 @@
local cmp = require "cmp"
local luasnip = require "luasnip"
local kinds = {
Enum = " Enum",
File = " File",
Text = " Text",
Unit = "󰑭 Unit",
Class = " Class",
Color = " Color",
Event = " Event",
Field = " Field",
Value = "󰎠 Value",
Folder = " Path",
Method = " Methd",
Module = " Modle",
Struct = "󰙅 Strct",
Keyword = "󰌋 Kword",
Snippet = " Snipp",
Constant = "󰏿 Const",
Function = "󰊕 Func",
Operator = " Oper",
Property = " Prop",
Variable = " Var",
Interface = " Itrfc",
Reference = "󰈇 Rfrnc",
EnumMember = " EnMem",
Constructor = "🏗 Cstctr",
TypeParameter = " TpPrm",
}
local function format_completion_entries(entry, vim_item) -- :h complete-items
vim_item.menu = ({
buffer = "[Buf]",
luasnip = "[LS]",
nvim_lsp = "[LSP]",
})[entry.source.name]
vim_item.kind = kinds[vim_item.kind] or "?"
return vim_item
end
-- Close the damn completion window
local function exit_completion()
vim.api.nvim_feedkeys("gi", "n", false)
end
local function register_oneshots()
for _, key in ipairs { "<CR>", "<Tab>", "<Space>", "<Down>", "<Up>", "<Left>", "<Right>" } do
vim.keymap.set("i", key, function()
exit_completion()
vim.keymap.del("i", key, { buffer = 0 })
return key
end, { buffer = 0, expr = true })
end
end
local function get_completion_buffers()
local buffers = {}
for _, win_id in ipairs(vim.api.nvim_list_wins()) do -- only visible buffers
local buf_id = vim.api.nvim_win_get_buf(win_id)
local buf_lines = vim.api.nvim_buf_line_count(buf_id)
local buf_bytes = vim.api.nvim_buf_get_offset(buf_id, buf_lines)
if buf_bytes < 196608 then -- 192 KiB
table.insert(buffers, buf_id)
end
end
return buffers
end
-- TODO use most common instead of just common
local function longest_common_completion()
cmp.complete { config = { -- should be fast asf
sources = {
{ name = "buffer", option = {
get_bufnrs = get_completion_buffers } },
-- { name = "nvim_lsp" }, -- there is other completion for lsp
},
performance = {
throttle = 0,
debounce = 15,
max_view_entries = 10,
fetching_timeout = 100
},
preselect = cmp.PreselectMode.None, -- not to mess up common_string
formatting = { format = false }
} }
return cmp.complete_common_string()
end
local mappings = {
["<C-n>"] = cmp.mapping.scroll_docs(4),
["<C-e>"] = cmp.mapping.scroll_docs(-4),
-- in my kitty.conf: map shift+space send_text all \033[32;2u
["<S-Space>"] = cmp.mapping.select_next_item(),
["<C-Space>"] = cmp.mapping.select_prev_item(),
["<S-Tab>"] = function()
if cmp.visible_docs() then
cmp.close_docs()
else
cmp.open_docs()
end
end,
-- My Caps is BS cuz caps is bs.
["<S-BS>"] = cmp.mapping(function()
if cmp.visible() then
exit_completion()
else
luasnip.expand_or_jump()
end
end, { "i", "s" }),
["<C-BS>"] = cmp.mapping(function()
if cmp.visible() then
cmp.abort()
exit_completion()
else
luasnip.jump(-1)
end
end, { "i", "s" }),
["<S-CR>"] = function()
if cmp.visible() then
cmp.confirm { select = true, behavior = cmp.ConfirmBehavior.Replace }
elseif cmp.complete() then
register_oneshots()
end
end,
["<C-CR>"] = function()
if cmp.visible() then
cmp.confirm { select = true, behavior = cmp.ConfirmBehavior.Insert }
elseif longest_common_completion() then
exit_completion()
else
register_oneshots()
end
end
}
cmp.setup.global { -- = cmp.setup
completion = {
autocomplete = false,
completeopt = "menu,menuone,noselect" -- noselect for complete_common_string
},
performance = {
--debounce = 60,
throttle = 15, -- 30
--fetching_timeout = 500,
max_view_entries = 40, -- 200
},
mapping = mappings,
preselect = cmp.PreselectMode.Item, -- Honour LSP preselect requests
--experimental = { ghost_text = true }
snippet = {
expand = function(args) luasnip.lsp_expand(args.body) end
},
formatting = {
expandable_indicator = true, -- show ~ indicator
fields = { "abbr", "kind", "menu" },
format = format_completion_entries,
},
view = {
docs = { auto_open = true },
entries = { name = "custom", selection_order = "near_cursor" }
},
sources = {
{ name = "nvim_lsp", group_index = 1 },
{ name = "luasnip", group_index = 2 },
{ name = "buffer", group_index = 2, option = {
indexing_interval = 100, -- default 100 ms
indexing_batch_size = 500, -- default 1000 lines
max_indexed_line_length = 2048, -- default 40*1024 bytes
get_bufnrs = get_completion_buffers
} }
},
window = {
completion = cmp.config.window.bordered {
side_padding = 0,
scrollbar = false,
border = vim.g.border_bleed
},
documentation = cmp.config.window.bordered {
side_padding = 0,
border = vim.g.border_bleed
}
}
}

View File

@ -0,0 +1,63 @@
local gs = require "gitsigns"
gs.setup {
auto_attach = true,
attach_to_untracked = false, -- use keymap
max_file_length = 10000,
update_debounce = 500,
-- base = "@", -- index by default
-- worktrees = {}, -- TODO for dotfiles
numhl = true,
signcolumn = false,
current_line_blame = false,
sign_priority = 6,
diff_opts = {
internal = true, -- for linematch
linematch = true, -- align lines
algorithm = "histogram", -- myers, minimal, patience, histrogram
},
preview_config = { border = vim.g.border_bleed },
}
-- Normal
Lmap("hb", "Blame line", gs.blame_line)
Lmap("hB", "Blame full", W(gs.blame_line) { full = true })
Lmap("hs", "Stage hunk", gs.stage_hunk)
Lmap("hr", "Reset hunk", gs.reset_hunk)
Lmap("hS", "Stage buffer", gs.stage_buffer)
Lmap("hR", "Reset buffer", gs.reset_buffer)
Lmap("hu", "Undo stage hunk", gs.undo_stage_hunk) -- only in current session
Lmap("hp", "Preview hunk", gs.preview_hunk)
Lmap("hi", "Inline preview", gs.preview_hunk_inline)
Lmap("hl", "List hunks", gs.setloclist)
Lmap("hq", "Qlist all hunks", W(gs.setqflist) "attached")
Lmap("hQ", "Qlist ALL hunks", W(gs.setqflist) "all")
Lmap("hs", "x", "Stage region", function() gs.stage_hunk { vim.fn.line ".", vim.fn.line "v" } end)
Lmap("hr", "x", "Reset region", function() gs.reset_hunk { vim.fn.line ".", vim.fn.line "v" } end)
-- Toggle
Lmap("hts", "Signs", gs.toggle_signs)
Lmap("htn", "Number hl", gs.toggle_numhl)
Lmap("htl", "Line hl", gs.toggle_linehl)
Lmap("htd", "Deleted", gs.toggle_deleted)
Lmap("htw", "Word diff", gs.toggle_word_diff)
Lmap("htb", "Blame", gs.toggle_current_line_blame)
-- View file
Lmap("hvh", "HEAD", W(gs.show) "@")
Lmap("hvp", "HEAD~", W(gs.show) "~")
Lmap("hvs", "Staged", gs.show)
Lmap("hvH", "Diff HEAD", W(gs.diffthis, "@", { split = "belowright" }))
Lmap("hvP", "Diff HEAD~", W(gs.diffthis, "~", { split = "belowright" }))
Lmap("hvS", "Diff Staged", W(gs.diffthis, nil, { split = "belowright" }))
-- Control
Lmap("hca", "Attach", gs.attach)
Lmap("hcd", "Detach", gs.detach)
Lmap("hcD", "Detach all", gs.detach_all)
Lmap("hcr", "Refresh", gs.refresh)
Lmap("hcs", "Base->staged", gs.change_base)
Lmap("hcS", "Base->staged all", W(gs.change_base, nil, true))
Lmap("hch", "Base->HEAD", W(gs.change_base) "@")
Lmap("hcH", "Base->HEAD all", W(gs.change_base, "@", true))
-- Other
vim.keymap.set({"x", "o"}, "ih", gs.select_hunk, { desc = "Select hunk" })
MakePair("h", "hunk", gs.next_hunk, gs.prev_hunk)

View File

@ -0,0 +1,30 @@
local lspconfig = require "lspconfig"
vim.diagnostic.config {
underline = true,
virtual_text = {
spacing = 4,
source = "if_many",
severity = { min = vim.diagnostic.severity.WARN },
},
-- virtual_lines = true,
severity_sort = true,
update_in_insert = false,
signs = { text = { "", "!", "󰙎", "󱠃" } }, -- E, W, I, H
float = { source = "if_many", border = vim.g.border_bleed },
}
lspconfig.util.default_config = vim.tbl_deep_extend("force", lspconfig.util.default_config, {
handlers = {
["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {
border = vim.g.border_bleed, max_width = 80
}),
["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, {
border = vim.g.border_bleed, max_width = 80
})
},
capabilities = pcall(require, "cmp_nvim_lsp") and
package.loaded.cmp_nvim_lsp.default_capabilities() or nil
})
require("lspconfig.ui.windows").default_options.border = vim.g.border -- :LspInfo

View File

@ -0,0 +1,94 @@
local telescope = require "telescope"
local builtin = require "telescope.builtin"
local layout = require "telescope.actions.layout"
--local actions = require "telescope.actions"
telescope.setup {
defaults = {
layout_strategy = "flex",
--preview = { hide_on_startup = true, filesize_limit = 0.1 --MB },
layout_config = {
vertical = { width = 0.9, height = 0.9 },
horizontal = { width = 0.9, height = 0.7 },
},
cycle_layout_list = { "vertical", "horizontal" },
-- borderchars = { "▔", "▕", "▁", "▏", "🭽", "🭾", "🭿", "🭼" },
path_display = { shorten = { len = 1, exclude = { -1 } } },
vimgrep_arguments = { -- live_grep & grep_string
"rg", "--color=never", "--no-heading", "--with-filename",
"--line-number", "--column", "--smart-case", "--trim" -- trim spaces
},
mappings = {
i = {
["<Esc>"] = "close",
["<C-d>"] = "delete_buffer", -- for buffers
["<C-h>"] = "select_horizontal", -- H| split
["<C-p>"] = layout.toggle_preview,
["<C-r>"] = layout.cycle_layout_next,
["<C-s>"] = "cycle_previewers_next", -- for git commits
["<C-a>"] = "cycle_previewers_prev",
["<C-n>"] = "preview_scrolling_down",
["<C-e>"] = "preview_scrolling_up",
["<C-Down>"] = "cycle_history_next",
["<C-Up>"] = "cycle_history_prev",
},
}
},
extensions = {
fzf = {
fuzzy = true,
override_generic_sorter = true,
override_file_sorter = true,
case_mode = "smart_case",
}
}
}
telescope.load_extension("fzf")
local which_key = package.loaded["which-key"]
if which_key then
which_key.add({
{ "<Leader>s", group = "Search" },
{ "<Leader>sh", group = "Git" },
{ "<Leader>sl", group = "LSP" },
})
end
Lmap("f", Try(builtin.git_files, builtin.find_files))
Lmap(".", function() builtin.find_files { cwd = vim.fn.expand("%:p:h") } end)
Lmap("/", builtin.current_buffer_fuzzy_find)
Lmap("so", builtin.oldfiles)
Lmap("sb", "Buffers", builtin.buffers)
Lmap("sf", "Files workdir", builtin.find_files)
Lmap("sn", "Nvim dotfiles", W(builtin.find_files) { cwd = vim.fn.expand("~/.config/nvim") })
Lmap("s.", "Dotfiles", W(builtin.find_files) { cwd = vim.fn.expand("~/.config/") })
Lmap("sd", "Diagnostics", builtin.diagnostics)
Lmap("ss", "Str in workdir", builtin.live_grep)
Lmap("sk", "Help tags", builtin.help_tags)
Lmap("sm", "Man pages", builtin.man_pages)
Lmap("s/", "/ history", builtin.search_history)
Lmap("sq", "Quickfix hist", builtin.quickfixhistory)
Lmap("sc", "nx", "Cursor workdir", builtin.grep_string)
Lmap("sp", "Pickers", builtin.pickers)
Lmap("sr", "Resume", builtin.resume)
Lmap("st", "Treesitter obj", builtin.treesitter)
-- Git
Lmap("shf", "Files", builtin.git_files)
Lmap("shs", "Status", builtin.git_status)
Lmap("shc", "Commits", builtin.git_commits)
Lmap("shB", "Branches", builtin.git_branches)
Lmap("shb", "Buf commits", builtin.git_bcommits)
-- LSP
Lmap("sld", "Definitions", builtin.lsp_definitions)
Lmap("slt", "Type defenitions", builtin.lsp_type_definitions)
Lmap("slr", "References", builtin.lsp_references)
Lmap("sli", "Incoming calls", builtin.lsp_incoming_calls)
Lmap("slo", "Outgoing calls", builtin.lsp_outgoing_calls)
Lmap("slm", "Implementations", builtin.lsp_implementations)
Lmap("sls", "Buffer symbols", builtin.lsp_document_symbols)
Lmap("slW", "Workspace symbols", builtin.lsp_workspace_symbols)
Lmap("slw", "Workspace dynamic", builtin.lsp_dynamic_workspace_symbols)
-- TODO Lmap("shb", "x", "Buf commits", builtin.git_bcommits_range)

View File

@ -0,0 +1,147 @@
local treesitter_config = {
auto_install = true,
sync_install = false,
ensure_installed = {
"arduino",
"bash",
"c",
"cmake",
"comment",
"cpp",
"c_sharp",
"diff",
"haskell",
"html",
"javascript",
"json",
"jsonc",
"lua",
"luadoc",
"luap",
"make",
"markdown",
"markdown_inline",
"ninja",
"python",
"query",
"regex",
"rust",
"toml",
"vim",
"vimdoc",
"yaml",
},
-- MODULES
indent = { enable = true }, -- for the `=` formatting
highlight = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<Tab>",
node_incremental = "<Tab>",
node_decremental = "<S-Tab>",
scope_incremental = "<C-Tab>",
}
}
}
treesitter_config.textobjects = {
select = {
enable = true,
lookahead = true, -- look for an object further in the file
include_surrounding_whitespace = false, -- disabled for Python
keymaps = { -- i - invocation, o - object, n - note, a - argument
["ai"] = "@call.outer", ["ic"] = "@conditional.inner",
["al"] = "@loop.outer", ["ia"] = "@parameter.inner",
["ak"] = "@block.outer", ["if"] = "@function.inner",
["ao"] = "@class.outer", ["in"] = "@comment.inner",
["ar"] = "@return.outer", ["ir"] = "@return.inner",
["an"] = "@comment.outer", ["io"] = "@class.inner",
["af"] = "@function.outer", ["ik"] = "@block.inner",
["aa"] = "@parameter.outer", ["il"] = "@loop.inner",
["as"] = "@assignment.outer", -- TODO
["ac"] = "@conditional.outer", ["ii"] = "@call.inner",
}
},
swap = {
enable = true,
swap_next = { -- a bit too much i guess... XD
[")i"] = "@call.inner", [")C"] = "@conditional.outer",
[")l"] = "@loop.inner", [")A"] = "@parameter.outer",
[")k"] = "@block.inner", [")F"] = "@function.outer",
[")o"] = "@class.inner", [")N"] = "@comment.outer",
[")r"] = "@return.inner", [")R"] = "@return.outer",
[")n"] = "@comment.inner", [")O"] = "@class.outer",
[")f"] = "@function.inner", [")K"] = "@block.outer",
[")a"] = "@parameter.inner", [")L"] = "@loop.outer",
[")c"] = "@conditional.inner", [")I"] = "@call.outer",
},
swap_previous = {
["(i"] = "@call.inner", ["(C"] = "@conditional.outer",
["(l"] = "@loop.inner", ["(A"] = "@parameter.outer",
["(k"] = "@block.inner", ["(F"] = "@function.outer",
["(o"] = "@class.inner", ["(N"] = "@comment.outer",
["(r"] = "@return.inner", ["(R"] = "@return.outer",
["(n"] = "@comment.inner", ["(O"] = "@class.outer",
["(f"] = "@function.inner", ["(K"] = "@block.outer",
["(a"] = "@parameter.inner", ["(L"] = "@loop.outer",
["(c"] = "@conditional.inner", ["(I"] = "@call.outer",
},
},
move = {
enable = true,
set_jumps = true, -- <C-o> back, <C-i> forward
goto_next = {},
goto_previous = {},
goto_next_start = {
["]i"] = "@call.outer", ["]c"] = "@conditional.outer",
["]l"] = "@loop.outer", -- ["]s"] = "@assignment.inner",
["]k"] = "@block.outer", ["]a"] = "@parameter.outer",
["]o"] = "@class.outer", ["]f"] = "@function.outer",
["]r"] = "@return.outer", ["]n"] = "@comment.outer",
},
goto_next_end = {
["]I"] = "@call.outer", ["]C"] = "@conditional.outer",
["]L"] = "@loop.outer", -- ["]S"] = "@assignment.inner",
["]K"] = "@block.outer", ["]A"] = "@parameter.outer",
["]O"] = "@class.outer", ["]F"] = "@function.outer",
["]R"] = "@return.outer", ["]N"] = "@comment.outer",
},
goto_previous_start = {
["[i"] = "@call.outer", ["[c"] = "@conditional.outer",
["[l"] = "@loop.outer", -- ["[s"] = "@assignment.inner",
["[k"] = "@block.outer", ["[a"] = "@parameter.outer",
["[o"] = "@class.outer", ["[f"] = "@function.outer",
["[r"] = "@return.outer", ["[n"] = "@comment.outer",
},
goto_previous_end = {
["[I"] = "@call.outer", ["[C"] = "@conditional.outer",
["[L"] = "@loop.outer", -- ["[S"] = "@assignment.inner",
["[K"] = "@block.outer", ["[A"] = "@parameter.outer",
["[O"] = "@class.outer", ["[F"] = "@function.outer",
["[R"] = "@return.outer", ["[N"] = "@comment.outer",
},
},
lsp_interop = {
enable = true, -- vim.lsp.util.open_floating_preview
floating_preview_opts = { border = vim.g.border_bleed },
peek_definition_code = {
["<Leader>lpo"] = { query = "@class.outer", desc = "Object" },
["<Leader>lpf"] = { query = "@function.outer", desc = "Function" },
["<Leader>lpa"] = { query = "@parameter.inner", desc = "Parameter" },
["<Leader>lps"] = { query = "@assignment.outer", desc = "Assignment" },
},
},
}
require("nvim-treesitter.configs").setup(treesitter_config)
local map = vim.keymap.set
local ts_repeat_move = require "nvim-treesitter.textobjects.repeatable_move"
map({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f_expr, {expr=true})
map({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F_expr, {expr=true})
map({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t_expr, {expr=true})
map({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T_expr, {expr=true})
map({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move)
map({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)

124
.config/nvim/lua/gpg.lua Normal file
View File

@ -0,0 +1,124 @@
--[[
TODO:
* make a plugin state table for each buffer
* what TO DO if also editing the file externally? have a decrypt fn?
* query for encryption parameters and be smart
* support key decryption & encryption
* write commands to manage parameters
MAYBE:
* be able to encrypt into binary? (bin decription works using file path and not buf contents)
* make fancy windows? why tho
AT LEAST TRY:
* ediding encrypted tar files. (is tar plugin even in Lua yet?)
]]
local function set_gpg_encrypt(passphrase)
-- Encrypt text within buffer. On error use old cipher.
vim.b.gpg_encrypt = function()
local result = vim.system(
{ "/usr/bin/gpg", "--batch", "--armor", "--symmetric", "--cipher-algo", "AES256", "--passphrase", passphrase },
{ env = {}, clear_env = true, stdin = vim.api.nvim_buf_get_lines(0, 0, -1, true), text = true }
):wait()
if result.code == 0 then
vim.b.backup_encrypted = vim.split(result.stdout, "\n", { trimempty = true })
else
vim.notify(result.stderr, vim.log.levels.ERROR)
end
vim.api.nvim_buf_set_lines(0, 0, -1, true, vim.b.backup_encrypted or {})
end
end
local gpg_group = vim.api.nvim_create_augroup("custom_gpg", { clear = true })
vim.api.nvim_create_autocmd({ "BufNewFile", "BufReadPre", "FilterReadPre", "FileReadPre" }, {
pattern = { "*.gpg", "*.asc" },
group = gpg_group,
callback = function() -- turn off options that write to disk
vim.opt_local.shada = ""
vim.opt_local.swapfile = false
vim.opt_local.undofile = false
end,
})
vim.api.nvim_create_autocmd({ "BufReadPost", "FileReadPost" }, {
pattern = { "*.gpg", "*.asc" },
group = gpg_group,
callback = function()
-- if vim.b.gpg_abort then return end
-- autocmd can't cancel :w, so for error cases using this backup cipher
vim.b.backup_encrypted = vim.api.nvim_buf_get_lines(0, 0, -1, true)
while true do
local passphrase = vim.fn.inputsecret("Enter passphrase to decrypt or 'q' to not: ")
if passphrase == "q" then
vim.b.gpg_abort = true
break
end
local result = vim.system(
{ "/usr/bin/gpg", "--batch", "--decrypt", "--passphrase",
passphrase, vim.api.nvim_buf_get_name(0) },
{ env = {}, clear_env = true, text = true }
):wait()
if result.code == 0 then
vim.api.nvim_buf_set_lines(0, 0, -1, true, vim.split(result.stdout:gsub("\n$", ""), "\n"))
set_gpg_encrypt(passphrase)
break
end
vim.notify(result.stderr, vim.log.levels.ERROR)
end
-- Execute BufReadPost without .gpg in filename
vim.api.nvim_exec_autocmds("BufReadPost", { pattern = vim.fn.expand("%:r") })
end,
})
-- Encrypt all text in buffer before writing
vim.api.nvim_create_autocmd({ "BufWritePre", "FileWritePre" }, {
pattern = { "*.gpg", "*.asc" },
group = gpg_group,
callback = function()
if vim.b.gpg_abort then
return
end
if vim.b.gpg_encrypt then
vim.b.gpg_encrypt()
return
end
vim.notify("Need passphrase to encrypt new file.", vim.log.levels.INFO)
while true do
local passphrase = vim.fn.inputsecret("Enter passphrase for encryption or 'q' to abort: ")
if passphrase == "q" then
vim.api.nvim_buf_set_lines(0, 0, -1, true, {}) -- can't stop writing operation
return
end
local passphrase2 = vim.fn.inputsecret("Repeat passphrase or 'q' to abort: ")
if passphrase2 == "q" then
vim.api.nvim_buf_set_lines(0, 0, -1, true, {}) -- can't stop writing operation
return
end
if passphrase == passphrase2 then
set_gpg_encrypt(passphrase)
vim.b.gpg_encrypt()
break
end
vim.notify("\nPassphrases do not match!", vim.log.levels.WARN)
end
end,
})
-- Undo the encryption in buffer after the file has been written
vim.api.nvim_create_autocmd({ "BufWritePost", "FileWritePost" }, {
pattern = { "*.gpg", "*.asc" },
group = gpg_group,
command = ":silent u",
})

View File

@ -0,0 +1,186 @@
-- LEADER
-- Utilities
Lmap("ul", "<Cmd>Lazy<CR>")
Lmap("um", "<Cmd>Mason<CR>")
Lmap("uL", "<Cmd>LspInfo<CR>")
Lmap("uc", "<Cmd>CmpStatus<CR>")
Lmap("un", "Netrw", vim.cmd.Ex)
-- Toggle stuff
local function toggle(o, a, b, p)
return function()
if vim.o[o] == a then vim.o[o] = b else vim.o[o] = a end
if p then vim.cmd("set "..o.."?") end
end
end
Lmap("tn", "Number", "<Cmd>set number!<CR>")
Lmap("ts", "Spellcheck", "<Cmd>set spell!<CR>")
Lmap("tl", "Cursorline", "<Cmd>set cursorline!<CR>")
Lmap("tr", "Relative num", "<Cmd>set relativenumber!<CR>")
-- Lmap("tw", "Wrap", "<Cmd>set wrap!<CR><Cmd>set wrap?<CR>")
Lmap("tw", "Wrap", toggle("wrap", true, false, 1))
Lmap("tb", "Statusline", toggle("ls", 0, 3))
Lmap("t:", "Cmd", toggle("ch", 0, 1))
Lmap("tc", "Column", toggle("cc", "80,100", ""))
-- Clipboard stuff
Lmap("p", "x", "Void paste", [["_dP]])
Lmap("p", "Clipboard paste", [["+p]])
Lmap("P", "Clipboard Paste", [["+P]])
Lmap("d", "nx", "Void delete", [["_d]])
Lmap("D", "nx", "Void Delete", [["_D]])
Lmap("y", "nx", "Clipboard yank", [["+y]])
Lmap("Y", "nx", "Clipboard Yank", [["+y$]])
-- Other
Lmap("g", "File name", "<Cmd>echo expand('%:p')<CR>")
-- Quickfix list
Lmap("co", "Open", "<Cmd>copen<CR>")
Lmap("cc", "Close", "<Cmd>cclose<CR>")
Lmap("cn", "Newer list", "<Cmd>cnewer<CR>")
Lmap("ce", "Older list", "<Cmd>colder<CR>")
Lmap("cl", "Last item", "<Cmd>clast<CR>")
Lmap("cf", "First item", "<Cmd>cfirst<CR>")
-- Location list
Lmap("Co", "Open", "<Cmd>lopen<CR>")
Lmap("Cc", "Close", "<Cmd>lclose<CR>")
Lmap("Cn", "Newer list", "<Cmd>lnewer<CR>")
Lmap("Ce", "Older list", "<Cmd>lolder<CR>")
Lmap("Cl", "Last item", "<Cmd>llast<CR>")
Lmap("Cf", "First item", "<Cmd>lfirst<CR>")
-- Buffers
Lmap("bd", "Delete", "<Cmd>bdelete<CR>")
Lmap("bu", "Unload", "<Cmd>bunload<CR>")
Lmap("bb", "Last accessed", "<Cmd>buffer#<CR>")
Lmap("bm", "Last modified", "<Cmd>bmodified<CR>")
Lmap("bh", "H- split with next", "<Cmd>sbnext<CR>")
Lmap("bH", "H- split with prev", "<Cmd>sbprev<CR>")
Lmap("bv", "V| split with next", "<Cmd>vert sbnext<CR>")
Lmap("bV", "V| split with prev", "<Cmd>vert sbprev<CR>")
Lmap("bs", "V| split with last", "<Cmd>vert sbuffer#<CR>")
Lmap("bS", "H- split with last", "<Cmd>sbuffer#<CR>")
-- Windows 
Lmap("ww", "Last accessed", "<C-W>p")
Lmap("wn", "New V|", "<Cmd>vnew<CR>")
Lmap("wN", "New H-", "<Cmd>new<CR>")
Lmap("wd", "Close", "<C-W>c")
Lmap("wD", "Close last accessd", "<C-W>p<C-W>c")
Lmap("wo", "Close others", "<C-W>o")
Lmap("wx", "Xchange with next", "<C-W>x")
Lmap("we", "Equal size", "<C-W>=")
Lmap("wW", "Max width", "<C-W>|")
Lmap("wH", "Max height", "<C-W>_")
Lmap("wr", "Rotate downwards", "<C-W>r")
Lmap("wR", "Rotate upwards", "<C-W>R")
Lmap("ws", "V| split", "<C-W>v")
Lmap("wS", "H- split", "<C-W>s")
Lmap("wj", "Move win down", "<C-W>J")
Lmap("wk", "Move win up", "<C-W>K")
Lmap("wh", "Move win left", "<C-W>H")
Lmap("wl", "Move win right", "<C-W>L")
Lmap("w<Down>", "Move win down", "<C-W>J")
Lmap("w<Up>", "Move win up", "<C-W>K")
Lmap("w<Left>", "Move win left", "<C-W>H")
Lmap("w<Right>","Move win right", "<C-W>L")
-- LSP
local lsp = vim.lsp.buf
local diag = vim.diagnostic
-- Normal
Lmap("o", "Diagnostics float", diag.open_float)
Lmap("lh", "Help", lsp.hover)
Lmap("ls", "Signature help", lsp.signature_help)
Lmap("ln", "Rename", lsp.rename)
Lmap("lv", "Highlight", lsp.document_highlight)
Lmap("lV", "Clear highlight", lsp.clear_references)
Lmap("ld", "Definition", lsp.definition)
Lmap("lD", "Declaration", lsp.declaration)
Lmap("lt", "Type definition", lsp.type_definition)
Lmap("la", "nx", "Code action", lsp.code_action)
Lmap("lf", "nx", "Format", W(lsp.format) { async = true })
Lmap("lt", "Type under cursor", function() vim.lsp.util.open_floating_preview(
{ vim.lsp.semantic_tokens.get_at_pos()[1].type },
nil, { border = vim.g.border_bleed })
end)
-- Control
Lmap("lcs", "Show", diag.show)
Lmap("lch", "Hide", diag.hide)
Lmap("lce", "Enable", diag.enable)
Lmap("lcd", "Disable", diag.disable)
-- List
Lmap("lld", "Diagnostics all Q", diag.setqflist)
Lmap("llD", "Diagnostics buf L", diag.setloclist)
Lmap("llr", "References", lsp.references)
Lmap("lli", "Incoming calls", lsp.incoming_calls)
Lmap("llo", "Outgoing calls", lsp.outgoing_calls)
Lmap("llm", "Implementations", lsp.implementation)
Lmap("lls", "Buffer symbols", lsp.document_symbol)
Lmap("llw", "Workspace symbols", lsp.workspace_symbol)
-- Workspace
Lmap("lwa", "Add folder", lsp.add_workspace_folder)
Lmap("lwr", "Remove folder", lsp.remove_workspace_folder)
Lmap("lwl", "List folders", function() vim.print(lsp.list_workspace_folders()) end)
-- Next/Prev
local cmd = W(vim.cmd)
local function try(func, fallback)
return function() return pcall(vim.cmd, func) or vim.cmd(fallback) end
end
MakePair("s", "misspelled word", cmd "norm!]s", cmd "norm![s")
MakePair("b", "buffer", cmd "bnext", cmd "bprev")
MakePair("w", "window", cmd "wincmd w", cmd "wincmd W")
MakePair("Q", "loclist", try("lnext", "lfirst"), try("lprev", "llast"))
MakePair("q", "quickfix", try("cnext", "cfirst"), try("cprev", "clast"))
MakePair("d", "diagnostic", diag.goto_next, diag.goto_prev)
local map = vim.keymap.set
-- ADDITIONAL
-- map("i", "<A-Right>", "O") -- for 2 keyboard layer
map("i", "<A-BS>", "<Del>")
map("n", "<C-i>", "<C-i>") -- jump list
map("", "<Esc>", "<Esc><Cmd>noh<CR>")
map("n", "))", ")", { desc = "Sentence forward" }) -- )* taken by treesitter
map("n", "((", "(", { desc = "Sentence backward" })
-- visual stuff
map("x", "<", "<gv")
map("x", ">", ">gv")
map("x", "<S-Down>", ":move '>+1<CR>gv=gv")
map("x", "<S-UP>", ":move '<-2<CR>gv=gv")
-- lock the cursor at the buffer center
map("n", "J", "mjJ`j")
map("n", "n", "nzvzz")
map("n", "N", "Nzvzz")
map("n", "*", "*zvzz")
map("n", "#", "#zvzz")
map("n", "g*", "g*zvzz")
map("n", "g#", "g#zvzz")
map("n", "<C-d>", "<C-d>zz")
map("n", "<C-u>", "<C-u>zz")
-- down/up on wrapped lines
map("i", "<Down>", "<Cmd>norm! gj<CR>")
map("i", "<Up>", "<Cmd>norm! gk<CR>")
map({ "n", "x" }, "<Down>", "j", { remap = true })
map({ "n", "x" }, "<Up>", "k", { remap = true })
map({ "n", "x" }, "j", [[v:count == 0 ? "gj" : "j"]], { expr = true })
map({ "n", "x" }, "k", [[v:count == 0 ? "gk" : "k"]], { expr = true })
-- LAYOUT
map("n", "<A-Down>", "<A-j>", { remap = true })
map("n", "<A-Up>", "<A-k>", { remap = true })
map("n", "<A-Left>", "<A-h>", { remap = true })
map("n", "<A-Right>", "<A-l>", { remap = true })
map("n", "<C-Down>", "<C-j>", { remap = true })
map("n", "<C-Up>", "<C-k>", { remap = true })
map("n", "<C-Left>", "<C-h>", { remap = true })
map("n", "<C-Right>", "<C-l>", { remap = true })
map("n", "<A-j>", "<C-W>j", { desc = "Lower window" })
map("n", "<A-k>", "<C-W>k", { desc = "Upper window" })
map("n", "<A-h>", "<C-W>h", { desc = "Left window" })
map("n", "<A-l>", "<C-W>l", { desc = "Right window" })
map("n", "<C-j>", "<Cmd>resize -2<CR>", { desc = "Decrease height" })
map("n", "<C-k>", "<Cmd>resize +2<CR>", { desc = "Increase height" })
map("n", "<C-h>", "<Cmd>vert resize -2<CR>", { desc = "Decrease width" })
map("n", "<C-l>", "<Cmd>vert resize +2<CR>", { desc = "Increase width" })

View File

@ -0,0 +1,76 @@
local o = vim.opt
vim.g.mapleader = " " -- must be before any plugins
vim.g.maplocalleader = " "
-- vim.g.editorconfig = true
-- behaviour
o.swapfile = false
o.undofile = true
o.undolevels = 10000
o.updatetime = 500 -- save swap, trigger CursorHold
o.timeout = false -- hit <ESC> manually instead
o.timeoutlen = 600 -- ms to wait for a mapping sequence
o.splitbelow = true
o.splitright = true
o.ignorecase = true
o.smartcase = true -- don't ignore case for CAPITALS
o.hlsearch = true -- default
o.incsearch = true -- default
o.confirm = true -- :q when there are changes
o.shortmess = "atTIcCF" -- oO?
o.wildmode = "longest:full,full" -- cmd completion
o.completeopt = "menu,menuone,longest" -- omnifunc completion
o.mouse = "a"
o.spell = false
o.spelllang = "en_us,uk"
o.spelloptions = "camel"
o.fileencodings = "utf-8,cp1251,cp866"
--o.clipboard = "unnamed"plus?
o.iskeyword:append "-" -- is part of the word
o.formatoptions:append "n" -- indents for numbered lists
-- movement
o.scrolloff = 7 -- vertical
o.sidescrolloff = 10
o.autoindent = true -- default
o.smartindent = true
o.expandtab = true -- spaces > tabs
o.tabstop = 8 -- to see the Tabs, see also `listchars`
o.softtabstop = 4
o.shiftwidth = 4 -- >> and <<
o.virtualedit = "block" -- move cursor anywhere in visual block mode
-- look
o.cmdheight = 1 -- 0 is experimental
o.rulerformat = ""
o.pumheight = 10 -- lines in cmp menu
o.pumblend = 10 -- cmp menu transparency
o.showmode = true -- in cmdline
o.wrap = false
o.linebreak = true -- when `wrap`, break lines at `breakat`
o.showbreak = "🞄" -- 🞄➣◜◞◟◝╴└╰... at the beginning of wrapped lines
o.breakindent = true -- for wrapped blocks to have indent
o.title = true -- better window title
o.list = true -- show trailing invisible chars
o.listchars = "tab:󰌒 ,trail:·,nbsp:%,leadmultispace: ▏" -- ▎▍
o.colorcolumn = "80,100"
o.cursorline = true
o.laststatus = 0 -- 3 for statusline only on last win; 0 to hide
o.conceallevel = 3 -- hide markup
o.number = true
o.numberwidth = 1 -- minimal possible width
o.rnu = true
o.signcolumn = "number"
o.termguicolors = true -- RGB True color
o.fillchars = {
fold = " ",
foldopen = "",
foldclose = "",
foldsep = " ",
diff = "",
eob = " ",
lastline = ""
}
-- CUSTOM
vim.g.border = "single" -- :h nvim_open_win
vim.g.border_bleed = { "🭽", "", "🭾", "", "🭿", "", "🭼", "" } -- full-bleed

View File

@ -0,0 +1,40 @@
---Handle require calls
---@param module_name string
---@param success_callback fun(module: table): any | any
---@param error_callback? fun(error: string): any | any
function Protected_require(module_name, success_callback, error_callback)
local status, module = pcall(require, module_name)
if status then
if type(success_callback) == "function" then
return success_callback(module)
end
return success_callback
end
if type(error_callback) == "function" then
return error_callback(module)
end
return error_callback
end
---vim.keymap.set but one-time-use
---@param mode string | table
---@param lhs string
---@param rhs fun(any) | string
---@param opts? table
function Oneshot_keymap(mode, lhs, rhs, opts)
local buffer = opts and opts.buffer and { buffer = opts.buffer }
local function trigger_oneshot()
vim.keymap.set(mode, lhs, rhs, opts)
local keys = vim.api.nvim_replace_termcodes(lhs, true, false, true)
vim.api.nvim_feedkeys(keys, "m", false)
vim.schedule_wrap(vim.keymap.del)(mode, lhs, buffer) -- run a bit later
end
vim.keymap.set(mode, lhs, trigger_oneshot, buffer)
end

View File

@ -0,0 +1,18 @@
return {
"hrsh7th/nvim-cmp",
event = "InsertEnter", -- , "CmdlineEnter"
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
{
"L3MON4D3/LuaSnip", -- jsregexp is optional
dependencies = "rafamadriz/friendly-snippets",
config = function()
require("luasnip.loaders.from_vscode").lazy_load()
end
},
"saadparwaiz1/cmp_luasnip", -- TODO
},
config = function() require "configs.cmp" end
}

View File

@ -0,0 +1,23 @@
local function config(test, opts)
opts.transparent = true
require("tokyonight").setup(opts)
vim.cmd.colorscheme "tokyonight"
end
return {
"navarasu/onedark.nvim",
{
"scottmckendry/cyberdream.nvim",
-- lazy = false,
-- priority = 1000,
config = config,
},
{
"folke/tokyonight.nvim",
lazy = false, -- for priority to work
priority = 1000, -- load before all other start plugins
config = config,
opts = { style = "moon" },
}
}

View File

@ -0,0 +1,10 @@
return {
"numToStr/Comment.nvim",
keys = {
{ "gc", mode = { "n", "x" } },
{ "gb", mode = { "n", "x" } },
{ "gp", "yy<Plug>(comment_toggle_linewise_current)p" },
{ "gp", "ygv<Plug>(comment_toggle_blockwise_visual)'>o<CR>p==", mode = "x" },
},
opts = {}
}

View File

@ -0,0 +1,5 @@
return {
"lewis6991/gitsigns.nvim",
event = "User VeryLazyFile",
config = function() require "configs.gitsigns" end
}

View File

@ -0,0 +1,31 @@
return {
"ThePrimeagen/harpoon", branch = "harpoon2",
dependencies = "nvim-lua/plenary.nvim",
keys = {
{ "<Leader>a", desc = "Append harpoon" },
{ "<Leader>A", desc = "Prepend harpoon" },
{ "<Leader>m", desc = "Harpoon menu" },
{ "<Leader>M", desc = "Harpoon clear" },
"<C-n>", "<C-p>", "]m", "[m",
"ñ", "é", "í", "ó", -- AltGr Colemak layer
},
config = function()
local harpoon = require "harpoon"
harpoon:setup()
Lmap("a", function() harpoon:list():append() end)
Lmap("A", function() harpoon:list():prepend() end)
Lmap("m", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end)
Lmap("M", function() harpoon:list():clear() end)
MakePair("m", "harpoon", function() harpoon:list():next() end, function() harpoon:list():prev() end)
local map = vim.keymap.set
map("n", "<C-p>", function() harpoon:list():prev() end)
map("n", "<C-n>", function() harpoon:list():next() end)
-- TODO ._.
map("n", "ñ", function() harpoon:list():select(1) end)
map("n", "é", function() harpoon:list():select(2) end)
map("n", "í", function() harpoon:list():select(3) end)
map("n", "ó", function() harpoon:list():select(4) end)
end
}

View File

@ -0,0 +1,22 @@
return {} -- can't really make this to work normally
-- 'Wansmer/langmapper.nvim',
-- lazy = false,
-- priority = 1,
-- opts = {},
-- init = function()
-- local ua = [['йцукенгшщзхїґфівапролджєячсмитьбю.]]
-- local UA = [[ʼЙЦУКЕНГШЩЗХЇҐФІВАПРОЛДЖЄЯЧСМИТЬБЮ,]]
-- local en = [[`qwfpgjluy;[]\arstdhneio'zxcvbkm,./]]
-- local EN = [[~QWFPGJLUY:{}|ARSTDHNEIO"ZXCVBKM<>?]]
--
-- local function escape(str)
-- local escape_chars = [[;,."|\]]
-- return vim.fn.escape(str, escape_chars)
-- end
--
-- vim.opt.langmap = vim.fn.join({
-- escape(UA) .. ';' .. escape(EN),
-- escape(ua) .. ';' .. escape(en),
-- }, ',')
-- end
-- }

View File

@ -0,0 +1,144 @@
local M = {
"williamboman/mason-lspconfig.nvim",
event = "BufReadPre",
dependencies = { -- load those first
"mason.nvim",
{
"neovim/nvim-lspconfig",
config = function() require "configs.lspconfig" end
}
}
}
M.opts = {
ensure_installed = {
"lua_ls",
"bashls",
"tinymist",
"rust_analyzer",
"yamlls",
"clangd",
"jdtls",
"hyprls",
-- "sqls",
-- "arduino_language_server",
-- "cmake",
--"csharp_ls", -- piece of 󰱵
-- "hls", -- Haskell
-- "taplo", -- toml
-- "jsonls",
-- "ruff_lsp", -- Python
},
handlers = { -- automatic server setup
function(server_name) -- default handler
package.loaded.lspconfig[server_name].setup {}
end
}
}
M.opts.handlers.lua_ls = function()
package.loaded.lspconfig.lua_ls.setup {
settings = {
Lua = {
diagnostics = { globals = { "vim" } }
}
}
}
end
M.opts.handlers.harper_ls = function()
package.loaded.lspconfig.harper_ls.setup {
settings = { -- https://writewithharper.com/docs/integrations/neovim
["harper-ls"] = {
isolateEnglish = true, -- highly experimental
fileDictPath = vim.fn.stdpath("config") .. "/spell/spell/",
userDictPath = vim.fn.stdpath("config") .. "/spell/en.utf-8.add",
codeActions = {
forceStable = true -- preserve the order of actions
},
diagnosticSeverity = "information" -- "hint", "information", "warning", "error"
-- markdown = { ignore_link_title = true }
-- linters = { -- turned off by default
-- spelled_numbers = false, wrong_quotes = false, linking_verbs = false,
-- boring_words = false, use_genitive = false, plural_conjugate = false,
-- no_oxford_comma = false,
-- }
}
},
}
end
-- https://myriad-dreamin.github.io/tinymist//frontend/neovim.html
M.opts.handlers.tinymist = function()
package.loaded.lspconfig.tinymist.setup {
settings = {
formatterPrintWidth = 100, -- can't stand 120
formatterMode = "typstyle", -- or typstfmt
-- exportPdf = "onDocumentHasTitle", -- default: never
semanticTokens = "enable"
},
single_file_support = true,
root_dir = function(_, bufnr)
return vim.fs.root(bufnr, { ".git" }) or vim.fn.expand "%:p:h"
end,
}
end
M.opts.handlers.yamlls = function()
package.loaded.lspconfig.yamlls.setup {
settings = {
yaml = {
format = { enable = true },
schemaStore = { enable = true },
}
}
}
end
M.opts.handlers.rust_analyzer = function() -- TODO
package.loaded.lspconfig.rust_analyzer.setup {
settings = {
["rust-analyzer"] = {
cargo = {
allFeatures = true,
loadOutDirsFromCheck = true,
runBuildScripts = true,
},
-- Add clippy lints for Rust.
checkOnSave = true,
check = {
-- allFeatures = true,
command = "clippy",
extraArgs = {
"--",
"--no-deps", -- run Clippy only on the given crate
-- Deny, Warn, Allow, Forbid
"-Wclippy::correctness", -- code that is outright wrong or useless
"-Wclippy::complexity", -- code that does something simple but in a complex way
"-Wclippy::suspicious", -- code that is most likely wrong or useless
"-Wclippy::style", -- code that should be written in a more idiomatic way
"-Wclippy::perf", -- code that can be written to run faster
"-Wclippy::pedantic", -- lints which are rather strict or have occasional false positives
"-Wclippy::nursery", -- new lints that are still under development
"-Wclippy::cargo", -- lints for the cargo manifest
-- Use in production
"-Aclippy::restriction", -- lints which prevent the use of language and library features
-- Other
"-Aclippy::must_use_candidate", -- must_use is rather annoing
},
},
procMacro = {
enable = true,
-- ignored = {
-- ["async-trait"] = { "async_trait" },
-- ["napi-derive"] = { "napi" },
-- ["async-recursion"] = { "async_recursion" },
-- },
},
},
}
}
end
return M

View File

@ -0,0 +1,14 @@
return {
"williamboman/mason.nvim",
opts = {
ui = {
height = 0.8,
border = vim.g.border,
icons = {
package_pending = "󱦳",
package_installed = "",
package_uninstalled = ""
}
}
}
}

View File

@ -0,0 +1,16 @@
return {
"nvim-telescope/telescope.nvim", branch = "0.1.x",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
{ "nvim-telescope/telescope-fzf-native.nvim", build = "make" }
},
keys = { -- so lazy 🥱
{ "<Leader>s", desc = "Load Telescope", mode = { "n", "x" } },
-- { "<Leader>o", desc = "Find old files" },
{ "<Leader>.", desc = "Find files in ." },
{ "<Leader>/", desc = "Telescope /" },
{ "<Leader>f", desc = "Find files" },
},
config = function() require "configs.telescope" end
}

View File

@ -0,0 +1,14 @@
return {
"nvim-treesitter/nvim-treesitter",
event = "User LazyFile",
-- lazy = false, --TODO
build = ":TSUpdate",
dependencies = "nvim-treesitter/nvim-treesitter-textobjects",
init = function()
vim.o.foldenable = true
vim.o.foldlevel = 99
vim.o.foldmethod = "expr"
vim.o.foldexpr = "nvim_treesitter#foldexpr()"
end,
config = function() require "configs.treesitter" end
}

View File

@ -0,0 +1,6 @@
return {
"dstein64/vim-startuptime",
cmd = "StartupTime", -- lazy-load on a command
keys = { { "<Leader>us", "<Cmd>StartupTime<CR>", desc = "StartupTime" } },
init = function() vim.g.startuptime_tries = 25 end
}

View File

@ -0,0 +1,64 @@
return {
"folke/which-key.nvim",
event = "VeryLazy",
opts = {
win = {
border = vim.g.border,
padding = { 0, 1, 0, 1 } -- ^, <, _, >
},
layout = {
spacing = 4,
align = "center",
width = { min = 1 },
height = { min = 1, max = 15 }
},
replace = { ["<leader>"] = "L" },
plugins = { spelling = { suggestions = 40 } },
},
init = function()
vim.o.timeout = true
vim.o.timeoutlen = 400 -- before opening WhichKey
end,
config = function(_, opts)
require("which-key").setup(opts)
require("which-key").add({ -- Naming groups here
{ "<Leader>C", group = "Loclist" },
{ "<Leader>b", group = "Buffer" },
{ "<Leader>c", group = "Quickfix" },
{ "<Leader>h", group = "Gitsigns" },
{ "<Leader>hc", group = "Control" },
{ "<Leader>ht", group = "Toggle" },
{ "<Leader>hv", group = "View" },
{ "<Leader>l", group = "LSP" },
{ "<Leader>lc", group = "Control" },
{ "<Leader>ll", group = "List" },
{ "<Leader>lp", group = "Peek definiton" },
{ "<Leader>lw", group = "Workspace" },
{ "<Leader>t", group = "Toggle" },
{ "<Leader>u", group = "Utils" },
{ "<Leader>w", group = "Window" },
-- c = { name = "Quickfix" },
-- C = { name = "Loclist" },
-- u = { name = "Utils" },
-- t = { name = "Toggle" },
-- b = { name = "Buffer" },
-- w = { name = "Window" },
-- h = { name = "Gitsigns",
-- v = { name = "View" },
-- t = { name = "Toggle" },
-- c = { name = "Control" },
-- },
-- l = {
-- name = "LSP",
-- l = { name = "List" },
-- c = { name = "Control" },
-- w = { name = "Workspace" },
-- p = { name = "Peek definiton" },
-- },
-- }, { prefix = "<Leader>" })
})
end
}

View File

@ -0,0 +1,65 @@
local map = vim.keymap.set
---function() y("1") end = W(y) "1"
---function() y(1,2) end = W(y,1,2)
---@param func function
function W(func, ...)
if ... then
local args = {...}
return function() func(unpack(args)) end
end
return function(arg)
return function() func(arg) end
end
end
---vim.keymap.set("n","<Leader>t",":Lazy<CR>",{desc="D"}) = Lmap("t", "D", ":Lazy<CR>")
---vim.keymap.set({"n","v"},"<Leader>D",":Lazy<CR>",{desc="D"}) = Lmap("t", "nv", "D", ":Lazy<CR>")
function Lmap(...)
local args = {...}
local len = select("#", ...)
if len == 3 then -- most used
map("n", "<Leader>"..args[1], args[3], { desc = args[2] })
elseif len == 2 then
map("n", "<Leader>"..args[1], args[2])
else -- 4
local modes = {}
args[2]:gsub(".", function(c) table.insert(modes, c) end)
map(modes, "<Leader>"..args[1], args[4], { desc = args[3] })
end
end
-- if try() succeeds then else_() else except(), always finally()
function Try(try, except, else_, finally)
return function()
if pcall(try) then
if else_ then else_() end
else
if except then except() end
end
if finally then finally() end
end
end
---Switch move pair to tresitter.textobjects.repeatable_move when it becomes available
---@param char string
---@param desc string
---@param next_func function
---@param prev_func function
function MakePair(char, desc, next_func, prev_func)
local function check_treesitter(func)
local ts_repeat = package.loaded["nvim-treesitter.textobjects.repeatable_move"]
if not ts_repeat then return func() end
local next, prev = ts_repeat.make_repeatable_move_pair(next_func, prev_func)
map("n", "]"..char, next, { desc = "Next "..desc.." (repeatable)" })
map("n", "["..char, prev, { desc = "Prev "..desc.." (repeatable)" })
if func == next_func then next() else prev() end
end
map("n", "]"..char, function() check_treesitter(next_func) end, { desc = "Next "..desc })
map("n", "["..char, function() check_treesitter(prev_func) end, { desc = "Prev "..desc })
end