Compare commits

...

7 commits

Author SHA1 Message Date
4bc0ef9ed7
nvim: Enable automatic installation of DAPs with mason 2025-06-21 16:44:41 +02:00
51595b8b81
nvim: Extract debug plugins into debug module 2025-06-21 16:44:40 +02:00
020ec86481
nvim: Split up mini plugins for lazier loading
Split off base16 (instant load for themes) and starter (only load on
empty start) from rest.
2025-06-21 16:44:40 +02:00
091274fd82
nvim: Add custom lazy loading events
Using lazy-events.nvim we can create custom events (such as the LazyVim
equivalent LazyFile event) based on other events (i.e. a grouping), on
globbing files in the current dir, or on arbitrary custom logic.

For now, any plugins which require files to be present to work are
loaded with the 'LazyFile' event.

Any plugins which need to be loaded when opening a directory with vim
are loaded with the 'StartWithDir' event (essentially only neo-tree for
now). Similarly mini.starter is loaded on the `StartScreen` event.

Any plugin which only makes sense to run in a `.git` dir (gitsigns etc)
will only run on the `LazyProject:git` event.
2025-06-21 16:44:39 +02:00
71ddce4119
nvim: Fix nvim-dap lazy loading
Switch its key maps to anonymous functions to not instantly run
'require' when creating the plugin load spec.
2025-06-21 16:44:39 +02:00
0d8208d722
nvim: Add highlights to nvim-dap repl 2025-06-21 16:44:38 +02:00
3454c60c44
nvim: Add nvim-dap configuration
Automatically opens dap-view when in debugging session (and closes when
done), sets some breakpoint jump logic and makes the gutter symbols
nicer.

Adds keybinds for most of the dap operations with
`<localleader>d<something>` where something is the operation (i.e. `c`
for continue, `b` for breakpoint and so on).
2025-06-21 16:44:38 +02:00
14 changed files with 404 additions and 155 deletions

View file

@ -30,6 +30,7 @@
"image.nvim": { "branch": "master", "commit": "a4638ec549c6aa56264cb0371255192ff37a8a90" },
"img-clip.nvim": { "branch": "main", "commit": "0bb8b5ced45c2672c70184c87d014194b0705815" },
"jupytext.nvim": { "branch": "main", "commit": "c8baf3ad344c59b3abd461ecc17fc16ec44d0f7b" },
"lazy-events.nvim": { "branch": "main", "commit": "63802b7ddc852bdfa29e33b158d52429276fa742" },
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
"lazydev.nvim": { "branch": "main", "commit": "f59bd14a852ca43db38e3662395354cb2a9b13e0" },
"ltex_extra.nvim": { "branch": "dev", "commit": "5b37806dfbadeb8d6c0f1ee03140a60ffa40852c" },
@ -40,11 +41,15 @@
"markmap.nvim": { "branch": "main", "commit": "5fb6755cf5434511cc23a4936c9eb76b9142fba5" },
"mason-conform.nvim": { "branch": "main", "commit": "f3b96fa2217fcb1513301eefbe10ea0e765e33eb" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "5477d67a5ca12b704f2a8a55a057fc79750f3dbb" },
"mason-nvim-dap.nvim": { "branch": "main", "commit": "4c2cdc69d69fe00c15ae8648f7e954d99e5de3ea" },
"mason-nvim-lint": { "branch": "main", "commit": "b579a00ee39dcd590b1023028dc8fb3d203a67b0" },
"mason.nvim": { "branch": "main", "commit": "7f265cd6ae56cecdd0aa50c8c73fc593b0604801" },
"mcphub.nvim": { "branch": "main", "commit": "85a7a659fc82da1429a2241ab61e9ce07b3db374" },
"mdeval.nvim": { "branch": "master", "commit": "0e1b248db174a9659a9ab16eb8c90ff3aec55264" },
"mini.base16": { "branch": "main", "commit": "2eb2d2b889a8c861d1a66ec651bd0edb417d5c7f" },
"mini.files": { "branch": "main", "commit": "49c855977e9f4821d1ed8179ed44fe098b93ea2a" },
"mini.nvim": { "branch": "main", "commit": "94cae4660a8b2d95dbbd56e1fbc6fcfa2716d152" },
"mini.starter": { "branch": "main", "commit": "d8038690eadf203a40863c3a9423df880a901d39" },
"molten-nvim": { "branch": "main", "commit": "a286aa914d9a154bc359131aab788b5a077a5a99" },
"neo-tree-jj.nvim": { "branch": "main", "commit": "c6534930c6f79893e12eafbb722ee23e6a83e80e" },
"neo-tree.nvim": { "branch": "main", "commit": "f481de16a0eb59c985abac8985e3f2e2f75b4875" },
@ -56,6 +61,11 @@
"nvim-FeMaco.lua": { "branch": "main", "commit": "96bbf843595dbe865838b3f2484b73557f34700c" },
"nvim-colorizer.lua": { "branch": "master", "commit": "517df88cf2afb36652830df2c655df2da416a0ae" },
"nvim-coverage": { "branch": "main", "commit": "a939e425e363319d952a6c35fb3f38b34041ded2" },
"nvim-dap": { "branch": "master", "commit": "6a5bba0ddea5d419a783e170c20988046376090d" },
"nvim-dap-go": { "branch": "main", "commit": "8763ced35b19c8dc526e04a70ab07c34e11ad064" },
"nvim-dap-python": { "branch": "master", "commit": "261ce649d05bc455a29f9636dc03f8cdaa7e0e2c" },
"nvim-dap-repl-highlights": { "branch": "master", "commit": "307cff2c364d3bf02501d59c405a817967fcd5fb" },
"nvim-dap-view": { "branch": "main", "commit": "fc0315087a871f9e74ef88559760b81dae81bc6d" },
"nvim-lint": { "branch": "master", "commit": "9dfb77ef6c5092a19502883c02dc5a02ec648729" },
"nvim-lspconfig": { "branch": "master", "commit": "77d3fdfb3554632c7a3b101ded643d422de7626f" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },

View file

@ -41,6 +41,7 @@ local languages = {
ts = { "bash" },
lint = { bash = { "shellcheck" } },
format = { bash = { "shellharden", "shfmt" } },
dap = { "bash" },
},
beancount = { lsp = { beancount = {} }, ts = { "beancount" }, format = { beancount = { "bean-format" } } },
bibtex = { ts = { "bibtex" }, format = { bib = { "bibtex-tidy" } } },
@ -63,7 +64,13 @@ local languages = {
format = { javascript = { "prettier" }, javascriptreact = { "prettier" } },
},
git = { ts = { "git_config", "git_rebase", "gitattributes", "gitcommit", "gitignore" } },
go = { lsp = { gopls = {} }, ts = { "go" }, lint = { go = { "revive" } }, format = { go = { "gofumpt" } } },
go = {
lsp = { gopls = {} },
ts = { "go" },
lint = { go = { "revive" } },
format = { go = { "gofumpt" } },
dap = { "delve" },
},
graphql = { format = { graphql = { "prettier" } } },
html = { format = { html = { "prettier", "rustywind" } } },
julia = { lsp = { julials = {} }, ts = { "julia" } },
@ -104,6 +111,7 @@ local languages = {
lsp = { basedpyright = {}, ruff = {} },
ts = { "python" },
format = { python = { "ruff_format", "ruff_organize_imports" } },
dap = { "python" },
},
quarto = { lint = { quarto = { "markdownlint" } }, format = { quarto = { "prettier", "injected" } } },
sh = { lint = { sh = { "shellcheck" } }, format = { sh = { "shellharden", "shfmt" } } },

View file

@ -36,8 +36,63 @@ local spec_dir = vim.fn.stdpath("config") .. "/lua/plugins"
local spec_exist = (vim.fn.isdirectory(spec_dir) ~= 0) and (#vim.fn.glob(spec_dir .. "/*.lua", nil, true) ~= 0)
local spec = spec_exist and { import = "plugins" } or {}
vim.g.lazy_events_config = {
simple = {
LazyFile = { "BufReadPost", "BufNewFile", "BufWritePre" },
},
projects = {
git = { ".git" },
},
custom = {
-- We are opening a directory with vim
StartWithDir = {
event = "BufEnter",
once = true,
cond = function()
local arg = vim.fn.argv(0)
if arg == "" then
return false
end
local stats = vim.uv.fs_stat(arg)
return (stats and stats.type == "directory") or false
end,
},
-- Nothing but the 'start screen' is shown (no file etc)
StartScreen = {
event = "BufEnter",
once = true,
cond = function()
-- Taken from mini.starter something_is_shown() func!
-- - There are files in arguments (like `nvim foo.txt` with new file).
if vim.fn.argc() > 0 then
return false
end
local listed_buffers = vim.tbl_filter(function(buf_id)
return vim.fn.buflisted(buf_id) == 1
end, vim.api.nvim_list_bufs())
if #listed_buffers > 1 or vim.bo.filetype ~= "" then
return false
end
local n_lines = vim.api.nvim_buf_line_count(0)
if n_lines > 1 then
return false
end
local first_line = vim.api.nvim_buf_get_lines(0, 0, 1, true)[1]
if string.len(first_line) > 0 then
return false
end
return true
end,
},
},
}
require("lazy").setup({
spec = { spec },
spec = {
{ "bwpge/lazy-events.nvim", import = "lazy-events.import" },
spec,
},
defaults = { lazy = true, version = "*" },
performance = {
rtp = {

View file

@ -109,9 +109,9 @@ return {
},
-- collection of plugins
{
"echasnovski/mini.nvim",
"echasnovski/mini.base16",
dependencies = { "rktjmp/fwatch.nvim" }, -- for colorscheme updating
event = "VimEnter", -- need to load pretty soon for Starter screen
event = "VimEnter",
config = function()
-- automatic callback to invoke 'mini.base16' when colorscheme file is changed
local colorsfile = vim.fn.stdpath("state") .. "/colorscheme.lua"
@ -129,8 +129,12 @@ return {
source_colors()
end),
})
-- this should be loaded as soon as the plugin is loaded
end,
},
{
"echasnovski/mini.starter",
event = "StartScreen",
config = function()
local starter = require("mini.starter")
starter.setup({
evaluate_single = true,
@ -153,6 +157,22 @@ return {
starter.gen_hook.aligning("center", "center"),
},
})
end,
keys = {
{
"<leader>ss",
function()
require("mini.starter").open()
end,
silent = true,
desc = "startpage",
},
},
},
{
"echasnovski/mini.files",
event = { "VeryLazy" },
config = function()
require("mini.files").setup({
mappings = {
synchronize = "S",
@ -169,115 +189,126 @@ return {
pattern = "MiniFilesWindowUpdate",
callback = function(args)
local win_id = args.data.win_id
vim.wo[win_id].number = true
end,
})
end,
keys = {
{
"<leader>e",
function()
local mf = require("mini.files")
if not mf.close() then
mf.open()
end
end,
desc = "floating file browser",
},
},
},
{
"echasnovski/mini.nvim",
event = { "InsertEnter", "VeryLazy" },
config = function()
-- manually create lazy loading scenarios
vim.api.nvim_create_autocmd({ "InsertEnter", "CursorHold" }, {
once = true,
require("mini.ai").setup()
-- Align tables and other alignable things
require("mini.align").setup({})
require("mini.bracketed").setup({
buffer = { suffix = "b", options = {} },
comment = { suffix = "k", options = {} },
conflict = { suffix = "" }, -- disable to use git-conflict instead
diagnostic = { suffix = "e", options = {} },
file = { suffix = "f", options = {} },
indent = { suffix = "" }, -- disable since we use indentscope
jump = { suffix = "j", options = {} },
location = { suffix = "l", options = {} },
oldfile = { suffix = "o", options = {} },
quickfix = { suffix = "q", options = {} },
treesitter = { suffix = "t", options = {} },
undo = { suffix = "" }, -- disable since I don't need it
window = { suffix = "w", options = {} },
yank = { suffix = "y", options = {} },
})
require("mini.comment").setup({
hooks = {
pre = function()
-- use treesitter commentstring functionality if it's installed
if require("core.util").is_available("ts_context_commentstring") then
require("ts_context_commentstring.internal").update_commentstring()
end
end,
},
})
require("mini.cursorword").setup({ delay = 500 })
vim.api.nvim_set_hl(0, "MiniCursorword", { bold = true, underline = false })
vim.api.nvim_set_hl(0, "MiniCursorwordCurrent", { bold = true, underline = false })
require("mini.fuzzy").setup()
require("mini.indentscope").setup({
symbol = "",
draw = { animation = require("mini.indentscope").gen_animation.none() },
options = { indent_at_cursor = false, n_lines = 2000 },
})
-- disable indentlines for terminals
vim.api.nvim_create_autocmd("TermOpen", {
pattern = "*",
callback = function()
require("mini.ai").setup()
-- Align tables and other alignable things
require("mini.align").setup({})
require("mini.bracketed").setup({
buffer = { suffix = "b", options = {} },
comment = { suffix = "k", options = {} },
conflict = { suffix = "" }, -- disable to use git-conflict instead
diagnostic = { suffix = "e", options = {} },
file = { suffix = "f", options = {} },
indent = { suffix = "" }, -- disable since we use indentscope
jump = { suffix = "j", options = {} },
location = { suffix = "l", options = {} },
oldfile = { suffix = "o", options = {} }, -- FIXME: overwritten by wrapping defaults currently
quickfix = { suffix = "q", options = {} },
treesitter = { suffix = "t", options = {} },
undo = { suffix = "" }, -- disable since I don't need it
window = { suffix = "w", options = {} },
yank = { suffix = "y", options = {} },
})
require("mini.comment").setup({
hooks = {
pre = function()
-- use treesitter commentstring functionality if it's installed
if require("core.util").is_available("ts_context_commentstring") then
require("ts_context_commentstring.internal").update_commentstring()
end
end,
},
})
require("mini.cursorword").setup({ delay = 500 })
vim.api.nvim_set_hl(0, "MiniCursorword", { bold = true, underline = false })
vim.api.nvim_set_hl(0, "MiniCursorwordCurrent", { bold = true, underline = false })
require("mini.fuzzy").setup()
require("mini.indentscope").setup({
symbol = "",
draw = { animation = require("mini.indentscope").gen_animation.none() },
options = { indent_at_cursor = false, n_lines = 2000 },
})
-- disable indentlines for terminals
vim.api.nvim_create_autocmd("TermOpen", {
pattern = "*",
callback = function()
vim.b.miniindentscope_disable = true
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = {
"lazy",
"mason",
"help",
"lspinfo",
"packer",
"checkhealth",
"man",
"gitcommit",
"TelescopePrompt",
"TelescopeResults",
"trouble",
},
callback = function()
vim.b.miniindentscope_disable = true
end,
})
require("mini.map").setup()
require("mini.move").setup()
require("mini.operators").setup()
require("mini.pairs").setup({
mappings = {
-- these mappings ensure that when trying to _close_ any of the pairs
-- it will not double insert:
-- " <- you are here. Normal pairs will do """. This config will do "".
['"'] = {
action = "closeopen",
pair = '""',
neigh_pattern = '[^\\"].',
register = { cr = false },
},
["'"] = {
action = "closeopen",
pair = "''",
neigh_pattern = "[^%a\\'].",
register = { cr = false },
},
["`"] = {
action = "closeopen",
pair = "``",
neigh_pattern = "[^\\`].",
register = { cr = false },
},
["<"] = { action = "open", pair = "<>", neigh_pattern = "\r." },
[">"] = { action = "close", pair = "<>" },
},
})
require("mini.trailspace").setup()
vim.b.miniindentscope_disable = true
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = {
"lazy",
"mason",
"help",
"lspinfo",
"packer",
"checkhealth",
"man",
"gitcommit",
"TelescopePrompt",
"TelescopeResults",
"trouble",
},
callback = function()
vim.b.miniindentscope_disable = true
end,
})
require("mini.map").setup()
require("mini.move").setup()
require("mini.operators").setup()
require("mini.pairs").setup({
mappings = {
-- these mappings ensure that when trying to _close_ any of the pairs
-- it will not double insert:
-- " <- you are here. Normal pairs will do """. This config will do "".
['"'] = {
action = "closeopen",
pair = '""',
neigh_pattern = '[^\\"].',
register = { cr = false },
},
["'"] = {
action = "closeopen",
pair = "''",
neigh_pattern = "[^%a\\'].",
register = { cr = false },
},
["`"] = {
action = "closeopen",
pair = "``",
neigh_pattern = "[^\\`].",
register = { cr = false },
},
["<"] = { action = "open", pair = "<>", neigh_pattern = "\r." },
[">"] = { action = "close", pair = "<>" },
},
})
require("mini.trailspace").setup()
end,
keys = {
{
@ -288,14 +319,6 @@ return {
silent = true,
desc = "minimap",
},
{
"<leader>ss",
function()
require("mini.starter").open()
end,
silent = true,
desc = "startpage",
},
{
"<localleader>w",
function()
@ -303,16 +326,6 @@ return {
end,
desc = "Trim trailing whitespace",
},
{
"<leader>e",
function()
local mf = require("mini.files")
if not mf.close() then
mf.open()
end
end,
desc = "floating file browser",
},
{
"[si",
function()

View file

@ -0,0 +1,183 @@
local function get_all_daps()
local enabled_daps = {}
for _, lang in pairs(Languages) do
if not lang.dap then
goto continue
end
for _, name in pairs(lang.dap) do
table.insert(enabled_daps, name)
end
::continue::
end
return enabled_daps
end
return {
{
"mfussenegger/nvim-dap",
init = function()
if require("core.util").is_available("which-key") then
require("which-key").add({ "<localleader>d", group = "debug" })
end
end,
dependencies = {
{
"LiadOz/nvim-dap-repl-highlights",
opts = {},
build = ":TSInstall dap_repl",
dependencies = { "nvim-treesitter/nvim-treesitter" },
},
{
"igorlfs/nvim-dap-view",
opts = { winbar = { controls = { enabled = true } } },
keys = {
{
"<leader>sb",
function()
require("dap-view").toggle()
end,
desc = "Dap UI",
},
},
},
{ "jay-babu/mason-nvim-dap.nvim", opts = { ensure_installed = get_all_daps() } },
},
config = function()
local dap, dv = require("dap"), require("dap-view")
dap.listeners.before.attach["dap-view-config"] = function()
dv.open()
end
dap.listeners.before.launch["dap-view-config"] = function()
dv.open()
end
dap.listeners.before.event_terminated["dap-view-config"] = function()
dv.close()
end
dap.listeners.before.event_exited["dap-view-config"] = function()
dv.close()
end
-- Signs
for _, group in pairs({
"DapBreakpoint",
"DapBreakpointCondition",
"DapBreakpointRejected",
"DapLogPoint",
}) do
vim.fn.sign_define(group, { text = "", texthl = group })
end
vim.fn.sign_define("DapStopped", { text = "", texthl = "DapStopped", numhl = "debugPC" })
-- jump to stopped-at breakpoint if it is visible in a tab or open a new tab
require("dap").defaults.fallback.switchbuf = "usevisible,usetab,newtab"
end,
keys = {
{
"<localleader>dc",
function()
require("dap").continue()
end,
desc = "continue",
},
{
"<localleader>dt",
function()
require("dap").terminate()
end,
desc = "terminate",
},
{
"<localleader>dr",
function()
require("dap").run_to_cursor()
end,
desc = "run to cursor",
},
{
"<localleader>dj",
function()
require("dap").step_over()
end,
desc = "step over",
},
{
"<localleader>dl",
function()
require("dap").step_into()
end,
desc = "step into",
},
{
"<localleader>dh",
function()
require("dap").step_out()
end,
desc = "step out",
},
{
"<localleader>[d",
function()
require("dap").up()
end,
desc = "DAP up",
},
{
"<localleader>]d",
function()
require("dap").down()
end,
desc = "DAP down",
},
{
"<localleader>db",
function()
require("dap").toggle_breakpoint()
end,
desc = "toggle breakpoint",
},
{
"<localleader>dB",
function()
vim.ui.input({ prompt = "Breakpoint condition: " }, function(input)
require("dap").set_breakpoint(input)
end)
end,
desc = "set logpoint",
},
{
"<localleader>dL",
function()
vim.ui.input({ prompt = "Log point message: " }, function(input)
require("dap").set_breakpoint(nil, nil, input)
end)
end,
desc = "set logpoint",
},
{
"<localleader>dk",
function()
require("dap.ui.widgets").hover()
end,
desc = "hover",
},
},
},
{
"mfussenegger/nvim-dap-python",
dependencies = { { "mfussenegger/nvim-dap", optional = true } },
ft = { "python" },
config = function()
require("dap-python").setup("debugpy-adapter")
end,
},
{
"leoluz/nvim-dap-go",
dependencies = { { "mfussenegger/nvim-dap", optional = true } },
ft = { "go" },
config = function()
require("dap-go").setup()
end,
},
}

View file

@ -31,7 +31,7 @@ return {
},
{
"lewis6991/gitsigns.nvim", -- show vcs changes on left-hand gutter
event = { "InsertEnter", "CursorHold", "VeryLazy" },
event = { "LazyProject:git" },
cmd = "Gitsigns",
init = function()
if require("core.util").is_available("which-key") then

View file

@ -33,7 +33,7 @@ return {
dependencies = { "williamboman/mason.nvim" },
},
},
event = { "BufReadPost", "BufNewFile", "BufWritePre" },
event = "LazyFile",
opts = {},
},
}

View file

@ -43,7 +43,7 @@ local lsp = {
},
{ "saghen/blink.cmp", optional = true },
},
event = { "BufReadPost", "BufNewFile", "BufWritePre" },
event = "LazyFile",
opts = { servers = get_all_servers() },
init = function()
if require("core.util").is_available("which-key") then

View file

@ -18,25 +18,7 @@ return { -- file/item pickers and managers
"nvim-lua/plenary.nvim",
{ "nvim-tree/nvim-web-devicons", optional = true },
},
init = function()
-- ensure neo-tree gets loaded if we start vim with a directory
-- netrw-like. See https://github.com/nvim-neo-tree/neo-tree.nvim/discussions/1326
vim.api.nvim_create_autocmd("BufEnter", {
group = vim.api.nvim_create_augroup("load_neo_tree", {}),
desc = "Loads neo-tree when opening a directory",
callback = function(args)
local stats = vim.uv.fs_stat(args.file)
if not stats or stats.type ~= "directory" then
return
end
require("neo-tree")
return true
end,
})
end,
event = "StartWithDir",
cmd = "Neotree",
opts = function(_, opts)
opts.sources = { "filesystem", "git_status", "buffers" }

View file

@ -168,7 +168,6 @@ local prose_plugs = {
-- easy copy paste of images into markup files
{
"HakonHarnes/img-clip.nvim",
event = "VeryLazy",
opts = {
filetypes = {
quarto = {

View file

@ -84,7 +84,6 @@ return {
"lazy",
"man",
"mason",
"nvim-dap-ui",
"nvim-tree",
"oil",
"quickfix",

View file

@ -94,13 +94,13 @@ return {
{
"<localleader>tw",
[[<cmd>lua require('neotest').watch.toggle()<cr>]],
desc = "watch current test",
desc = "watch current test toggle",
silent = true,
},
{
"<localleader>tW",
[[<cmd>lua require('neotest').watch.toggle(vim.fn.expand("%"))<cr>]],
desc = "watch current file",
desc = "watch current file toggle",
silent = true,
},
},

View file

@ -1,6 +1,7 @@
return {
{
"nvim-treesitter/nvim-treesitter",
event = "LazyFile",
build = ":TSUpdate",
-- show current cursor context at top of buffer
-- improves commenting plugin above by using ts
@ -28,7 +29,7 @@ return {
goto continue
end
for _, name in pairs(lang.ts) do
table.insert(enabled_parsers,name)
table.insert(enabled_parsers, name)
end
::continue::
end
@ -110,7 +111,6 @@ return {
},
})
end,
event = { "VeryLazy" },
cmd = {
"TSBufDisable",
"TSBufEnable",

View file

@ -94,7 +94,7 @@ return {
"folke/todo-comments.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
opts = {},
event = "VeryLazy",
event = "LazyFile",
},
{
"OXY2DEV/helpview.nvim",