diff --git a/desktop/.config/river/init b/desktop/.config/river/init index 000e921..debf7fc 100755 --- a/desktop/.config/river/init +++ b/desktop/.config/river/init @@ -23,11 +23,11 @@ riverctl border-color-unfocused 0x586e75 # Set repeat rate riverctl set-repeat 75 300 # Make certain views start floating -riverctl float-filter-add app-id float -# riverctl float-filter-add title "popup title with spaces" +riverctl rule-add -app-id float float +# riverctl rule-add -title "popup title with spaces" float # # Set app-ids and titles of views which should use client side decorations -# riverctl csd-filter-add app-id "gedit" -riverctl csd-filter-remove app-id "org.pwmt.zathura" +riverctl rule-add -app-id "gedit" csd +riverctl rule-add -app-id "org.pwmt.zathura" csd ## DEBUG # Reload river configuration diff --git a/nvim/.config/nvim/lazy-lock.json b/nvim/.config/nvim/lazy-lock.json index 68cb24b..f8bd112 100644 --- a/nvim/.config/nvim/lazy-lock.json +++ b/nvim/.config/nvim/lazy-lock.json @@ -9,7 +9,6 @@ "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" }, "cmp-calc": { "branch": "main", "commit": "5947b412da67306c5b68698a02a846760059be2e" }, "cmp-cmdline": { "branch": "main", "commit": "d250c63aa13ead745e3a40f61fdd3470efde3923" }, - "cmp-digraphs": { "branch": "master", "commit": "5efc1f0078d7c5f3ea1c8e3aad04da3fd6e081a9" }, "cmp-latex-symbols": { "branch": "main", "commit": "165fb66afdbd016eaa1570e41672c4c557b57124" }, "cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" }, "cmp-nvim-lsp-signature-help": { "branch": "main", "commit": "031e6ba70b0ad5eee49fd2120ff7a2e325b17fa7" }, @@ -17,7 +16,6 @@ "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" }, "cmp-rg": { "branch": "master", "commit": "677a7874ee8f1afc648c2e7d63a97bc21a7663c5" }, "cmp-spell": { "branch": "master", "commit": "694a4e50809d6d645c1ea29015dad0c293f019d6" }, - "cmp-tmux": { "branch": "main", "commit": "95b1b921802e6f60627b3e76afb9380fddd87f9a" }, "cmp-treesitter": { "branch": "master", "commit": "958fcfa0d8ce46d215e19cc3992c542f576c4123" }, "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" }, "completion-vcard": { "branch": "master", "commit": "2220fd517a985ececed1adcf0e5be8f2815564c7" }, @@ -31,6 +29,7 @@ "git-conflict.nvim": { "branch": "main", "commit": "bfd9fe6fba9a161fc199771d85996236a0d0faad" }, "gitsigns.nvim": { "branch": "main", "commit": "0b04035bb7b3c83e999b9676e2fb46fd0aa9f910" }, "glance.nvim": { "branch": "master", "commit": "51059bcf21016387b6233c89eed220cf47fca752" }, + "grug-far.nvim": { "branch": "main", "commit": "536b23dcf3165a622654544e5f9f395584e73b57" }, "image.nvim": { "branch": "master", "commit": "da64ce69598875c9af028afe129f916b02ccc42e" }, "img-clip.nvim": { "branch": "main", "commit": "fc30500c35663aa1762697f5aba31d43b86028f0" }, "jupytext.nvim": { "branch": "main", "commit": "c8baf3ad344c59b3abd461ecc17fc16ec44d0f7b" }, @@ -49,32 +48,32 @@ "mdeval.nvim": { "branch": "master", "commit": "2c32e2f3e7d8f222e7a4724989f218d036e1081d" }, "mini.nvim": { "branch": "main", "commit": "19e1584124cda35388d4fdb911eab7124014e541" }, "molten-nvim": { "branch": "main", "commit": "eb6d0fe33e14989b0f1fbe25d9732889ee57bd1a" }, - "neogen": { "branch": "main", "commit": "88698b12c3c7db6fcc38e0fa28df5e4ab52c5be6" }, + "neogen": { "branch": "main", "commit": "dc50715c009f89b8111197fd2f282f6042daa7ea" }, "neotest": { "branch": "master", "commit": "32ff2ac21135a372a42b38ae131e531e64833bd3" }, - "neotest-python": { "branch": "master", "commit": "81d2265efac717bb567bc15cc652ae10801286b3" }, + "neotest-python": { "branch": "master", "commit": "e5bff6dcf3cb33e6dfb97722e142961099c6021e" }, "nvim-FeMaco.lua": { "branch": "main", "commit": "96bbf843595dbe865838b3f2484b73557f34700c" }, "nvim-cmp": { "branch": "main", "commit": "ae644feb7b67bf1ce4260c231d1d4300b19c6f30" }, "nvim-colorizer.lua": { "branch": "master", "commit": "194ec600488f7c7229668d0e80bd197f3a2b84ff" }, "nvim-coverage": { "branch": "main", "commit": "aa4b4400588e2259e87e372b1e4e90ae13cf5a39" }, "nvim-lint": { "branch": "master", "commit": "ad0fe35e80f5cd31a0f19176d7b30e5c3011119d" }, - "nvim-lspconfig": { "branch": "master", "commit": "ff97d376b1d22b2eaf9274605531babf0cd0cf21" }, + "nvim-lspconfig": { "branch": "master", "commit": "ad32182cc4a03c8826a64e9ced68046c575fdb7d" }, "nvim-nio": { "branch": "master", "commit": "a428f309119086dc78dd4b19306d2d67be884eee" }, "nvim-surround": { "branch": "main", "commit": "ec2dc7671067e0086cdf29c2f5df2dd909d5f71f" }, "nvim-toggleterm.lua": { "branch": "main", "commit": "48be57eaba817f038d61bbf64d2c597f578c0827" }, "nvim-tree.lua": { "branch": "master", "commit": "ad0b95dee55955817af635fa121f6e2486b10583" }, "nvim-treesitter": { "branch": "master", "commit": "f197a15b0d1e8d555263af20add51450e5aaa1f0" }, - "nvim-treesitter-context": { "branch": "master", "commit": "5efba33af0f39942e426340da7bc15d7dec16474" }, + "nvim-treesitter-context": { "branch": "master", "commit": "0f3332788e0bd37716fbd25f39120dcfd557c90f" }, "nvim-treesitter-endwise": { "branch": "master", "commit": "8b34305ffc28bd75a22f5a0a9928ee726a85c9a6" }, "nvim-treesitter-textsubjects": { "branch": "master", "commit": "a8d2844bba925d9450ef7ab215f3b054028288ca" }, "nvim-ts-autotag": { "branch": "main", "commit": "dc5e1687ab76ee02e0f11c5ce137f530b36e98b3" }, "nvim-ts-context-commentstring": { "branch": "main", "commit": "6b5f95aa4d24f2c629a74f2c935c702b08dbde62" }, "nvim-web-devicons": { "branch": "master", "commit": "5b9067899ee6a2538891573500e8fd6ff008440f" }, - "otter.nvim": { "branch": "main", "commit": "837f258040d0174ff8495584088046f98499b1ac" }, + "otter.nvim": { "branch": "main", "commit": "3b4fa74f0a385207fa9c29b61b07178345a3dab2" }, "peek.nvim": { "branch": "master", "commit": "5820d937d5414baea5f586dc2a3d912a74636e5b" }, "plenary.nvim": { "branch": "master", "commit": "50012918b2fc8357b87cff2a7f7f0446e47da174" }, "popup.nvim": { "branch": "master", "commit": "b7404d35d5d3548a82149238289fa71f7f6de4ac" }, "quarto-nvim": { "branch": "main", "commit": "09fabb62d414e56ee3245c558aaedbdc662b6493" }, - "rainbow-delimiters.nvim": { "branch": "master", "commit": "12b1a1e095d968887a17ef791c2edb78d7595d46" }, + "rainbow-delimiters.nvim": { "branch": "master", "commit": "a2072fef01645c5b06045f126437ff8e2057ef3c" }, "render-markdown": { "branch": "main", "commit": "ced4a66f9bc38580f4797a789d2d5575fcd809fd" }, "smartcolumn.nvim": { "branch": "main", "commit": "d01b99355c7fab13233f48d0f28dc097e68a03f7" }, "stickybuf.nvim": { "branch": "master", "commit": "2160fcd536d81f5fa43f7167dba6634e814e3154" }, diff --git a/nvim/.config/nvim/lua/core/commands.lua b/nvim/.config/nvim/lua/core/commands.lua index 289cd36..d000d38 100644 --- a/nvim/.config/nvim/lua/core/commands.lua +++ b/nvim/.config/nvim/lua/core/commands.lua @@ -5,7 +5,8 @@ vim.api.nvim_create_autocmd({ "TextYankPost" }, { group = vim.api.nvim_create_augroup("highlightyanks", { clear = true }), }) --- Special setting for editing gopass files - make sure nothing leaks outside the directories it is supposed to +-- Special setting for editing gopass files - make sure nothing leaks outside the directories it +-- is supposed to vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { pattern = { "/dev/shm/gopass.*", @@ -41,3 +42,4 @@ vim.api.nvim_create_user_command("SpellToggle", function(opt) vim.notify("Spellcheck disabled") end end, { nargs = "*", bang = true }) + diff --git a/nvim/.config/nvim/lua/core/lazy.lua b/nvim/.config/nvim/lua/core/lazy.lua index f57bf7b..ddb750b 100644 --- a/nvim/.config/nvim/lua/core/lazy.lua +++ b/nvim/.config/nvim/lua/core/lazy.lua @@ -31,8 +31,13 @@ if not vim.loop.fs_stat(lazypath) then end vim.opt.rtp:prepend(lazypath) +-- ensure plugins specs exist before loading into lazy +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 {} + require("lazy").setup({ - spec = { { import = "plugins" } }, + spec = { spec }, defaults = { lazy = true, version = "*" }, performance = { rtp = { disabled_plugins = { "netrw", "netrwPlugin" } }, diff --git a/nvim/.config/nvim/lua/core/mappings.lua b/nvim/.config/nvim/lua/core/mappings.lua index 4384247..7f457e9 100644 --- a/nvim/.config/nvim/lua/core/mappings.lua +++ b/nvim/.config/nvim/lua/core/mappings.lua @@ -6,8 +6,9 @@ if is_available("which-key") then prefix({ { "v", group = "vim" }, { "s", group = "show" }, - { "s", group = "set" }, { "Z", group = "spelling" }, + { "]o", group = "options" }, + { "[o", group = "options" }, }) end @@ -127,8 +128,16 @@ map("x", "q", "gq", { silent = true, desc = "Format {motion}" }) map("n", "Q", "vapJgqap", { silent = true, desc = "Unformat then format paragraph" }) -- SPELL CHECKING --- Move to the prev/next spelling error with [S ]S --- Move to the prev/next spelling error or suggestion with [s ]s +-- Move to the prev/next spelling error with [z|[Z ]Z|]z instead of ]s +map("n", "]z", "]s") +map("n", "[z", "[s") +map("n", "]s", "") +map("n", "[s", "") +map("n", "]Z", "]S") +map("n", "[Z", "[S") +map("n", "]S", "") +map("n", "[S", "") +-- Move to the prev/next spelling error or suggestion with [z ]z map("n", "ZZ", "SpellToggle en_us en_gb de_de", { desc = "Toggle spellcheck" }) map("n", "ZA", "SpellToggle! en_us en_gb de_de", { desc = "Enable spellcheck" }) map("n", "ZE", "SpellToggle en_us", { desc = "Toggle EN_US spellcheck" }) diff --git a/nvim/.config/nvim/lua/plugins/core.lua b/nvim/.config/nvim/lua/plugins/base.lua similarity index 60% rename from nvim/.config/nvim/lua/plugins/core.lua rename to nvim/.config/nvim/lua/plugins/base.lua index d267be6..35bac31 100644 --- a/nvim/.config/nvim/lua/plugins/core.lua +++ b/nvim/.config/nvim/lua/plugins/base.lua @@ -92,8 +92,8 @@ return { -- collection of plugins { "echasnovski/mini.nvim", - version = "*", - dependencies = { "rktjmp/fwatch.nvim" }, + dependencies = { "rktjmp/fwatch.nvim" }, -- for colorscheme updating + event = "VimEnter", -- need to load pretty soon for Starter screen config = function() -- automatic callback to invoke 'mini.base16' when colorscheme file is changed local colorsfile = vim.fn.stdpath("state") .. "/colorscheme.lua" @@ -112,62 +112,7 @@ return { end), }) - 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 = "d", options = {} }, - file = { suffix = "", options = {} }, - indent = { suffix = "" }, -- disable since we use indentscope above - 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.files").setup() - vim.api.nvim_create_autocmd("User", { - pattern = "MiniFilesWindowUpdate", - callback = function(args) - vim.wo[args.data.win_id].number = true - end, - }) - - require("mini.fuzzy").setup() - require("mini.indentscope").setup({ - symbol = "│", - draw = { animation = require("mini.indentscope").gen_animation.none() }, - options = { indent_at_cursor = false }, - }) - require("mini.map").setup() - require("mini.move").setup() - require("mini.operators").setup() - require("mini.pairs").setup() - require("mini.trailspace").setup() + -- this should be loaded as soon as the plugin is loaded local starter = require("mini.starter") starter.setup({ evaluate_single = true, @@ -190,8 +135,82 @@ return { starter.gen_hook.aligning("center", "center"), }, }) + require("mini.files").setup({ + mappings = { + synchronize = "S", + go_in = "L", -- switch go-ins around + go_in_plus = "l", + go_out = "H", + go_out_plus = "h", + }, + options = { + use_as_default_explorer = true, + }, + }) + vim.api.nvim_create_autocmd("User", { + pattern = "MiniFilesWindowUpdate", + callback = function(args) + local win_id = args.data.win_id + + vim.wo[win_id].number = true + end, + }) + + -- manually create lazy loading scenarios + vim.api.nvim_create_autocmd({ "InsertEnter", "CursorHold" }, { + once = true, + 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 = "d", options = {} }, + file = { suffix = "", options = {} }, + indent = { suffix = "" }, -- disable since we use indentscope above + 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 }, + }) + require("mini.map").setup() + require("mini.move").setup() + require("mini.operators").setup() + require("mini.pairs").setup() + require("mini.trailspace").setup() + end, + }) end, - event = "VimEnter", -- need to load pretty soon for Starter screen keys = { { "sm", diff --git a/nvim/.config/nvim/lua/plugins/completion.lua b/nvim/.config/nvim/lua/plugins/completion.lua index e8dedd7..6d38c40 100644 --- a/nvim/.config/nvim/lua/plugins/completion.lua +++ b/nvim/.config/nvim/lua/plugins/completion.lua @@ -1,53 +1,29 @@ -return { - -- completion setup +local completion_engine = { { "hrsh7th/nvim-cmp", branch = "main", - version = false, + version = false, -- new releases (>2022) are sadly not versioned dependencies = { - "andersevenrud/cmp-tmux", - "cbarrete/completion-vcard", - "f3fora/cmp-spell", + -- TODO: Move to lsp "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-nvim-lsp-signature-help", "hrsh7th/cmp-path", "hrsh7th/cmp-buffer", "hrsh7th/cmp-calc", "hrsh7th/cmp-cmdline", - "hrsh7th/cmp-nvim-lsp-signature-help", - "dmitmel/cmp-digraphs", + -- TODO: Move me into a separate load? + "cbarrete/completion-vcard", + "f3fora/cmp-spell", "jc-doyle/cmp-pandoc-references", - "kdheepak/cmp-latex-symbols", + -- TODO: Decide: get rid or just enable in very specific circumstances "lukas-reineke/cmp-rg", - "crispgm/cmp-beancount", + -- TODO: Move to treesitter { "ray-x/cmp-treesitter", dependencies = { "nvim-treesitter/nvim-treesitter" } }, - { - "saadparwaiz1/cmp_luasnip", - dependencies = { - - { - "L3MON4D3/LuaSnip", - dependencies = { - "rafamadriz/friendly-snippets", - { - "benfowler/telescope-luasnip.nvim", - dependencies = { { "nvim-telescope/telescope.nvim", optional = true } }, - config = function() - require("telescope").load_extension("luasnip") - end, - }, - }, - build = "make install_jsregexp", - config = function() - require("luasnip.loaders.from_vscode").lazy_load({ exclude = { "markdown", "quarto" } }) - require("luasnip.loaders.from_snipmate").lazy_load() - end, - }, - }, - }, }, - config = function() - local luasnip = require("luasnip") + opts = function() local cmp = require("cmp") + -- style 'ghosttext' which appears behind cursor, showing current completion + vim.api.nvim_set_hl(0, "CmpGhostText", { link = "Comment", default = true }) local has_words_before = function() ---@diagnostic disable-next-line:deprecated @@ -84,32 +60,42 @@ return { TypeParameter = "", } - cmp.setup({ + -- `/` cmdline setup. + cmp.setup.cmdline("/", { + completion = { completeopt = "menu,menuone,noinsert,noselect" }, + preselect = cmp.PreselectMode.None, + mapping = cmp.mapping.preset.cmdline(), + sources = { { name = "buffer" } }, + }) + -- `:` cmdline setup. + cmp.setup.cmdline(":", { + completion = { completeopt = "menu,menuone,noinsert,noselect" }, + preselect = cmp.PreselectMode.None, + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ { name = "path" } }, { + { name = "cmdline", option = { ignore_cmds = { "Man", "!" } } }, + }), + }) + return { window = { documentation = cmp.config.window.bordered() }, - snippet = { - expand = function(args) - require("luasnip").lsp_expand(args.body) - end, + -- add noselect to not automatically select first item + completion = { completeopt = "menu,menuone,noinsert" }, + preselect = cmp.PreselectMode.Item, -- not sure what this changes diff than above? + experimental = { + ghost_text = { + hl_group = "CmpGhostText", + }, }, sources = { - { - name = "beancount", - option = { - account = vim.env["HOME"] .. "/documents/records/budget/main.beancount", -- TODO implement dynamically - }, - }, { name = "nvim_lsp" }, { name = "nvim_lsp_signature_help" }, - { name = "luasnip", keyword_length = 1 }, { name = "pandoc_references" }, { name = "calc" }, { name = "path" }, { name = "buffer", keyword_length = 3 }, - { name = "latex_symbols" }, { name = "spell", keyword_length = 3 }, - { name = "tmux" }, -- { name = 'rg', keyword_length = 5 }, + -- { name = 'rg', keyword_length = 5 }, { name = "vCard" }, - { name = "digraphs", keyword_length = 2 }, }, mapping = cmp.mapping.preset.insert({ [""] = cmp.mapping.scroll_docs(-4), @@ -134,9 +120,7 @@ return { [""] = cmp.mapping(function(fallback) -- expand_or_jumpable() will always jump -- expand_or_locally_jumpable() only jumps when still inside snippet region - if luasnip.expand_or_locally_jumpable() then - luasnip.expand_or_jump() - elseif cmp.visible() then + if cmp.visible() then cmp.select_next_item() elseif has_words_before() then cmp.complete() @@ -145,9 +129,7 @@ return { end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) - if luasnip.jumpable(-1) then - luasnip.jump(-1) - elseif cmp.visible() then + if cmp.visible() then cmp.select_prev_item() else fallback() @@ -178,20 +160,111 @@ return { return vim_item end, }, - }) - -- `/` cmdline setup. - cmp.setup.cmdline("/", { - mapping = cmp.mapping.preset.cmdline(), - sources = { { name = "buffer" } }, - }) - -- `:` cmdline setup. - cmp.setup.cmdline(":", { - mapping = cmp.mapping.preset.cmdline(), - sources = cmp.config.sources({ { name = "path" } }, { - { name = "cmdline", option = { ignore_cmds = { "Man", "!" } } }, - }), - }) + } end, event = { "InsertEnter", "CmdlineEnter" }, }, } +-- +-- TODO: Enable more lazy loaded startup? And integrate into +-- cmp as insert source instead of in its setup config below. +local snippet_engine = { + "nvim-cmp", + dependencies = { + "L3MON4D3/LuaSnip", + "rafamadriz/friendly-snippets", + "saadparwaiz1/cmp_luasnip", + { + "benfowler/telescope-luasnip.nvim", + dependencies = { { "nvim-telescope/telescope.nvim", optional = true } }, + config = function() + if require("core.util").is_available("telescope") then + require("telescope").load_extension("luasnip") + end + end, + }, + }, + event = { "InsertEnter" }, + build = "make install_jsregexp", + opts = function(_, opts) + local cmp = require("cmp") + local luasnip = require("luasnip") + + require("luasnip.loaders.from_vscode").lazy_load({ exclude = { "markdown", "quarto" } }) + require("luasnip.loaders.from_snipmate").lazy_load() + + opts.snippet = { + expand = function(item) + require("luasnip").lsp_expand(item.body) + end, + } + local has_words_before = function() + ---@diagnostic disable-next-line:deprecated + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end + + table.insert(opts.sources, { name = "luasnip", keyword_length = 1 }) + + opts.mapping[""] = cmp.mapping(function(fallback) -- expand_or_jumpable() will always jump + -- expand_or_locally_jumpable() only jumps when still inside snippet region + if luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + elseif cmp.visible() then + cmp.select_next_item() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { "i", "s" }) + opts.mapping[""] = cmp.mapping(function(fallback) + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + elseif cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end, { "i", "s" }) + end, +} + +local beancount_cmp = { + "nvim-cmp", + dependencies = { + "crispgm/cmp-beancount", + }, + ft = "beancount", + opts = function(_, opts) + vim.g.python3_host_prog = "/home/marty/.local/pipx/venvs/beancount/bin/python" + table.insert(opts.sources, { + name = "beancount", + -- option = { + -- -- TODO: implement dynamically + -- -- I believe if we don't supply this it automatically takes + -- -- from the open file which would be good enough + -- account = "/home/marty/documents/records/budget/main.beancount", + -- }, + }) + end, +} + +local latex_cmp = { + "nvim-cmp", + dependencies = { + -- TODO: Needs better lazy loading + "kdheepak/cmp-latex-symbols", + }, + event = "CursorHold", + opts = function(_, opts) + table.insert(opts.sources, { name = "latex_symbols" }) + end, +} + +return { + completion_engine, + snippet_engine, + beancount_cmp, + latex_cmp, +} diff --git a/nvim/.config/nvim/lua/plugins/formatting.lua b/nvim/.config/nvim/lua/plugins/formatting.lua index ad7414e..42c24d8 100644 --- a/nvim/.config/nvim/lua/plugins/formatting.lua +++ b/nvim/.config/nvim/lua/plugins/formatting.lua @@ -4,6 +4,7 @@ local formatters = { bash = { "shfmt" }, bib = { "bibtex-tidy" }, css = { "prettier", "rustywind" }, + go = { "gofumpt" }, graphql = { "prettier" }, html = { "prettier", "rustywind" }, javascript = { "prettier" }, diff --git a/nvim/.config/nvim/lua/plugins/linting.lua b/nvim/.config/nvim/lua/plugins/linting.lua index 89af1e8..53e0946 100644 --- a/nvim/.config/nvim/lua/plugins/linting.lua +++ b/nvim/.config/nvim/lua/plugins/linting.lua @@ -3,6 +3,7 @@ local linters = { bash = { "shellcheck" }, javascript = { "eslint_d" }, javascriptreact = { "eslint_d" }, + go = { "revive" }, markdown = { "markdownlint" }, quarto = { "markdownlint" }, sh = { "shellcheck" }, diff --git a/nvim/.config/nvim/lua/plugins/lsp.lua b/nvim/.config/nvim/lua/plugins/lsp.lua index 097ed94..d54c8f6 100644 --- a/nvim/.config/nvim/lua/plugins/lsp.lua +++ b/nvim/.config/nvim/lua/plugins/lsp.lua @@ -34,6 +34,7 @@ local servers = { serve_d = {}, taplo = {}, texlab = {}, + tinymist = {}, tsserver = {}, yamlls = {}, } diff --git a/nvim/.config/nvim/lua/plugins/pickers.lua b/nvim/.config/nvim/lua/plugins/pickers.lua index 1d715cb..7637b6d 100644 --- a/nvim/.config/nvim/lua/plugins/pickers.lua +++ b/nvim/.config/nvim/lua/plugins/pickers.lua @@ -23,6 +23,7 @@ return { { "se", "NvimTreeToggle", desc = "filetree", silent = true }, }, }, + { "MagicDuck/grug-far.nvim", lazy = false, opts = {} }, -- fuzzy matching picker { "nvim-telescope/telescope.nvim", @@ -42,6 +43,13 @@ return { -- rg (ripgrep) for in-text searches -- fd for quicker directory structure searches -- lsp for a variety of lsp queries + local trouble_mappings = {} + if require("core.util").is_available("trouble") then + trouble_mappings = { + i = { [""] = require("trouble.sources.telescope").open }, + n = { [""] = require("trouble.sources.telescope").open }, + } + end require("telescope").setup({ defaults = { vimgrep_arguments = { @@ -60,11 +68,7 @@ return { prompt_prefix = "󰍉 ", selection_caret = "󰳟 ", color_devicons = true, - mappings = { - -- FIXME Find way to only invoke this *IF* trouble plugin is found - i = { [""] = require("trouble.sources.telescope").open }, - n = { [""] = require("trouble.sources.telescope").open }, - }, + mappings = trouble_mappings or {}, }, pickers = { buffers = { theme = "ivy" }, @@ -174,4 +178,21 @@ return { }, }, }, + { + "jiaoshijie/undotree", + dependencies = { + "nvim-lua/plenary.nvim", + }, + config = true, + keys = { + { + "su", + function() + require("undotree").toggle() + end, + desc = "toggle undotree", + silent = true, + }, + }, + }, } diff --git a/nvim/.config/nvim/lua/plugins/prose.lua b/nvim/.config/nvim/lua/plugins/prose.lua index b0a3e16..76b0b45 100644 --- a/nvim/.config/nvim/lua/plugins/prose.lua +++ b/nvim/.config/nvim/lua/plugins/prose.lua @@ -1,4 +1,28 @@ -local writing_ft = { "quarto", "pandoc", "markdown", "text", "tex", "typst", "bib", "context", "rst", "vimwiki" } +local md_like = { + "markdown", + "pandoc", + "quarto", + "vimwiki", +} +local org_like = { + "norg", + "org", +} +local prose_ft = { + unpack(md_like), + unpack(org_like), + "asciidoc", + "bib", + "context", + "gitcommit", + "latex", + "mail", + "rst", + "tex", + "text", + "typst", + "rmd", +} local prose_plugs = { -- UI improvements @@ -13,30 +37,29 @@ local prose_plugs = { { "andrewferrier/wrapping.nvim", opts = { - create_keymappings = false, + create_keymaps = false, notify_on_switch = false, - softener = { quarto = true, markdown = true, text = true, asciidoc = true }, - auto_set_mode_filetype_allowlist = { - "asciidoc", - "gitcommit", - "latex", - "mail", - "markdown", - "rst", - "tex", - "text", - "quarto", - }, + -- softener = { quarto = true, markdown = true, text = true, asciidoc = true }, + auto_set_mode_filetype_allowlist = prose_ft, }, - event = { "BufReadPre", "BufNewFile" }, + -- event = { "BufReadPre", "BufNewFile" }, + ft = prose_ft, keys = { { - "sw", + "[ow", function() - require("wrapping").toggle_wrap_mode() + require("wrapping").soft_wrap_mode() end, silent = true, - desc = "toggle wrap mode", + desc = "soft wrap", + }, + { + "]ow", + function() + require("wrapping").hard_wrap_mode() + end, + silent = true, + desc = "hard wrap", }, }, }, @@ -45,16 +68,16 @@ local prose_plugs = { "MeanderingProgrammer/render-markdown.nvim", main = "render-markdown", opts = { - file_types = { "markdown", "quarto", "pandoc", "vimwiki", "norg", "rmd", "org" }, - code = { - sign = false, - width = 'block', - right_pad = 1, - }, + file_types = { unpack(md_like) }, + code = { + sign = false, + width = "block", + right_pad = 1, + }, }, name = "render-markdown", -- Only needed if you have another plugin named markdown.nvim dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" }, -- if you prefer nvim-web-devicons - ft = writing_ft, + ft = md_like, cmd = "RenderMarkdown", keys = { { @@ -74,6 +97,7 @@ local prose_plugs = { event = { "VeryLazy" }, cond = vim.fn.executable("deno") == 1, build = "deno task --quiet build:fast", + ft = md_like, config = function() require("peek").setup() vim.api.nvim_create_user_command("PeekOpen", require("peek").open, {}) @@ -82,11 +106,12 @@ local prose_plugs = { }, { "iamcco/markdown-preview.nvim", + event = { "VeryLazy" }, cond = vim.fn.executable("deno") == 0, build = function() vim.fn["mkdp#util#install"]() end, - ft = writing_ft, + ft = md_like, }, -- easy copy paste of images into markup files @@ -106,7 +131,7 @@ local prose_plugs = { keys = { { "pi", "PasteImage", desc = "Paste image from system clipboard" }, }, - ft = writing_ft, + ft = prose_ft, }, -- bring zettelkasten commands @@ -135,7 +160,7 @@ local prose_plugs = { }, }) end, - ft = writing_ft, + ft = prose_ft, cmd = { "ZkBacklinks", "ZkCd", @@ -173,7 +198,7 @@ local prose_plugs = { }, -- syntax highlighting for markdown criticmarkup (comments, additions, ...) - { "vim-pandoc/vim-criticmarkup", ft = writing_ft }, + { "vim-pandoc/vim-criticmarkup", ft = md_like }, -- create mindmaps from your markdown { diff --git a/nvim/.config/nvim/lua/plugins/statusline.lua b/nvim/.config/nvim/lua/plugins/statusline.lua new file mode 100644 index 0000000..468067b --- /dev/null +++ b/nvim/.config/nvim/lua/plugins/statusline.lua @@ -0,0 +1,90 @@ +return { + -- statusline + { + "nvim-lualine/lualine.nvim", + cond = true, + dependencies = { { "nvim-tree/nvim-web-devicons", config = true } }, + config = function() + local has_pynvim = -1 + -- if molten exists, is initialized and connected to a kernel + -- show it in the statusline + local function molten() + -- we don't have access to python, disregard element + if has_pynvim == 0 then + return "" + elseif has_pynvim == 1 then + local status_ok, res = pcall(function() + return require("molten.status").kernels() ~= "" + end) + if status_ok and res then + return "󱪄" + end + return "" + -- we don't know if we have python yet, start a check + else + vim.system({ "poetry", "env", "info", "-p" }, { text = true }, function(obj) + if obj.code == 0 then + has_pynvim = 1 + else + has_pynvim = 0 + end + end) + has_pynvim = 0 + end + end + + -- count number of selected lines and characters + -- stolen: https://github.com/chrisgrieser/.config/blob/8af1841ba24f7c81c513e12f853b52f530ef5b37/nvim/lua/plugins/lualine.lua#L80C1-L87C4 + local function selectionCount() + local isVisualMode = vim.fn.mode():find("[Vv]") + if not isVisualMode then + return "" + end + local starts = vim.fn.line("v") + local ends = vim.fn.line(".") + local lines = starts <= ends and ends - starts + 1 or starts - ends + 1 + return " " .. tostring(lines) .. "L " .. tostring(vim.fn.wordcount().visual_chars) .. "C" + end + require("lualine").setup({ + options = { + icons_enabled = true, + theme = "auto", + component_separators = { left = "", right = "" }, + section_separators = { left = "", right = "" }, + disabled_filetypes = {}, + always_divide_middle = true, + }, + sections = { + lualine_a = { "mode" }, + lualine_b = { "branch", "diff", "diagnostics" }, + lualine_c = { "filename" }, + lualine_x = { "encoding", "fileformat", "filetype", molten }, + lualine_y = { "progress" }, + lualine_z = { selectionCount, "location" }, + }, + inactive_sections = { + lualine_a = {}, + lualine_b = { "branch", "diff" }, + lualine_c = { "filename" }, + lualine_x = {}, + lualine_y = { "location" }, + lualine_z = {}, + }, + tabline = {}, + extensions = { + "aerial", + "lazy", + "man", + "mason", + "nvim-dap-ui", + "nvim-tree", + "oil", + "quickfix", + "toggleterm", + "trouble", + }, + }) + end, + event = { "VeryLazy" }, + }, +} diff --git a/nvim/.config/nvim/lua/plugins/terminal.lua b/nvim/.config/nvim/lua/plugins/terminal.lua new file mode 100644 index 0000000..ac97546 --- /dev/null +++ b/nvim/.config/nvim/lua/plugins/terminal.lua @@ -0,0 +1,103 @@ +return { + -- simpler, programmable and multiple terminal toggling for nvim + { + "akinsho/nvim-toggleterm.lua", + config = function() + require("toggleterm").setup({ + open_mapping = [[=]], + insert_mappings = false, -- don't map the key in insert mode + terminal_mappings = false, + }) + + local Terminal = require("toggleterm.terminal").Terminal + + -- need to disable indentlines since they obscure first line of terminal + if require("core.util").is_available("mini.nvim") then + vim.api.nvim_create_autocmd({ "TermOpen" }, { + pattern = "*", + callback = function() + vim.b.miniindentscope_disable = true + end, + }) + end + + local function custom_term_set_toggle_key(term) + vim.keymap.set("t", "", function() + term:toggle() + end, { silent = true, buffer = true }) + end + + -- create python window + local function get_python_cmd() + if vim.fn.executable("py") then + return "py" + end + if vim.fn.executable("ptipython") then + return "ptipython" + end + if vim.fn.executable("ipython") then + return "ipython" + end + if vim.fn.executable("ptpython") then + return "ptpython" + end + if vim.fn.executable("python") then + return "python" + end + end + local terms = { + lazygit = Terminal:new({ + cmd = "lazygit", + hidden = true, + direction = "float", + float_opts = { border = "curved" }, + on_open = custom_term_set_toggle_key, + }), + python = Terminal:new({ + cmd = get_python_cmd(), + hidden = true, + direction = "float", + float_opts = { border = "curved" }, + on_open = custom_term_set_toggle_key, + }), + } + -- create a lazygit window with the lazygit command + local function toggle_custom_term(term, bang, vertsize) + vertsize = vertsize or vim.o.columns * 0.4 + if not bang then + term.direction = "float" + term:toggle() + else + term.direction = "vertical" + term:resize(vertsize) + term:toggle() + end + end + + local function _Pythonterm_toggle(opts) + toggle_custom_term(terms.python, opts.bang) + end + local function _Lazygit_toggle(opts) + toggle_custom_term(terms.lazygit, opts.bang, vim.o.columns * 0.6) + end + + vim.api.nvim_create_user_command( + "Lazygit", + _Lazygit_toggle, + { desc = "Toggle floating Lazygit terminal", bang = true } + ) + vim.api.nvim_create_user_command( + "Pythonterm", + _Pythonterm_toggle, + { desc = "Toggle floating Python terminal", bang = true } + ) + end, + cmd = { "ToggleTerm", "TermExec", "Lazygit", "Pythonterm" }, + keys = { + { "sg", ":Lazygit", desc = "git floating" }, + { "sG", ":Lazygit!", desc = "git buffer" }, + { "sp", ":Pythonterm", desc = "python floating" }, + { "sP", ":Pythonterm!", desc = "python buffer" }, + }, + }, +} diff --git a/nvim/.config/nvim/lua/plugins/testing.lua b/nvim/.config/nvim/lua/plugins/testing.lua index 208fc6c..4da2e00 100644 --- a/nvim/.config/nvim/lua/plugins/testing.lua +++ b/nvim/.config/nvim/lua/plugins/testing.lua @@ -37,7 +37,7 @@ return { adapters = { require("neotest-python")({ -- with coverage requires coverage.py and pytest-cov installed - args = { "--cov" }, + args = { "--cov", "--doctest-modules" }, }), }, }) diff --git a/nvim/.config/nvim/lua/plugins/ui.lua b/nvim/.config/nvim/lua/plugins/ui.lua index ce6539e..33d0684 100644 --- a/nvim/.config/nvim/lua/plugins/ui.lua +++ b/nvim/.config/nvim/lua/plugins/ui.lua @@ -1,91 +1,4 @@ return { - -- statusline - { - "nvim-lualine/lualine.nvim", - dependencies = { { "nvim-tree/nvim-web-devicons", config = true } }, - config = function() - local has_pynvim = -1 - -- if molten exists, is initialized and connected to a kernel - -- show it in the statusline - local function molten() - -- we don't have access to python, disregard element - if has_pynvim == 0 then - return "" - elseif has_pynvim == 1 then - local status_ok, res = pcall(function() - return require("molten.status").kernels() ~= "" - end) - if status_ok and res then - return "󱪄" - end - return "" - -- we don't know if we have python yet, start a check - else - vim.system({ "poetry", "env", "info", "-p" }, { text = true }, function(obj) - if obj.code == 0 then - has_pynvim = 1 - else - has_pynvim = 0 - end - end) - has_pynvim = 0 - end - end - - -- count number of selected lines and characters - -- stolen: https://github.com/chrisgrieser/.config/blob/8af1841ba24f7c81c513e12f853b52f530ef5b37/nvim/lua/plugins/lualine.lua#L80C1-L87C4 - local function selectionCount() - local isVisualMode = vim.fn.mode():find("[Vv]") - if not isVisualMode then - return "" - end - local starts = vim.fn.line("v") - local ends = vim.fn.line(".") - local lines = starts <= ends and ends - starts + 1 or starts - ends + 1 - return " " .. tostring(lines) .. "L " .. tostring(vim.fn.wordcount().visual_chars) .. "C" - end - require("lualine").setup({ - options = { - icons_enabled = true, - theme = "auto", - component_separators = { left = "", right = "" }, - section_separators = { left = "", right = "" }, - disabled_filetypes = {}, - always_divide_middle = true, - }, - sections = { - lualine_a = { "mode" }, - lualine_b = { "branch", "diff", "diagnostics" }, - lualine_c = { "filename" }, - lualine_x = { "encoding", "fileformat", "filetype", molten }, - lualine_y = { "progress" }, - lualine_z = { selectionCount, "location" }, - }, - inactive_sections = { - lualine_a = {}, - lualine_b = { "branch", "diff" }, - lualine_c = { "filename" }, - lualine_x = {}, - lualine_y = { "location" }, - lualine_z = {}, - }, - tabline = {}, - extensions = { - "aerial", - "lazy", - "man", - "mason", - "nvim-dap-ui", - "nvim-tree", - "oil", - "quickfix", - "toggleterm", - "trouble", - }, - }) - end, - event = { "VeryLazy" }, - }, -- create pretty unobtrusive notifications { "j-hui/fidget.nvim", @@ -143,11 +56,33 @@ return { "ColorizerReloadAllBuffers", }, keys = { - { "sc", "ColorizerToggle", { silent = true, desc = "toggle colorizer" } }, { - "sC", - 'lua require("colorizer").attach_to_buffer(0, {mode = "background"} )', - { silent = true, desc = "colorize background" }, + "[oc", + function() + require("colorizer").detach_from_buffer(0) + end, + { silent = true, desc = "colorize disable" }, + }, + { + "]oc", + function() + require("colorizer").attach_to_buffer(0) + end, + { silent = true, desc = "colorize enable" }, + }, + { + "]oC", + function() + require("colorizer").attach_to_buffer(0, { mode = "background" }) + end, + { silent = true, desc = "colorize bg" }, + }, + { + "[oC", + function() + require("colorizer").attach_to_buffer(0, { mode = "virtualtext" }) + end, + { silent = true, desc = "colorize eol" }, }, }, }, @@ -157,122 +92,4 @@ return { opts = {}, event = "VeryLazy", }, - { - "jiaoshijie/undotree", - dependencies = { - "nvim-lua/plenary.nvim", - }, - config = true, - keys = { - { - "su", - function() - require("undotree").toggle() - end, - desc = "toggle undotree", - silent = true, - }, - }, - }, - -- simpler, programmable and multiple terminal toggling for nvim - { - "akinsho/nvim-toggleterm.lua", - config = function() - require("toggleterm").setup({ - open_mapping = [[=]], - insert_mappings = false, -- don't map the key in insert mode - terminal_mappings = false, - }) - - local Terminal = require("toggleterm.terminal").Terminal - - -- need to disable indentlines since they obscure first line of terminal - if require("core.util").is_available("mini.nvim") then - vim.api.nvim_create_autocmd({ "TermOpen" }, { - pattern = "*", - callback = function() - vim.b.miniindentscope_disable = true - end, - }) - end - - local function custom_term_set_toggle_key(term) - vim.keymap.set("t", "", function() - term:toggle() - end, { silent = true, buffer = true }) - end - - -- create python window - local function get_python_cmd() - if vim.fn.executable("py") then - return "py" - end - if vim.fn.executable("ptipython") then - return "ptipython" - end - if vim.fn.executable("ipython") then - return "ipython" - end - if vim.fn.executable("ptpython") then - return "ptpython" - end - if vim.fn.executable("python") then - return "python" - end - end - local terms = { - lazygit = Terminal:new({ - cmd = "lazygit", - hidden = true, - direction = "float", - float_opts = { border = "curved" }, - on_open = custom_term_set_toggle_key, - }), - python = Terminal:new({ - cmd = get_python_cmd(), - hidden = true, - direction = "float", - float_opts = { border = "curved" }, - on_open = custom_term_set_toggle_key, - }), - } - -- create a lazygit window with the lazygit command - local function toggle_custom_term(term, bang, vertsize) - vertsize = vertsize or vim.o.columns * 0.4 - if not bang then - term.direction = "float" - term:toggle() - else - term.direction = "vertical" - term:resize(vertsize) - term:toggle() - end - end - - local function _Pythonterm_toggle(opts) - toggle_custom_term(terms.python, opts.bang) - end - local function _Lazygit_toggle(opts) - toggle_custom_term(terms.lazygit, opts.bang, vim.o.columns * 0.6) - end - - vim.api.nvim_create_user_command( - "Lazygit", - _Lazygit_toggle, - { desc = "Toggle floating Lazygit terminal", bang = true } - ) - vim.api.nvim_create_user_command( - "Pythonterm", - _Pythonterm_toggle, - { desc = "Toggle floating Python terminal", bang = true } - ) - end, - cmd = { "ToggleTerm", "TermExec", "Lazygit", "Pythonterm" }, - keys = { - { "sg", ":Lazygit", desc = "git floating" }, - { "sG", ":Lazygit!", desc = "git buffer" }, - { "sp", ":Pythonterm", desc = "python floating" }, - { "sP", ":Pythonterm!", desc = "python buffer" }, - }, - }, } diff --git a/sh/.config/sh/alias b/sh/.config/sh/alias index f316329..5ac00fa 100644 --- a/sh/.config/sh/alias +++ b/sh/.config/sh/alias @@ -40,6 +40,11 @@ alias ...="cd ../.." alias ~="cd ~" alias md="mkdir -p" +mcd() { + mkdir -p "$@" + cd "$1" || exit 1 +} + # clear my screen alias cl="clear"