diff --git a/home/features/neovim/config/ftplugin/hkf.lua b/home/features/neovim/config/ftplugin/hkf.lua deleted file mode 100644 index c8e8ccc..0000000 --- a/home/features/neovim/config/ftplugin/hkf.lua +++ /dev/null @@ -1 +0,0 @@ -vim.api.nvim_buf_set_option(0, "commentstring", "-- %s") diff --git a/home/features/neovim/config/ftplugin/markdown.lua b/home/features/neovim/config/ftplugin/markdown.lua deleted file mode 100644 index a1d0d70..0000000 --- a/home/features/neovim/config/ftplugin/markdown.lua +++ /dev/null @@ -1 +0,0 @@ -require("my.helpers.wrapMovement").enable() diff --git a/home/features/neovim/config/ftplugin/nix.lua b/home/features/neovim/config/ftplugin/nix.lua deleted file mode 100644 index c49ab7f..0000000 --- a/home/features/neovim/config/ftplugin/nix.lua +++ /dev/null @@ -1,9 +0,0 @@ --- Use _lg_ to fetchgit stuff -vim.keymap.set("n", "lg", function() - require("my.tempest").withSavedCursor(function() - vim.cmd(":%!update-nix-fetchgit") - end) -end, { buffer = true, desc = "Update all fetchgit calls" }) - --- Idk why this isn't here by default -vim.api.nvim_buf_set_option(0, "commentstring", "# %s") diff --git a/home/features/neovim/config/ftplugin/tex.lua b/home/features/neovim/config/ftplugin/tex.lua index 4e8ad72..9cd7196 100644 --- a/home/features/neovim/config/ftplugin/tex.lua +++ b/home/features/neovim/config/ftplugin/tex.lua @@ -1,7 +1,6 @@ local A = require("my.abbreviations") local scrap = require("scrap") -require("my.helpers.wrapMovement").enable() require("my.abbreviations.math").setup() vim.opt.conceallevel = 0 diff --git a/home/features/neovim/config/ftplugin/typst.lua b/home/features/neovim/config/ftplugin/typst.lua index 62714cb..6636bc6 100644 --- a/home/features/neovim/config/ftplugin/typst.lua +++ b/home/features/neovim/config/ftplugin/typst.lua @@ -1,3 +1,2 @@ -require("my.helpers.wrapMovement").enable() require("my.abbreviations.math").setup() require("my.abbreviations.unicode").setup() diff --git a/home/features/neovim/config/lazy-lock.json b/home/features/neovim/config/lazy-lock.json index feac94c..b3a9cc5 100644 --- a/home/features/neovim/config/lazy-lock.json +++ b/home/features/neovim/config/lazy-lock.json @@ -14,6 +14,7 @@ "conform": { "branch": "master", "commit": "48bc9996ebfe90e7766f46338360f75fd6ecb174" }, "crates": { "branch": "main", "commit": "b8ea20fda2e1029fbbb1bae7a9eab35c84037ca0" }, "discord-rich-presence": { "branch": "main", "commit": "87c857a56b7703f976d3a5ef15967d80508df6e6" }, + "dressing": { "branch": "master", "commit": "94b0d24483d56f3777ee0c8dc51675f21709318c" }, "edit-code-block": { "branch": "main", "commit": "5e4e31012eafa113216cb5894f696682833f8e7f" }, "fidget": { "branch": "main", "commit": "0ba1e16d07627532b6cae915cc992ecac249fb97" }, "flash": { "branch": "main", "commit": "48817af25f51c0590653bbc290866e4890fe1cbe" }, @@ -37,6 +38,7 @@ "mini.comment": { "branch": "main", "commit": "3d9c8009615857e982f09bc5357fc95f2a2175f3" }, "mini.files": { "branch": "main", "commit": "173d73f5d0b2a9abbb2d6533a3770fdbbd0c4dcc" }, "mini.operators": { "branch": "main", "commit": "7a97e2528a4c274e9da8953d3ba22f493c360a9f" }, + "mini.pairs": { "branch": "main", "commit": "552062017ff207e1f35f7028bfb3f27c7421d22d" }, "mini.statusline": { "branch": "main", "commit": "950d9029c7ed901b67c839e74478f784b7432665" }, "mini.surround": { "branch": "main", "commit": "af8129efcabe95fc08a233e9f91569829bed031f" }, "neoconf": { "branch": "main", "commit": "64437787dba70fce50dad7bfbb97d184c5bc340f" }, @@ -46,7 +48,6 @@ "nui": { "branch": "main", "commit": "c9b4de623d19a85b353ff70d2ae9c77143abe69c" }, "nui.nvim": { "branch": "main", "commit": "c9b4de623d19a85b353ff70d2ae9c77143abe69c" }, "null-ls": { "branch": "main", "commit": "0010ea927ab7c09ef0ce9bf28c2b573fc302f5a7" }, - "nvim-autopairs": { "branch": "master", "commit": "0f04d78619cce9a5af4f355968040f7d675854a1" }, "nvim-lspconfig": { "branch": "master", "commit": "511609ae0311abfcfaed3c398429a147e895ce2c" }, "nvim-tree": { "branch": "master", "commit": "7d1760f892951dd6a118dae1d7a1d8df5f029edf" }, "nvim-treesitter-textobjects": { "branch": "master", "commit": "ec1c5bdb3d87ac971749fa6c7dbc2b14884f1f6a" }, diff --git a/home/features/neovim/config/lua/my/neovide.lua b/home/features/neovim/config/lua/my/neovide.lua deleted file mode 100644 index 50a62a4..0000000 --- a/home/features/neovim/config/lua/my/neovide.lua +++ /dev/null @@ -1,14 +0,0 @@ -local M = {} - -function M.setup() - local default_length = 0.04 - -- vim.g.neovide_floating_blur_amount_x = 10.0 - -- vim.g.neovide_floating_blur_amount_y = 10.0 - vim.g.neovide_transparency = require("nix.theme").opacity.applications - -- vim.g.transparency = 0.6 - -- vim.g.pumblend = 0 - vim.g.neovide_cursor_animation_length = default_length - vim.g.neovide_cursor_animate_in_insert_mode = false -end - -return M diff --git a/home/features/neovim/config/lua/my/plugins/init.lua b/home/features/neovim/config/lua/my/plugins/init.lua deleted file mode 100644 index c06ccad..0000000 --- a/home/features/neovim/config/lua/my/plugins/init.lua +++ /dev/null @@ -1,36 +0,0 @@ -local runtime = require("my.tempest") - -if runtime.whitelist("neovide") then - require("my.neovide").setup() -end - -return { - { - -- Better ui for inputs/selects - "stevearc/dressing.nvim", - config = true, - -- https://github.com/folke/dot/blob/master/config/nvim/lua/config/plugins/init.lua - init = function() - ---@diagnostic disable-next-line: duplicate-set-field - vim.ui.select = function(...) - require("lazy").load({ plugins = { "dressing.nvim" } }) - return vim.ui.select(...) - end - ---@diagnostic disable-next-line: duplicate-set-field - vim.ui.input = function(...) - require("lazy").load({ plugins = { "dressing.nvim" } }) - return vim.ui.input(...) - end - end, - cond = runtime.blacklist("vscode"), - enabled = false, - }, - - { - "windwp/nvim-autopairs", - event = "InsertEnter", - config = function() - require("nvim-autopairs").setup() - end, - }, -} diff --git a/home/features/neovim/config/lua/my/plugins/lspconfig.lua b/home/features/neovim/config/lua/my/plugins/lspconfig.lua index 885b94e..fff0125 100644 --- a/home/features/neovim/config/lua/my/plugins/lspconfig.lua +++ b/home/features/neovim/config/lua/my/plugins/lspconfig.lua @@ -4,7 +4,7 @@ local lspconfig = { "neovim/nvim-lspconfig", event = "BufReadPre", dependencies = { - "folke/neoconf.nvim", + "neoconf", { "folke/neodev.nvim", config = true, @@ -26,59 +26,19 @@ local M = { }, } -function M.on_attach(client, bufnr) +function M.on_attach(_, _) end +function M.legacy_on_attach(_, bufnr) -- {{{ Keymap helpers local opts = function(desc) return { silent = true, desc = desc, buffer = bufnr } end - - local nmap = function(from, to, desc) - vim.keymap.set("n", from, to, opts(desc)) - end - -- }}} - -- {{{ Go to declaration / references / implementation - nmap("gd", vim.lsp.buf.definition, "[G]o to [d]efinition") - nmap("gi", vim.lsp.buf.implementation, "[G]o to [i]mplementation") - nmap("gr", vim.lsp.buf.references, "[G]o to [r]eferences") - -- }}} - -- {{{ Hover - -- Note: diagnostics are already covered in keymaps.lua - if client.supports_method("textDocument/hover") then - nmap("K", vim.lsp.buf.hover, "Hover") - end - nmap("L", vim.lsp.buf.signature_help, "Signature help") -- }}} -- {{{ Code actions - nmap("c", vim.lsp.buf.code_action, "[C]ode actions") - nmap("li", "LspInfo", "[L]sp [i]nfo") - local expropts = opts("[R]e[n]ame") expropts.expr = true vim.keymap.set("n", "rn", function() return ":IncRename " .. vim.fn.expand("") end, expropts) - - vim.keymap.set( - "v", - "c", - ":'<,'> lua vim.lsp.buf.range_code_action()", - opts("[C]ode actions") - ) - -- }}} - -- {{{ Workspace stuff - nmap( - "wa", - vim.lsp.buf.add_workspace_folder, - "[W]orkspace [A]dd Folder" - ) - nmap( - "wr", - vim.lsp.buf.remove_workspace_folder, - "[W]orkspace [R]emove Folder" - ) - nmap("wl", function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end, "[W]orkspace [L]ist Folders") -- }}} end @@ -156,7 +116,7 @@ local servers = { -- }}} -- {{{ Nix rnix = {}, - nil_ls = {}, + -- nil_ls = {}, nixd = {}, -- }}} ---@diagnostic disable-next-line: missing-fields @@ -185,21 +145,9 @@ M.capabilities = function() return c end -- }}} --- {{{ Nice diagnostic icons --- See https://github.com/folke/dot/blob/master/config/nvim/lua/config/plugins/lsp/diagnostics.lua -local function diagnostics_icons() - local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " } - - for type, icon in pairs(signs) do - local hl = "DiagnosticSign" .. type - vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" }) - end -end - ---}}} -- {{{ Main config function function lspconfig.config() - diagnostics_icons() + -- diagnostics_icons() -- -- {{{ Change on-hover borders vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "single" }) @@ -210,23 +158,22 @@ function lspconfig.config() local capabilities = M.capabilities() -- Setup basic language servers for lsp, details in pairs(servers) do - if details.on_attach == nil then - -- Default setting for on_attach - details.on_attach = M.on_attach - end - require("lspconfig")[lsp].setup({ on_attach = details.on_attach, settings = details.settings, -- Specific per-language settings - flags = { - debounce_text_changes = 150, -- This will be the default in neovim 0.7+ - }, cmd = details.cmd, capabilities = capabilities, }) end -end + vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("UserLspConfig", {}), + callback = function(ev) + local client = vim.lsp.get_client_by_id(ev.data.client_id) + M.legacy_on_attach(client, ev.buf) + end, + }) +end --}}} return M diff --git a/home/features/neovim/config/lua/my/plugins/venn.lua b/home/features/neovim/config/lua/my/plugins/venn.lua index 0ca1a4a..d426e27 100644 --- a/home/features/neovim/config/lua/my/plugins/venn.lua +++ b/home/features/neovim/config/lua/my/plugins/venn.lua @@ -49,32 +49,31 @@ function M.config() on_enter = function() vim.opt.virtualedit = "all" vim.g.inside_venn = true - vim.opt.cmdheight = 1 end, on_exit = function() vim.opt.virtualedit = "" - vim.g.inside_venn = false - vim.opt.cmdheight = 0 end, desc = "[V]enn mode", }, mode = "n", body = "V", heads = { - { "H", "h:VBox", { silent = true, desc = "test description" } }, - { "J", "j:VBox", { silent = true, desc = "test description" } }, - { "K", "k:VBox", { silent = true, desc = "test description" } }, - { "L", "l:VBox", { silent = true, desc = "test description" } }, + { "H", "hsilent VBox", { silent = true } }, + { "J", "jsilent VBox", { silent = true } }, + { "K", "ksilent VBox", { silent = true } }, + { "L", "lsilent VBox", { silent = true } }, { "f", "VBox", { mode = "v" } }, { "", nil, { exit = true } }, }, }) + + -- vim.keymap.set("n", "w", "h:VBox", { silent = true }) end function M.init() - require("which-key").register({ - ["V"] = { name = "[V]enn mode" }, - }) + -- require("which-key").register({ + -- ["V"] = { name = "[V]enn mode" }, + -- }) end return M diff --git a/home/features/neovim/config/lua/my/tempest.lua b/home/features/neovim/config/lua/my/tempest.lua index 9f4bb87..5b64789 100644 --- a/home/features/neovim/config/lua/my/tempest.lua +++ b/home/features/neovim/config/lua/my/tempest.lua @@ -100,7 +100,7 @@ function M.create_autocmd(opts) vim.api.nvim_create_autocmd(opts.event, { group = vim.api.nvim_create_augroup(opts.group, {}), - pattern = opts.pattern, + pattern = H.with_default("*", opts.pattern), callback = callback, }) end @@ -118,6 +118,7 @@ local function recursive_assign(source, destination) end function M.configure(opts, context) + -- {{{ Construct opts & context if type(opts) == "function" then opts = opts(context) end @@ -130,11 +131,20 @@ function M.configure(opts, context) if type(opts.mkContext) == "function" then context = opts.mkContext(context) end + -- }}} + + if + opts.cond == false + or type(opts.cond) == "function" and opts.cond(context) == false + then + return + end if type(opts.vim) == "table" then recursive_assign(opts.vim, vim) end + -- {{{ Keybinds if type(opts.keys) == "function" then opts.keys = opts.keys(context) end @@ -151,7 +161,8 @@ function M.configure(opts, context) M.set_keymap(keymap, context) end end - + -- }}} + -- {{{ Autocmds if type(opts.autocmds) == "function" then opts.autocmds = opts.autocmds(context) end @@ -160,7 +171,7 @@ function M.configure(opts, context) local autocmds = opts.autocmds -- Detect single autocmd passed instead of array - if autocmds.pattern ~= nil then + if autocmds.event ~= nil then autocmds = { autocmds } end @@ -168,7 +179,8 @@ function M.configure(opts, context) M.create_autocmd(autocmd) end end - + -- }}} + -- {{{ .setup calls if type(opts.setup) == "table" then for key, arg in pairs(opts.setup) do require(key).setup(arg) @@ -187,10 +199,16 @@ function M.configure(opts, context) module.setup(context.opts) end end - + -- }}} + -- {{{ Callbacks if type(opts.callback) == "function" then opts.callback(context) end + + if type(opts.callback) == "table" then + M.configure(opts.callback, context) + end + -- }}} end function M.configureMany(specs, context) diff --git a/home/features/neovim/default.nix b/home/features/neovim/default.nix index b9b2ecf..0621b2a 100644 --- a/home/features/neovim/default.nix +++ b/home/features/neovim/default.nix @@ -6,1261 +6,1336 @@ let inherit lib korora; } { - languageServerModule = "my.plugins.lspconfig"; tempestModule = "my.tempest"; }; - generated = nlib.generateConfig (lib.fix (self: { - # {{{ Pre-plugin config - pre = { - # {{{ General options - "0:general-options".vim = { - g = { - # Disable filetype.vim - do_filetype_lua = true; - did_load_filetypes = false; + generated = nlib.generateConfig + (lib.fix (self: with nlib; { + # {{{ Pre-plugin config + pre = { + # {{{ General options + "0:general-options".vim = { + g = { + # Disable filetype.vim + do_filetype_lua = true; + did_load_filetypes = false; - # Set leader - mapleader = " "; - }; + # Set leader + mapleader = " "; + }; - opt = { - # Basic options - joinspaces = false; # No double spaces with join (mapped to qj in my config) - list = true; # Show some invisible characters - cmdheight = 0; # Hide command line when it's not getting used + opt = { + # Basic options + joinspaces = false; # No double spaces with join (mapped to qj in my config) + list = true; # Show some invisible characters + cmdheight = 0; # Hide command line when it's not getting used - # tcqj are there by default, and "r" automatically continues comments on enter - formatoptions = "tcqjr"; + # tcqj are there by default, and "r" automatically continues comments on enter + formatoptions = "tcqjr"; - scrolloff = 4; # Starts scrolling 4 lines from the edge of the screen - termguicolors = true; # True color support + scrolloff = 4; # Starts scrolling 4 lines from the edge of the screen + termguicolors = true; # True color support - wrap = false; # Disable line wrap (by default) - wildmode = [ "list" "longest" ]; # Command-line completion mode - completeopt = [ "menu" "menuone" "noselect" ]; + wrap = false; # Disable line wrap (by default) + wildmode = [ "list" "longest" ]; # Command-line completion mode + completeopt = [ "menu" "menuone" "noselect" ]; - undofile = true; # persist undos!! + undofile = true; # persist undos!! - # {{{ Line numbers - number = true; # Show line numbers - relativenumber = true; # Relative line numbers - # }}} - # {{{ Indents - expandtab = true; # Use spaces for the tab char - shiftwidth = 2; # Size of an indent - tabstop = 2; # Size of tab character - shiftround = true; # When using < or >, rounds to closest multiple of shiftwidth - smartindent = true; # Insert indents automatically - # }}} - # {{{ Casing - ignorecase = true; # Ignore case - smartcase = true; # Do not ignore case with capitals - # }}} - # {{{ Splits - splitbelow = true; # Put new windows below current - splitright = true; # Put new windows right of current - # }}} - # {{{ Folding - foldmethod = "marker"; # use {{{ }}} for folding - foldcolumn = "1"; # show column with folds on the left - # }}} - }; - - # Disable pseudo-transparency; - autocmds = { - event = "FileType"; - group = " WinblendSettings"; - action.vim.opt.winblend = 0; - }; - }; - # }}} - # {{{ Misc keybinds - "1:misc-keybinds" = { - # {{{ Global keybinds - keys = - let - # {{{ Keybind helpers - nmap = mapping: action: desc: - { inherit mapping action desc; }; - unmap = mapping: - { inherit mapping; action = ""; }; - dmap = mapping: action: desc: { - inherit mapping desc; - action = nlib.lua "vim.diagnostic.${action}"; - }; + # {{{ Line numbers + number = true; # Show line numbers + relativenumber = true; # Relative line numbers # }}} - in - [ - # {{{ Free up q and Q - (nmap "" "q" "Record macro") - (nmap "" "Q" "Repeat last recorded macro") - (unmap "q") - (unmap "Q") + # {{{ Indents + expandtab = true; # Use spaces for the tab char + shiftwidth = 2; # Size of an indent + tabstop = 2; # Size of tab character + shiftround = true; # When using < or >, rounds to closest multiple of shiftwidth + smartindent = true; # Insert indents automatically # }}} - # {{{ Chords - # Different chords get remapped to f-keys by my slambda config. - # See [my slambda config](../../../hosts/nixos/common/optional/services/slambda.nix) for details. - # - # Exit insert mode using *jk* - { - mode = "iv"; - mapping = ""; - action = ""; - desc = "Exit insert mode"; - } - # Use global clipboard using *cp* - { - mode = "nv"; - mapping = ""; - action = ''"+''; - desc = "Use global clipboard"; - } - # Save using *ji* - (nmap "" "silent write" "Save current file") + # {{{ Casing + ignorecase = true; # Ignore case + smartcase = true; # Do not ignore case with capitals # }}} - # {{{ Newline without comments - { - mode = "i"; - mapping = ""; - action = nlib.thunk /* lua */ '' - vim.paste({ "", "" }, -1) - ''; - desc = "Insert newline without continuing the current comment"; - } - { - mode = "i"; - mapping = ""; - # This is a bit scuffed and might not work for all languages - action = "norm O"; - desc = "Insert newline above without continuing the current comment"; - } + # {{{ Splits + splitbelow = true; # Put new windows below current + splitright = true; # Put new windows right of current # }}} - # {{{ Diagnostics - (dmap "[d" "goto_prev" "Goto previous [d]iagnostic") - (dmap "]d" "goto_next" "Goto next [d]iagnostic") - (dmap "J" "open_float" "Open current diagnostic") - (dmap "D" "setloclist" "[D]iagnostic loclist") - { - mapping = "qj"; - action = "J"; - desc = "join lines"; - } + # {{{ Folding + foldmethod = "marker"; # use {{{ }}} for folding + foldcolumn = "1"; # show column with folds on the left # }}} - # {{{ Other misc keybinds - (nmap "a" "" "[A]lternate file") - (unmap "") - (nmap "Q" ":wqa" "Save all files and [q]uit") - (nmap "rw" ":%s//" "[R]eplace [w]ord in file") - (nmap "sw" - (nlib.lua ''require("my.helpers.wrapMovement").toggle'') - "toggle word [w]rap") - # }}} - ]; - # }}} - # {{{ Exit certain buffers with qq - autocmds = { - event = "FileType"; - pattern = [ "help" ]; - group = "BasicBufferQuitting"; - action.keys = { - mapping = "qq"; - action = "close"; - desc = "[q]uit current buffer"; + }; + + # Disable pseudo-transparency; + autocmds = { + event = "FileType"; + group = "WinblendSettings"; + action.vim.opt.winblend = 0; }; }; # }}} + # {{{ Misc keybinds + "1:misc-keybinds" = { + # {{{ Global keybinds + keys = + # {{{ Keybind helpers + let dmap = mapping: action: desc: { + inherit mapping desc; + action = lua "vim.diagnostic.${action}"; + }; + in + # }}} + [ + # {{{ Free up q and Q + (nmap "" "q" "Record macro") + (nmap "" "Q" "Repeat last recorded macro") + (unmap "q") + (unmap "Q") + # }}} + # {{{ Chords + # Different chords get remapped to f-keys by my slambda config. + # See [my slambda config](../../../hosts/nixos/common/optional/services/slambda.nix) for details. + # + # Exit insert mode using *jk* + (keymap "iv" "" "" "Exit insert mode") + + # Use global clipboard using *cp* + (keymap "nv" "" ''"+'' "Use global clipboard") + # Save using *ji* + (nmap "" "silent write" "Save current file") + # }}} + # {{{ Newline without comments + { + mode = "i"; + mapping = ""; + action = thunk /* lua */ '' + vim.paste({ "", "" }, -1) + ''; + desc = "Insert newline without continuing the current comment"; + } + { + mode = "i"; + mapping = ""; + # This is a bit scuffed and might not work for all languages + action = "norm O"; + desc = "Insert newline above without continuing the current comment"; + } + # }}} + # {{{ Diagnostics + (dmap "[d" "goto_prev" "Goto previous [d]iagnostic") + (dmap "]d" "goto_next" "Goto next [d]iagnostic") + (dmap "J" "open_float" "Open current diagnostic") + (dmap "D" "setloclist" "[D]iagnostic loclist") + (nmap "qj" "J" "join lines") + # }}} + # {{{ Other misc keybinds + (nmap "a" "" "[A]lternate file") + (unmap "") + (nmap "Q" ":wqa" "Save all files and [q]uit") + (nmap "rw" ":%s//" "[R]eplace [w]ord in file") + (nmap "sw" + (lua ''require("my.helpers.wrapMovement").toggle'') + "toggle word [w]rap") + # }}} + ]; + # }}} + # {{{ Autocmds + autocmds = [ + # {{{ Exit certain buffers with qq + { + event = "FileType"; + pattern = [ "help" ]; + group = "BasicBufferQuitting"; + action.keys = + nmap "qq" "close" "[q]uit current buffer"; + } + # }}} + # {{{ Enable wrap movemenets by default in certain filetypes + { + event = "FileType"; + pattern = [ "markdown" "typst" "tex" ]; + group = "EnableWrapMovement"; + action = lua ''require("my.helpers.wrapMovement").enable''; + } + # }}} + ]; + # }}} + }; + # }}} + # {{{ Manage cmdheight + "2:manage-cmdheight".autocmds = [ + { + event = "CmdlineEnter"; + group = "SetCmdheightCmdlineEnter"; + action.vim.opt.cmdheight = 1; + } + { + event = "CmdlineLeave"; + group = "SetCmdheightCmdlineLeave"; + action.vim.opt.cmdheight = 0; + } + ]; + # }}} + # {{{ Lsp on-attach + "3:lsp-on-attach".autocmds = { + event = "LspAttach"; + group = "UserLspConfig"; + action = + let nmap = mapping: action: desc: + nlib.nmap mapping + (lua "vim.lsp.buf.${action}") + desc; + in + { + mkContext = event: { + bufnr = lua "${event}.buf"; + client = lua /* lua */ + "vim.lsp.get_client_by_id(${event}.data.client_id)"; + }; + keys = [ + (nlib.nmap "li" "LspInfo" "[L]sp [i]nfo") + (nmap "gd" "definition" "[G]o to [d]efinition") + (nmap "gi" "implementation" "[G]o to [i]mplementation") + (nmap "gr" "references" "[G]o to [r]eferences") + (nmap "L" "signature_help" "Signature help") + (nmap "c" "code_action" "[C]ode actions") + (keymap "v" "c" ":'<,'> lua vim.lsp.buf.range_code_action()" "[C]ode actions") + (nmap "wa" "add_workspace_folder" "[W]orkspace [A]dd Folder") + (nmap "wr" "remove_workspace_folder" "[W]orkspace [R]emove Folder") + (nlib.nmap "wl" + (thunk /* lua */ '' + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + '') "[W]orkspace [L]ist Folders") + ]; + callback = { + cond = ctx: lua '' + return ${ctx}.client.supports_method("textDocument/hover") + ''; + keys = nmap "K" "hover" "Hover"; + }; + }; + }; + # }}} + # {{{ Neovide config + "4:configure-neovide" = { + cond = whitelist "neovide"; + vim.g = { + neovide_transparency = lua ''require("my.helpers.theme").theme.opacity.applications''; + neovide_cursor_animation_length = 0.04; + neovide_cursor_animate_in_insert_mode = false; + }; + }; + # }}} + # {{{ Language specific settings + "5:language-specific-settings".autocmds = [{ + event = "FileType"; + group = "UserNixSettings"; + pattern = "*.nix"; + action = { + vim.opt.commentstring = "# %s"; + keys = { + mapping = "lg"; + action = thunk /* lua */ '' + D.tempest.withSavedCursor(function() + vim.cmd(":%!${lib.getExe pkgs.update-nix-fetchgit}") + end) + ''; + desc = "Update all fetchgit calls"; + }; + }; + }]; + # }}} }; # }}} - # {{{ Manage cmdheight - "2:manage-cmdheight".autocmds = [ - { - event = "CmdlineEnter"; - group = "SetCmdheightCmdlineEnter"; - action.vim.opt.cmdheight = 1; - } - { - event = "CmdlineLeave"; - group = "SetCmdheightCmdlineLeave"; - action.vim.opt.cmdheight = 0; - } - ]; - # }}} - }; - # }}} - # {{{ Plugins - lazy = { - # {{{ libraries - # {{{ plenary - plenary = { - package = "nvim-lua/plenary.nvim"; - # Autoload when running tests - cmd = [ "PlenaryBustedDirectory" "PlenaryBustedFile" ]; - }; - # }}} - # {{{ nui - nui.package = "MunifTanjim/nui.nvim"; - # }}} - # {{{ web-devicons - web-devicons.package = "nvim-tree/nvim-web-devicons"; - # }}} - # {{{ Scrap - scrap = { - package = "mateiadrielrafael/scrap.nvim"; + # {{{ Plugins + lazy = { + # {{{ libraries + # {{{ plenary + plenary = { + package = "nvim-lua/plenary.nvim"; + # Autoload when running tests + cmd = [ "PlenaryBustedDirectory" "PlenaryBustedFile" ]; + }; + # }}} + # {{{ nui + nui.package = "MunifTanjim/nui.nvim"; + # }}} + # {{{ web-devicons + web-devicons.package = "nvim-tree/nvim-web-devicons"; + # }}} + # {{{ Scrap + scrap = { + package = "mateiadrielrafael/scrap.nvim"; - event = "InsertEnter"; - config.setup."my.abbreviations" = true; - }; - # }}} - # }}} - # {{{ ui - # {{{ nvim-tree - nvim-tree = { - package = "kyazdani42/nvim-tree.lua"; + event = "InsertEnter"; + config.setup."my.abbreviations" = true; + }; + # }}} + # }}} + # {{{ ui + # {{{ nvim-tree + nvim-tree = { + package = "kyazdani42/nvim-tree.lua"; - cond = nlib.blacklist [ "vscode" "firenvim" ]; - config = true; + cond = blacklist [ "vscode" "firenvim" ]; + config = true; - keys.mapping = ""; - keys.desc = "Toggle [n]vim-tree"; - keys.action = "NvimTreeToggle"; - }; - # }}} - # {{{ mini.statusline - mini-statusline = { - package = "echasnovski/mini.statusline"; - name = "mini.statusline"; - dependencies.lua = [ self.lazy.web-devicons.package ]; + keys = nmap "" "Toggle [n]vim-tree" "NvimTreeToggle"; + }; + # }}} + # {{{ mini.statusline + mini-statusline = { + package = "echasnovski/mini.statusline"; + name = "mini.statusline"; + dependencies.lua = [ self.lazy.web-devicons.package ]; - cond = nlib.blacklist [ "vscode" "firenvim" ]; - lazy = false; + cond = blacklist [ "vscode" "firenvim" ]; + lazy = false; - opts.content.inactive = nlib.thunk /* lua */ '' - require("mini.statusline").combine_groups({ - { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } }, - }) - ''; + opts.content.inactive = thunk /* lua */ '' + require("mini.statusline").combine_groups({ + { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } }, + }) + ''; - opts.content.active = nlib.thunk /* lua */ '' - local st = require("mini.statusline"); - local mode, mode_hl = st.section_mode({ trunc_width = 120 }) - local git = st.section_git({ trunc_width = 75 }) - local diagnostics = st.section_diagnostics({ trunc_width = 75 }) + opts.content.active = thunk /* lua */ '' + local st = require("mini.statusline"); + local mode, mode_hl = st.section_mode({ trunc_width = 120 }) + local git = st.section_git({ trunc_width = 75 }) + local diagnostics = st.section_diagnostics({ trunc_width = 75 }) - return st.combine_groups({ - { hl = mode_hl, strings = { mode } }, - { hl = "MiniStatuslineDevinfo", strings = { git } }, - { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } }, - "%=", -- End left alignment - { hl = "MiniStatuslineFilename", strings = { diagnostics } }, - { hl = "MiniStatuslineDevinfo", strings = { vim.bo.filetype } }, - }) - ''; - }; - # }}} - # {{{ mini.files - mini-files = { - package = "echasnovski/mini.files"; - name = "mini.files"; - dependencies.lua = [ self.lazy.web-devicons.package ]; + return st.combine_groups({ + { hl = mode_hl, strings = { mode } }, + { hl = "MiniStatuslineDevinfo", strings = { git } }, + { hl = "MiniStatuslineFilename", strings = { vim.fn.expand("%:t") } }, + "%=", -- End left alignment + { hl = "MiniStatuslineFilename", strings = { diagnostics } }, + { hl = "MiniStatuslineDevinfo", strings = { vim.bo.filetype } }, + }) + ''; + }; + # }}} + # {{{ mini.files + mini-files = { + package = "echasnovski/mini.files"; + name = "mini.files"; + dependencies.lua = [ self.lazy.web-devicons.package ]; - cond = nlib.blacklist [ "vscode" "firenvim" ]; - keys = { - mapping = ""; - desc = "[S]earch [F]iles"; - action = nlib.thunk /* lua */ '' - local files = require("mini.files") - if not files.close() then - files.open(vim.api.nvim_buf_get_name(0)) - files.reveal_cwd() + cond = blacklist [ "vscode" "firenvim" ]; + keys = { + mapping = ""; + desc = "[S]earch [F]iles"; + action = thunk /* lua */ '' + local files = require("mini.files") + if not files.close() then + files.open(vim.api.nvim_buf_get_name(0)) + files.reveal_cwd() + end + ''; + }; + + opts.windows.preview = false; + opts.mappings.go_in_plus = "l"; + }; + # }}} + # {{{ winbar + winbar = { + package = "fgheng/winbar.nvim"; + + cond = blacklist [ "vscode" "firenvim" ]; + event = "BufReadPost"; + + opts.enabled = true; + # TODO: blacklist harpoon, NeogitStatus + }; + # }}} + # {{{ harpoon + harpoon = { + package = "ThePrimeagen/harpoon"; + keys = + let goto = key: index: { + desc = "Goto harpoon file ${toString index}"; + mapping = "${key}"; + action = thunk + /* lua */ ''require("harpoon.ui").nav_file(${toString index})''; + }; + in + [ + { + desc = "Add file to [h]arpoon"; + mapping = "H"; + action = thunk + /* lua */ ''require("harpoon.mark").add_file()''; + } + { + desc = "Toggle harpoon quickmenu"; + mapping = ""; + action = thunk + /* lua */ ''require("harpoon.ui").toggle_quick_menu()''; + } + (goto "q" 1) + (goto "w" 2) + (goto "e" 3) + (goto "r" 4) + (goto "a" 5) + (goto "s" 6) + (goto "d" 7) + (goto "f" 8) + (goto "z" 9) + ]; + }; + # }}} + # {{{ neogit + neogit = { + package = "TimUntersberger/neogit"; + dependencies.lua = [ self.lazy.plenary.package ]; + + cond = blacklist [ "vscode" "firenvim" ]; + cmd = "Neogit"; # We sometimes spawn this directly from fish using a keybind + keys = nmap "" "Neogit" "Open neo[g]it"; + + opts = true; # Here so the tempest runtime will call .setup + config.autocmds = { + event = "FileType"; + pattern = "NeogitStatus"; + group = "NeogitStatusDisableFolds"; + action.vim.opt.foldenable = false; + }; + }; + # }}} + # {{{ telescope + telescope = { + package = "nvim-telescope/telescope.nvim"; + version = "0.1.x"; + cond = blacklist "vscode"; + + # {{{ Dependencies + dependencies = { + nix = [ pkgs.ripgrep ]; + lua = [ + self.lazy.plenary.package + { + # We want a prebuilt version of this plugin + dir = pkgs.vimPlugins.telescope-fzf-native-nvim; + name = "telescope-fzf-native"; + } + ]; + }; + # }}} + # {{{ Keymaps + keys = + let + nmap = mapping: action: desc: { + inherit mapping desc; + action = "Telescope ${action} theme=ivy"; + }; + + findFilesByExtension = mapping: extension: tag: + nmap + "f${mapping}" + "find_files find_command=rg,--files,--glob=**/*.${extension}" + "Find ${tag} files"; + in + [ + (nmap "" "find_files" "File finder [p]alette") + (nmap "d" "diagnostics" "[D]iagnostics") + (nmap "" "live_grep" "[F]ind in project") + (nmap "t" "builtin" "[T]elescope pickers") + # {{{ Files by extension + (findFilesByExtension "tx" "tex" "[t]ex") + (findFilesByExtension "ts" "ts" "[t]ypescript") + (findFilesByExtension "ty" "typ" "[t]ypst") + (findFilesByExtension "l" "lua" "[l]ua") + (findFilesByExtension "n" "nix" "[n]ua") + (findFilesByExtension "p" "purs" "[p]urescript") + (findFilesByExtension "h" "hs" "[h]askell") + (findFilesByExtension "e" "elm" "[e]lm") + (findFilesByExtension "r" "rs" "[r]ust") + # }}} + ]; + # }}} + # {{{ Disable folds in telescope windows + config.autocmds = { + event = "FileType"; + pattern = "TelescopeResults"; + group = "TelescopeResultsDisableFolds"; + action.vim.opt.foldenable = false; + }; + # }}} + # {{{ Load fzf extension + config.callback = thunk /* lua */ '' + require("telescope").load_extension("fzf") + ''; + # }}} + # {{{ Options + opts.defaults.mappings.i."" = "which_key"; + opts.pickers.find_files.hidden = true; + opts.extensions.fzf = { + fuzzy = true; + override_generic_sorter = true; + override_file_sorter = true; + }; + # }}} + }; + # }}} + # {{{ dressing + dressing = { + package = "stevearc/dressing.nvim"; + + cond = blacklist "vscode"; + event = "BufReadPre"; + + config = true; + init = thunk /* lua */ '' + vim.ui.select = function(...) + require("lazy").load({ plugins = { "dressing.nvim" } }) + return vim.ui.select(...) + end + vim.ui.input = function(...) + require("lazy").load({ plugins = { "dressing.nvim" } }) + return vim.ui.input(...) end ''; }; + # }}} + # }}} + # {{{ visual + # The line between `ui` and `visual` is a bit rought. I currenlty mostly judge + # it by vibe. + # {{{ indent-blankline + indent-blankline = { + package = "lukas-reineke/indent-blankline.nvim"; + main = "ibl"; + config = true; - opts.windows.preview = false; - opts.mappings.go_in_plus = "l"; - }; - # }}} - # {{{ winbar - winbar = { - package = "fgheng/winbar.nvim"; - - cond = nlib.blacklist [ "vscode" "firenvim" ]; - event = "BufReadPost"; - - opts.enabled = true; - # TODO: blacklist harpoon, NeogitStatus - }; - # }}} - # {{{ harpoon - harpoon = { - package = "ThePrimeagen/harpoon"; - keys = - let goto = key: index: { - desc = "Goto harpoon file ${toString index}"; - mapping = "${key}"; - action = nlib.thunk - /* lua */ ''require("harpoon.ui").nav_file(${toString index})''; - }; - in - [ - { - desc = "Add file to [h]arpoon"; - mapping = "H"; - action = nlib.thunk - /* lua */ ''require("harpoon.mark").add_file()''; - } - { - desc = "Toggle harpoon quickmenu"; - mapping = ""; - action = nlib.thunk - /* lua */ ''require("harpoon.ui").toggle_quick_menu()''; - } - (goto "q" 1) - (goto "w" 2) - (goto "e" 3) - (goto "r" 4) - (goto "a" 5) - (goto "s" 6) - (goto "d" 7) - (goto "f" 8) - (goto "z" 9) - ]; - }; - # }}} - # {{{ neogit - neogit = { - package = "TimUntersberger/neogit"; - dependencies.lua = [ self.lazy.plenary.package ]; - - cond = nlib.blacklist [ "vscode" "firenvim" ]; - cmd = "Neogit"; # We sometimes spawn this directly from fish using a keybind - keys = { - mapping = ""; - action = "Neogit"; - desc = "Open neo[g]it"; - }; - - opts = true; # Here so the tempest runtime will call .setup - config.autocmds = { - event = "FileType"; - pattern = "NeogitStatus"; - group = "NeogitStatusDisableFolds"; - action.vim.opt.foldenable = false; - }; - }; - # }}} - # {{{ telescope - telescope = { - package = "nvim-telescope/telescope.nvim"; - version = "0.1.x"; - cond = nlib.blacklist "vscode"; - - # {{{ Dependencies - dependencies = { - nix = [ pkgs.ripgrep ]; - lua = [ - self.lazy.plenary.package - { - # We want a prebuilt version of this plugin - dir = pkgs.vimPlugins.telescope-fzf-native-nvim; - name = "telescope-fzf-native"; - } - ]; + cond = blacklist "vscode"; + event = "BufReadPost"; }; # }}} - # {{{ Keymaps - keys = - let - keymap = mapping: action: desc: { - inherit mapping desc; - action = "Telescope ${action} theme=ivy"; - }; + # {{{ live-command + # Live command preview for commands like :norm + live-command = { + package = "smjonas/live-command.nvim"; + version = "remote"; # https://github.com/smjonas/live-command.nvim/pull/29 + main = "live-command"; - findFilesByExtension = mapping: extension: tag: - keymap - "f${mapping}" - "find_files find_command=rg,--files,--glob=**/*.${extension}" - "Find ${tag} files"; - in - [ - (keymap "" "find_files" "File finder [p]alette") - (keymap "d" "diagnostics" "[D]iagnostics") - (keymap "" "live_grep" "[F]ind in project") - (keymap "t" "builtin" "[T]elescope pickers") - # {{{ Files by extension - (findFilesByExtension "tx" "tex" "[t]ex") - (findFilesByExtension "ts" "ts" "[t]ypescript") - (findFilesByExtension "ty" "typ" "[t]ypst") - (findFilesByExtension "l" "lua" "[l]ua") - (findFilesByExtension "n" "nix" "[n]ua") - (findFilesByExtension "p" "purs" "[p]urescript") - (findFilesByExtension "h" "hs" "[h]askell") - (findFilesByExtension "e" "elm" "[e]lm") - (findFilesByExtension "r" "rs" "[r]ust") - # }}} - ]; - # }}} - # {{{ Disable folds in telescope windows - config.autocmds = { - event = "FileType"; - pattern = "TelescopeResults"; - group = "TelescopeResultsDisableFolds"; - action.vim.opt.foldenable = false; + event = "CmdlineEnter"; + opts.commands.Norm.cmd = "norm"; + opts.commands.G.cmd = "g"; + + keys = keymap "v" "N" ":Norm " "Map lines in [n]ormal mode"; }; # }}} - # {{{ Load fzf extension - config.callback = nlib.thunk /* lua */ '' - require("telescope").load_extension("fzf") - ''; - # }}} - # {{{ Options - opts.defaults.mappings.i."" = "which_key"; - opts.pickers.find_files.hidden = true; - opts.extensions.fzf = { - fuzzy = true; - override_generic_sorter = true; - override_file_sorter = true; + # {{{ fidget + fidget = { + package = "j-hui/fidget.nvim"; + tag = "legacy"; + + cond = blacklist "vscode"; + event = "BufReadPre"; + config = true; }; # }}} - }; - # }}} - # }}} - # {{{ visual - # The line between `ui` and `visual` is a bit rought. I currenlty mostly judge - # it by vibe. - # {{{ indent-blankline - indent-blankline = { - package = "lukas-reineke/indent-blankline.nvim"; - main = "ibl"; - config = true; + # {{{ treesitter + treesitter = { + # REASON: more grammars + dir = upkgs.vimPlugins.nvim-treesitter.withAllGrammars; + dependencies.lua = [ "nvim-treesitter/nvim-treesitter-textobjects" ]; + dependencies.nix = [ pkgs.tree-sitter ]; - cond = nlib.blacklist "vscode"; - event = "BufReadPost"; - }; - # }}} - # {{{ live-command - # Live command preview for commands like :norm - live-command = { - package = "smjonas/live-command.nvim"; - version = "remote"; # https://github.com/smjonas/live-command.nvim/pull/29 - main = "live-command"; + cond = blacklist "vscode"; + event = "BufReadPost"; - event = "CmdlineEnter"; - opts.commands.Norm.cmd = "norm"; - opts.commands.G.cmd = "g"; - - keys = { - mode = "v"; - mapping = "N"; - action = ":Norm "; - desc = "Map lines in [n]ormal mode"; - }; - }; - # }}} - # {{{ fidget - fidget = { - package = "j-hui/fidget.nvim"; - tag = "legacy"; - - cond = nlib.blacklist "vscode"; - event = "BufReadPre"; - config = true; - }; - # }}} - # {{{ treesitter - treesitter = { - # REASON: more grammars - dir = upkgs.vimPlugins.nvim-treesitter.withAllGrammars; - dependencies.lua = [ "nvim-treesitter/nvim-treesitter-textobjects" ]; - dependencies.nix = [ pkgs.tree-sitter ]; - - cond = nlib.blacklist "vscode"; - event = "BufReadPost"; - - #{{{ Highlighting - opts.highlight = { - enable = true; - disable = [ "kotlin" ]; # This one seemed a bit broken - additional_vim_regex_highlighting = false; - }; - #}}} - # {{{ Textobjects - opts.textobjects = { - #{{{ Select - select = { + #{{{ Highlighting + opts.highlight = { enable = true; - lookahead = true; - keymaps = { - # You can use the capture groups defined in textobjects.scm - af = "@function.outer"; - "if" = "@function.inner"; - ac = "@class.outer"; - ic = "@class.inner"; - }; + disable = [ "kotlin" ]; # This one seemed a bit broken + additional_vim_regex_highlighting = false; }; #}}} - #{{{ Move - move = { - enable = true; - set_jumps = true; # whether to set jumps in the jumplist - goto_next_start = { - "]f" = "@function.outer"; - "]t" = "@class.outer"; + # {{{ Textobjects + opts.textobjects = { + #{{{ Select + select = { + enable = true; + lookahead = true; + keymaps = { + # You can use the capture groups defined in textobjects.scm + af = "@function.outer"; + "if" = "@function.inner"; + ac = "@class.outer"; + ic = "@class.inner"; + }; }; - goto_next_end = { - "]F" = "@function.outer"; - "]T" = "@class.outer"; - }; - goto_previous_start = { - "[f" = "@function.outer"; - "[t" = "@class.outer"; - }; - goto_previous_end = { - "[F" = "@function.outer"; - "[T" = "@class.outer"; + #}}} + #{{{ Move + move = { + enable = true; + set_jumps = true; # whether to set jumps in the jumplist + goto_next_start = { + "]f" = "@function.outer"; + "]t" = "@class.outer"; + }; + goto_next_end = { + "]F" = "@function.outer"; + "]T" = "@class.outer"; + }; + goto_previous_start = { + "[f" = "@function.outer"; + "[t" = "@class.outer"; + }; + goto_previous_end = { + "[F" = "@function.outer"; + "[T" = "@class.outer"; + }; }; + #}}} }; - #}}} + # }}} + opts.indent.enable = true; }; # }}} - opts.indent.enable = true; - }; - # }}} - # {{{ treesitter context - # Show context at the of closing delimiters - treesitter-virtual-context = { - package = "haringsrob/nvim_context_vt"; - dependencies.lua = [ "treesitter" ]; + # {{{ treesitter context + # Show context at the of closing delimiters + treesitter-virtual-context = { + package = "haringsrob/nvim_context_vt"; + dependencies.lua = [ "treesitter" ]; - cond = nlib.blacklist "vscode"; - event = "BufReadPost"; - }; - - # show context at top of file - treesitter-top-context = { - package = "nvim-treesitter/nvim-treesitter-context"; - dependencies.lua = [ "treesitter" ]; - - cond = nlib.blacklist "vscode"; - event = "BufReadPost"; - opts.enable = true; - }; - # }}} - # }}} - # {{{ editing {{{ text navigation - # {{{ flash - flash = { - package = "folke/flash.nvim"; - - cond = nlib.blacklist "vscode"; - keys = - let keybind = mode: mapping: action: desc: { - inherit mapping desc mode; - action = nlib.thunk /* lua */ ''require("flash").${action}()''; - }; - in - [ - (keybind "nxo" "s" "jump" "Flash") - (keybind "nxo" "S" "treesitter" "Flash Treesitter") - (keybind "o" "r" "remote" "Remote Flash") - (keybind "ox" "R" "treesitter_search" "Treesitter Search") - (keybind "c" "" "toggle" "Toggle Flash Search") - ]; - - # Disable stuff like f/t/F/T - opts.modes.char.enabled = false; - }; - # }}} - # {{{ ftft (quickscope but written in lua) - ftft = { - package = "gukz/ftFT.nvim"; - - cond = nlib.blacklist "vscode"; - keys = [ "f" "F" "t" "T" ]; - config = true; - }; - # }}} - # }}} - # {{{ clipboard-image - clipboard-image = { - package = "postfen/clipboard-image.nvim"; - - cond = nlib.blacklist "firenvim"; - cmd = "PasteImg"; - - keys = { - mapping = "p"; - action = "PasteImg"; - desc = "[P]aste image from clipboard"; + cond = blacklist "vscode"; + event = "BufReadPost"; }; - opts.default.img_name = nlib.import ./plugins/clipboard-image.lua "img_name"; - opts.tex = { - img_dir = [ "%:p:h" "img" ]; - affix = "\\includegraphics[width=\\textwidth]{%s}"; - }; - opts.typst = { - img_dir = [ "%:p:h" "img" ]; - affix = ''#image("%s", width: 100)''; - }; - }; - # }}} - # {{{ lastplace - lastplace = { - package = "ethanholz/nvim-lastplace"; + # show context at top of file + treesitter-top-context = { + package = "nvim-treesitter/nvim-treesitter-context"; + dependencies.lua = [ "treesitter" ]; - cond = nlib.blacklist "vscode"; - event = "BufReadPre"; - - opts.lastplace_ignore_buftype = [ "quickfix" "nofile" "help" ]; - }; - # }}} - # {{{ undotree - undotree = { - package = "mbbill/undotree"; - - cond = nlib.blacklist "vscode"; - cmd = "UndotreeToggle"; - keys = { - mapping = "u"; - action = "UndoTreeToggle"; - desc = "[U]ndo tree"; - }; - }; - # }}} - # {{{ ssr (structured search & replace) - ssr = { - package = "cshuaimin/ssr.nvim"; - - cond = nlib.blacklist "vscode"; - keys = { - mode = "nx"; - mapping = "rt"; - action = nlib.thunk /* lua */ ''require("ssr").open()''; - desc = "[r]eplace [t]emplate"; - }; - - opts.keymaps.replace_all = ""; - }; - # }}} - # {{{ edit-code-block (edit injections in separate buffers) - edit-code-block = { - package = "dawsers/edit-code-block.nvim"; - dependencies.lua = [ "treesitter" ]; - main = "ecb"; - - cond = nlib.blacklist "vscode"; - config = true; - keys = { - mapping = "e"; - action = "EditCodeBlock"; - desc = "[e]dit injection"; - }; - }; - # }}} - # {{{ mini.comment - mini-comment = { - package = "echasnovski/mini.comment"; - name = "mini.comment"; - - config = true; - keys = [ - { mapping = "gc"; mode = "nxv"; } - "gcc" - ]; - }; - # }}} - # {{{ mini.surround - mini-surround = { - package = "echasnovski/mini.surround"; - name = "mini.surround"; - - keys = lib.flatten [ - # ^ doing the whole `flatten` thing to lie to my formatter - { mapping = "s"; mode = "nv"; } - [ "d" "f" "F" "h" "r" ] - ]; - - # {{{ Keymaps - opts.mappings = { - add = "s"; # Add surrounding in Normal and Visul modes - delete = "d"; # Delete surrounding - find = "f"; # Find surrounding (to the right) - find_left = "F"; # Find surrounding (to the left) - highlight = "h"; # Highlight surrounding - replace = "r"; # Replace surrounding - update_n_lines = ""; # Update `n_lines` + cond = blacklist "vscode"; + event = "BufReadPost"; + opts.enable = true; }; # }}} - # {{{ Custom surroundings - opts.custom_surroundings = - let mk = balanced: input: left: right: { - input = [ - input - (if balanced - then "^.%s*().-()%s*.$" - else "^.().*().$") + # }}} + # {{{ editing + # {{{ text navigation + # {{{ flash + flash = { + package = "folke/flash.nvim"; + + cond = blacklist "vscode"; + keys = + let nmap = mode: mapping: action: desc: { + inherit mapping desc mode; + action = thunk /* lua */ ''require("flash").${action}()''; + }; + in + [ + (nmap "nxo" "s" "jump" "Flash") + (nmap "nxo" "S" "treesitter" "Flash Treesitter") + (nmap "o" "r" "remote" "Remote Flash") + (nmap "ox" "R" "treesitter_search" "Treesitter Search") + (nmap "c" "" "toggle" "Toggle Flash Search") ]; - output = { inherit left right; }; - }; - in - { - b = mk true "%b()" "(" ")"; - B = mk true "%b{}" "{" "}"; - r = mk true "%b[]" "[" "]"; - q = mk false "\".-\"" "\"" "\""; - a = mk false "'.-'" "'" "'"; - }; + + # Disable stuff like f/t/F/T + opts.modes.char.enabled = false; + }; # }}} - }; - # }}} - # {{{ mini.operators - mini-operators = { - package = "echasnovski/mini.operators"; - name = "mini.operators"; + # {{{ ftft (quickscope but written in lua) + ftft = { + package = "gukz/ftFT.nvim"; - config = true; - keys = - let operator = key: [ - { mapping = "g${key}"; mode = "nv"; } - "g${key}${key}" - ]; - in - lib.flatten [ - (operator "=") - (operator "x") - (operator "r") - (operator "s") - ]; - }; - # }}} - # {{{ luasnip - # snippeting engine - luasnip = - let reload = /* lua */ ''require("luasnip.loaders.from_vscode").lazy_load()''; - in - { - package = "L3MON4D3/LuaSnip"; - version = "v2"; + cond = blacklist "vscode"; + keys = [ "f" "F" "t" "T" ]; + config = true; + }; + # }}} + # }}} + # {{{ clipboard-image + clipboard-image = { + package = "postfen/clipboard-image.nvim"; - cond = nlib.blacklist "vscode"; - config = nlib.thunk reload; + cond = blacklist "firenvim"; + cmd = "PasteImg"; - # {{{ Keybinds + keys = { + mapping = "p"; + action = "PasteImg"; + desc = "[P]aste image from clipboard"; + }; + + opts.default.img_name = importFrom ./plugins/clipboard-image.lua "img_name"; + opts.tex = { + img_dir = [ "%:p:h" "img" ]; + affix = "\\includegraphics[width=\\textwidth]{%s}"; + }; + opts.typst = { + img_dir = [ "%:p:h" "img" ]; + affix = ''#image("%s", width: 100)''; + }; + }; + # }}} + # {{{ lastplace + lastplace = { + package = "ethanholz/nvim-lastplace"; + + cond = blacklist "vscode"; + event = "BufReadPre"; + + opts.lastplace_ignore_buftype = [ "quickfix" "nofile" "help" ]; + }; + # }}} + # {{{ undotree + undotree = { + package = "mbbill/undotree"; + + cond = blacklist "vscode"; + cmd = "UndotreeToggle"; + keys = nmap + "u" + "UndoTreeToggle" + "[U]ndo tree"; + }; + # }}} + # {{{ ssr (structured search & replace) + ssr = { + package = "cshuaimin/ssr.nvim"; + + cond = blacklist "vscode"; + keys = { + mode = "nx"; + mapping = "rt"; + action = thunk /* lua */ ''require("ssr").open()''; + desc = "[r]eplace [t]emplate"; + }; + + opts.keymaps.replace_all = ""; + }; + # }}} + # {{{ edit-code-block (edit injections in separate buffers) + edit-code-block = { + package = "dawsers/edit-code-block.nvim"; + dependencies.lua = [ "treesitter" ]; + main = "ecb"; + + cond = blacklist "vscode"; + config = true; + keys = { + mapping = "e"; + action = "EditCodeBlock"; + desc = "[e]dit injection"; + }; + }; + # }}} + # {{{ mini.comment + mini-comment = { + package = "echasnovski/mini.comment"; + name = "mini.comment"; + + config = true; keys = [ - { - mapping = "rs"; - action = nlib.thunk reload; - desc = "[R]eload [s]nippets"; - } - { - mode = "i"; - expr = true; - mapping = ""; - action = nlib.thunk /* lua */ '' - local luasnip = require("luasnip") - - if not luasnip.jumpable(1) then - return "" - end - - vim.schedule(function() - luasnip.jump(1) - end) - - return "" - ''; - desc = "Jump to next snippet tabstop"; - } - { - mode = "i"; - mapping = ""; - action = nlib.thunk /* lua */ '' - require("luasnip").jump(-1) - ''; - desc = "Jump to previous snippet tabstop"; - } + { mapping = "gc"; mode = "nxv"; } + "gcc" ]; + }; + # }}} + # {{{ mini.surround + mini-surround = { + package = "echasnovski/mini.surround"; + name = "mini.surround"; + + keys = lib.flatten [ + # ^ doing the whole `flatten` thing to lie to my formatter + { mapping = "s"; mode = "nv"; } + [ "d" "f" "F" "h" "r" ] + ]; + + # {{{ Keymaps + opts.mappings = { + add = "s"; # Add surrounding in Normal and Visul modes + delete = "d"; # Delete surrounding + find = "f"; # Find surrounding (to the right) + find_left = "F"; # Find surrounding (to the left) + highlight = "h"; # Highlight surrounding + replace = "r"; # Replace surrounding + update_n_lines = ""; # Update `n_lines` + }; + # }}} + # {{{ Custom surroundings + opts.custom_surroundings = + let mk = balanced: input: left: right: { + input = [ + input + (if balanced + then "^.%s*().-()%s*.$" + else "^.().*().$") + ]; + output = { inherit left right; }; + }; + in + { + b = mk true "%b()" "(" ")"; + B = mk true "%b{}" "{" "}"; + r = mk true "%b[]" "[" "]"; + q = mk false "\".-\"" "\"" "\""; + a = mk false "'.-'" "'" "'"; + }; # }}} }; - # }}} - # }}} - # {{{ ide - # {{{ conform - conform = { - package = "stevearc/conform.nvim"; + # }}} + # {{{ mini.operators + mini-operators = { + package = "echasnovski/mini.operators"; + name = "mini.operators"; - cond = nlib.blacklist "vscode"; - event = "BufReadPost"; - - opts.format_on_save.lsp_fallback = true; - opts.formatters_by_ft = let prettier = [ [ "prettierd" "prettier" ] ]; in - { - lua = [ "stylua" ]; - python = [ "ruff_format" ]; - - javascript = prettier; - typescript = prettier; - javascriptreact = prettier; - typescriptreact = prettier; - html = prettier; - css = prettier; - markdown = prettier; - }; - }; - # }}} - # {{{ neoconf - neoconf = { - package = "folke/neoconf.nvim"; - - cmd = "Neoconf"; - - opts.import = { - vscode = true; # local .vscode/settings.json - coc = false; # global/local coc-settings.json - nlsp = false; # global/local nlsp-settings.nvim json settings - }; - }; - # }}} - # {{{ null-ls - null-ls = { - package = "jose-elias-alvarez/null-ls.nvim"; - dependencies.lua = [ "neovim/nvim-lspconfig" ]; - - cond = nlib.blacklist "vscode"; - event = "BufReadPre"; - - opts = nlib.thunk /* lua */ '' - local p = require("null-ls") - return { - on_attach = require("my.plugins.lspconfig").on_attach, - sources = { - p.builtins.diagnostics.ruff - } - } - ''; - }; - # }}} - # {{{ gitsigns - gitsigns = { - package = "lewis6991/gitsigns.nvim"; - - cond = nlib.blacklist [ "vscode" "firenvim" ]; - event = "BufReadPost"; - - opts.on_attach = nlib.tempest { - mkContext = nlib.lua /* lua */ - "function(bufnr) return { bufnr = bufnr } end"; + config = true; keys = - let - prefix = m: "h${m}"; - gs = "package.loaded.gitsigns"; + let operator = key: [ + { mapping = "g${key}"; mode = "nv"; } + "g${key}${key}" + ]; + in + lib.flatten [ + (operator "=") + (operator "x") + (operator "r") + (operator "s") + ]; + }; + # }}} + # {{{ mini.pairs + mini-pairs = { + package = "echasnovski/mini.pairs"; + name = "mini.pairs"; - # {{{ nmap helper - nmap = mapping: action: desc: { - inherit desc; - mapping = prefix "mapping"; - action = "${gs}.action"; - }; - # }}} - # {{{ exprmap helper - exprmap = mapping: action: desc: { - inherit mapping desc; - action = nlib.thunk /* lua */ '' - if vim.wo.diff then - return "${mapping}" + config = true; + # We could specify all the generated bindings, but I don't think it's worth it + event = [ "InsertEnter" "CmdlineEnter" ]; + }; + # }}} + # {{{ luasnip + # snippeting engine + luasnip = + let reload = /* lua */ ''require("luasnip.loaders.from_vscode").lazy_load()''; + in + { + package = "L3MON4D3/LuaSnip"; + version = "v2"; + + cond = blacklist "vscode"; + config = thunk reload; + + # {{{ Keybinds + keys = [ + { + mapping = "rs"; + action = thunk reload; + desc = "[R]eload [s]nippets"; + } + { + mode = "i"; + expr = true; + mapping = ""; + action = thunk /* lua */ '' + local luasnip = require("luasnip") + + if not luasnip.jumpable(1) then + return "" end vim.schedule(function() - ${gs}.${action}() + luasnip.jump(1) end) return "" ''; - expr = true; - }; - # }}} - in - [ - # {{{ navigation - (exprmap "]c" "next_hunk" "Navigate to next hunk") - (exprmap "[c" "prev_hunk" "Navigate to previous hunk") - # }}} - # {{{ actions - (nmap "s" "stage_hunk" "[s]tage hunk") - (nmap "r" "reset_hunk" "[s]tage hunk") - (nmap "S" "stage_buffer" "[s]tage hunk") - (nmap "u" "undo_stage_hunk" "[s]tage hunk") - (nmap "R" "reset_buffer" "[s]tage hunk") - (nmap "p" "preview_hunk" "[s]tage hunk") - (nmap "d" "diffthis" "[s]tage hunk") - { - mapping = prefix "D"; - action = nlib.thunk '' - ${gs}.diffthis("~") - ''; - desc = "[d]iff file (?)"; + desc = "Jump to next snippet tabstop"; } { - mapping = prefix "b"; - action = nlib.thunk '' - ${gs}.blame_line({ full = true }) + mode = "i"; + mapping = ""; + action = thunk /* lua */ '' + require("luasnip").jump(-1) ''; - desc = "[b]lame line"; + desc = "Jump to previous snippet tabstop"; } - # }}} - # {{{ Toggles - (nmap "tb" "toggle_current_line_blame" "[t]oggle line [b]laming") - (nmap "td" "toggle_deleted" "[t]oggle [d]eleted") - # }}} - # {{{ visual mappings - { - mode = "v"; - mapping = prefix "s"; - action = nlib.thunk /* lua */ '' - ${gs}.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) - ''; - desc = "stage visual hunk"; - } - { - mode = "v"; - mapping = prefix "r"; - action = nlib.thunk /* lua */ '' - ${gs}.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) - ''; - desc = "reset visual hunk"; - } - # }}} ]; + # }}} + }; + # }}} + # }}} + # {{{ ide + # {{{ conform + conform = { + package = "stevearc/conform.nvim"; + + cond = blacklist "vscode"; + event = "BufReadPost"; + + opts.format_on_save.lsp_fallback = true; + opts.formatters_by_ft = let prettier = [ [ "prettierd" "prettier" ] ]; in + { + lua = [ "stylua" ]; + python = [ "ruff_format" ]; + + javascript = prettier; + typescript = prettier; + javascriptreact = prettier; + typescriptreact = prettier; + html = prettier; + css = prettier; + markdown = prettier; + }; }; - }; - # }}} - # {{{ cmp - cmp = { - package = "hrsh7th/nvim-cmp"; - dependencies.lua = [ - # {{{ Completion sources - "hrsh7th/cmp-nvim-lsp" - "hrsh7th/cmp-buffer" - "hrsh7th/cmp-emoji" - "hrsh7th/cmp-cmdline" - "hrsh7th/cmp-path" - "saadparwaiz1/cmp_luasnip" - "dmitmel/cmp-digraphs" - # }}} - "onsails/lspkind.nvim" # show icons in lsp completion menus - self.lazy.luasnip.package - ]; + # }}} + # {{{ neoconf + neoconf = { + package = "folke/neoconf.nvim"; - cond = nlib.blacklist "vscode"; - event = [ "InsertEnter" "CmdlineEnter" ]; - config = nlib.import ./plugins/cmp.lua "config"; - }; - # }}} - # }}} - # {{{ language support - # {{{ haskell support - haskell-tools = { - package = "mrcjkb/haskell-tools.nvim"; - dependencies.lua = [ self.lazy.plenary.package ]; - version = "^2"; + cmd = "Neoconf"; - cond = nlib.blacklist "vscode"; - ft = [ "haskell" "lhaskell" "cabal" "cabalproject" ]; + # Provide autocomplete for every language server + opts.plugins.jsonls.configure_servers_only = false; + opts.import = { + vscode = true; # local .vscode/settings.json + coc = false; # global/local coc-settings.json + nlsp = false; # global/local nlsp-settings.nvim json settings + }; + }; + # }}} + # {{{ null-ls + null-ls = { + package = "jose-elias-alvarez/null-ls.nvim"; + dependencies.lua = [ "neovim/nvim-lspconfig" ]; - config.vim.g.haskell_tools = { - hls = { - on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach''; - settings.haskell = { + cond = blacklist "vscode"; + event = "BufReadPre"; + + opts = thunk /* lua */ '' + local p = require("null-ls") + return { + sources = { + p.builtins.diagnostics.ruff + } + } + ''; + }; + # }}} + # {{{ gitsigns + gitsigns = { + package = "lewis6991/gitsigns.nvim"; + + cond = blacklist [ "vscode" "firenvim" ]; + event = "BufReadPost"; + + opts.on_attach = tempest { + mkContext = lua /* lua */ + "function(bufnr) return { bufnr = bufnr } end"; + keys = + let + prefix = m: "h${m}"; + gs = "package.loaded.gitsigns"; + + # {{{ nmap helper + nmap = mapping: action: desc: { + inherit desc; + mapping = prefix "mapping"; + action = "${gs}.action"; + }; + # }}} + # {{{ exprmap helper + exprmap = mapping: action: desc: { + inherit mapping desc; + action = thunk /* lua */ '' + if vim.wo.diff then + return "${mapping}" + end + + vim.schedule(function() + ${gs}.${action}() + end) + + return "" + ''; + expr = true; + }; + # }}} + in + [ + # {{{ navigation + (exprmap "]c" "next_hunk" "Navigate to next hunk") + (exprmap "[c" "prev_hunk" "Navigate to previous hunk") + # }}} + # {{{ actions + (nmap "s" "stage_hunk" "[s]tage hunk") + (nmap "r" "reset_hunk" "[s]tage hunk") + (nmap "S" "stage_buffer" "[s]tage hunk") + (nmap "u" "undo_stage_hunk" "[s]tage hunk") + (nmap "R" "reset_buffer" "[s]tage hunk") + (nmap "p" "preview_hunk" "[s]tage hunk") + (nmap "d" "diffthis" "[s]tage hunk") + { + mapping = prefix "D"; + action = thunk '' + ${gs}.diffthis("~") + ''; + desc = "[d]iff file (?)"; + } + { + mapping = prefix "b"; + action = thunk '' + ${gs}.blame_line({ full = true }) + ''; + desc = "[b]lame line"; + } + # }}} + # {{{ Toggles + (nmap "tb" "toggle_current_line_blame" "[t]oggle line [b]laming") + (nmap "td" "toggle_deleted" "[t]oggle [d]eleted") + # }}} + # {{{ visual mappings + { + mode = "v"; + mapping = prefix "s"; + action = thunk /* lua */ '' + ${gs}.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) + ''; + desc = "stage visual hunk"; + } + { + mode = "v"; + mapping = prefix "r"; + action = thunk /* lua */ '' + ${gs}.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) + ''; + desc = "reset visual hunk"; + } + # }}} + ]; + }; + }; + # }}} + # {{{ cmp + cmp = { + package = "hrsh7th/nvim-cmp"; + dependencies.lua = [ + # {{{ Completion sources + "hrsh7th/cmp-nvim-lsp" + "hrsh7th/cmp-buffer" + "hrsh7th/cmp-emoji" + "hrsh7th/cmp-cmdline" + "hrsh7th/cmp-path" + "saadparwaiz1/cmp_luasnip" + "dmitmel/cmp-digraphs" + # }}} + "onsails/lspkind.nvim" # show icons in lsp completion menus + self.lazy.luasnip.package + ]; + + cond = blacklist "vscode"; + event = [ "InsertEnter" "CmdlineEnter" ]; + config = importFrom ./plugins/cmp.lua "config"; + }; + # }}} + # }}} + # {{{ language support + # {{{ haskell support + haskell-tools = { + package = "mrcjkb/haskell-tools.nvim"; + dependencies.lua = [ self.lazy.plenary.package ]; + version = "^2"; + + cond = blacklist "vscode"; + ft = [ "haskell" "lhaskell" "cabal" "cabalproject" ]; + + config.vim.g.haskell_tools = { + hls.settings.haskell = { formattingProvider = "fourmolu"; # This seems to work better with custom preludes # See this issue https://github.com/fourmolu/fourmolu/issues/357 plugin.fourmolu.config.external = true; }; + + # I think this wasn't showing certain docs as I expected (?) + tools.hover.enable = false; }; - - # I think this wasn't showing certain docs as I expected (?) - tools.hover.enable = false; - }; - }; - # }}} - # {{{ rust support - # {{{ rust-tools - rust-tools = { - package = "simrat39/rust-tools.nvim"; - dependencies.nix = [ pkgs.rust-analyzer pkgs.rustfmt ]; - - cond = nlib.blacklist "vscode"; - ft = "rust"; - - opts.server.on_attach = nlib.customLanguageServerOnAttach { - keys = { - mapping = "lc"; - action = "RustOpenCargo"; - desc = "Open [c]argo.toml"; - }; - }; - }; - # }}} - # {{{ crates - crates = { - package = "saecki/crates.nvim"; - dependencies.lua = [ self.lazy.plenary.package ]; - - cond = nlib.blacklist "vscode"; - event = "BufReadPost Cargo.toml"; - - # {{{ Set up null_ls source - opts.null_ls = { - enabled = true; - name = "crates"; }; # }}} + # {{{ rust support + # {{{ rust-tools + rust-tools = { + package = "simrat39/rust-tools.nvim"; + dependencies.nix = [ pkgs.rust-analyzer pkgs.rustfmt ]; - config.autocmds = [ - # {{{ Load cmp source on insert - { - event = "InsertEnter"; - group = "CargoCmpSource"; - pattern = "Cargo.toml"; - action = nlib.thunk /* lua */ '' - require("cmp").setup.buffer({ sources = { { name = "crates" } } }) - ''; - } - # }}} - # {{{ Load keybinds on attach - { - event = "BufReadPost"; - group = "CargoKeybinds"; - pattern = "Cargo.toml"; - # # {{{ Register which-key info - # action.callback = nlib.contextThunk /* lua */ '' - # require("which-key").register({ - # ["lc"] = { - # name = "[l]ocal [c]rates", - # bufnr = context.bufnr - # }, - # }) - # ''; - # }}} + cond = blacklist "vscode"; + ft = "rust"; - action.keys = _: - let - # {{{ Keymap helpers - keymap = mapping: action: desc: { - inherit mapping desc; - action = nlib.lua /* lua */ ''require("crates").${action}''; - }; - - keyroot = "lc"; - # }}} - in - # {{{ Keybinds - [ - (keymap "${keyroot}t" "toggle" "[c]rates [t]oggle") - (keymap "${keyroot}r" "reload" "[c]rates [r]efresh") - - (keymap "${keyroot}H" "open_homepage" "[c]rate [H]omephage") - (keymap "${keyroot}R" "open_repository" "[c]rate [R]epository") - (keymap "${keyroot}D" "open_documentation" "[c]rate [D]ocumentation") - (keymap "${keyroot}C" "open_crates_io" "[c]rate [C]rates.io") - - (keymap "${keyroot}v" "show_versions_popup" "[c]rate [v]ersions") - (keymap "${keyroot}f" "show_features_popup" "[c]rate [f]eatures") - (keymap "${keyroot}d" "show_dependencies_popup" "[c]rate [d]eps") - (keymap "K" "show_popup" "[c]rate popup") - ]; - # }}} - } - # }}} - ]; - }; - # }}} - # }}} - # {{{ lean support - lean = { - package = "Julian/lean.nvim"; - name = "lean"; - dependencies.lua = [ - self.lazy.plenary.package - "neovim/nvim-lspconfig" - ]; - - cond = nlib.blacklist "vscode"; - ft = "lean"; - - opts = { - abbreviations = { - builtin = true; - cmp = true; - }; - - lsp = { - on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach''; - capabilites = nlib.lua /* lua */ ''require("my.plugins.lspconfig").capabilities''; - }; - - lsp3 = false; # We don't want the lean 3 language server! - mappings = true; - }; - }; - # }}} - # {{{ idris support - idris = { - package = "ShinKage/idris2-nvim"; - name = "idris"; - dependencies.lua = [ - self.lazy.nui.package - "neovim/nvim-lspconfig" - ]; - - cond = nlib.blacklist "vscode"; - ft = [ "idris2" "lidris2" "ipkg" ]; - - opts = { - client.hover.use_split = true; - serve.on_attach = nlib.customLanguageServerOnAttach { - # {{{ Keymaps - keys = - let keymap = mapping: action: desc: { - inherit desc; - mapping = "i${mapping}"; - action = nlib.lua /* lua */ ''require("idris2.code_action").${action}''; - }; - in - [ - (keymap "C" "make_case" "Make [c]ase") - (keymap "L" "make_lemma" "Make [l]emma") - (keymap "c" "add_clause" "Add [c]lause") - (keymap "e" "expr_search" "[E]xpression search") - (keymap "d" "generate_def" "Generate [d]efinition") - (keymap "s" "case_split" "Case [s]plit") - (keymap "h" "refine_hole" "Refine [h]ole") - ]; - # }}} + opts.server.on_attach = tempestBufnr { + keys = { + mapping = "lc"; + action = "RustOpenCargo"; + desc = "Open [c]argo.toml"; + }; }; }; - }; - # }}} - # {{{ github actions - github-actions = { - package = "yasuhiroki/github-actions-yaml.vim"; - - cond = nlib.blacklist "vscode"; - ft = [ "yml" "yaml" ]; - }; - # }}} - # {{{ typst support - typst = { - package = "kaarmu/typst.vim"; - dependencies.nix = [ pkgs.typst-lsp pkgs.typst-fmt ]; - - cond = nlib.blacklist "vscode"; - ft = "typst"; - }; - # }}} - # {{{ hyprland - hyprland = { - package = "theRealCarneiro/hyprland-vim-syntax"; - - cond = nlib.blacklist "vscode"; - ft = "hypr"; - - config.autocmds = { - event = "BufRead"; - group = "DetectHyprlandConfig"; - pattern = "hyprland.conf"; - action.vim.opt.ft = "hypr"; - }; - }; - # }}} - # }}} - # {{{ external - # These plugins integrate neovim with external services - # {{{ wakatime - wakatime = { - package = "wakatime/vim-wakatime"; - dependencies.nix = [ pkgs.wakatime ]; - - cond = nlib.blacklist [ "vscode" "firenvim" ]; - event = "BufReadPost"; - }; - # }}} - # {{{ discord rich presence - discord-rich-presence = { - package = "andweeb/presence.nvim"; - main = "presence"; - - cond = nlib.blacklist [ "vscode" "firenvim" ]; - event = "BufReadPost"; - config = true; - }; - # }}} - # {{{ gitlinker - # generate permalinks for code - gitlinker = - let mapping = "yg"; - in - { - package = "ruifm/gitlinker.nvim"; + # }}} + # {{{ crates + crates = { + package = "saecki/crates.nvim"; dependencies.lua = [ self.lazy.plenary.package ]; - cond = nlib.blacklist [ "vscode" "firenvim" ]; - opts.mappings = mapping; - keys = mapping; - }; - # }}} - # {{{ paperplanes - # export to pastebin like services - paperlanes = { - package = "rktjmp/paperplanes.nvim"; - cmd = "PP"; - opts.provider = "paste.rs"; - }; - # }}} - # {{{ obsidian - obsidian = - let vault = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum"; - in - { - package = "epwalsh/obsidian.nvim"; - dependencies.lua = [ self.lazy.plenary.package ]; + cond = blacklist "vscode"; + event = "BufReadPost Cargo.toml"; - cond = [ - (nlib.blacklist [ "vscode" "firenvim" ]) - (nlib.lua /* lua */ "vim.loop.cwd() == ${nlib.encode vault}") + # {{{ Set up null_ls source + opts.null_ls = { + enabled = true; + name = "crates"; + }; + # }}} + + config.autocmds = [ + # {{{ Load cmp source on insert + { + event = "InsertEnter"; + group = "CargoCmpSource"; + pattern = "Cargo.toml"; + action = thunk /* lua */ '' + require("cmp").setup.buffer({ sources = { { name = "crates" } } }) + ''; + } + # }}} + # {{{ Load keybinds on attach + { + event = "BufReadPost"; + group = "CargoKeybinds"; + pattern = "Cargo.toml"; + # # {{{ Register which-key info + # action.callback = contextThunk /* lua */ '' + # require("which-key").register({ + # ["lc"] = { + # name = "[l]ocal [c]rates", + # bufnr = context.bufnr + # }, + # }) + # ''; + # }}} + + action.keys = _: + let + # {{{ Keymap helpers + nmap = mapping: action: desc: { + inherit mapping desc; + action = lua /* lua */ ''require("crates").${action}''; + }; + + keyroot = "lc"; + # }}} + in + # {{{ Keybinds + [ + (nmap "${keyroot}t" "toggle" "[c]rates [t]oggle") + (nmap "${keyroot}r" "reload" "[c]rates [r]efresh") + + (nmap "${keyroot}H" "open_homepage" "[c]rate [H]omephage") + (nmap "${keyroot}R" "open_repository" "[c]rate [R]epository") + (nmap "${keyroot}D" "open_documentation" "[c]rate [D]ocumentation") + (nmap "${keyroot}C" "open_crates_io" "[c]rate [C]rates.io") + + (nmap "${keyroot}v" "show_versions_popup" "[c]rate [v]ersions") + (nmap "${keyroot}f" "show_features_popup" "[c]rate [f]eatures") + (nmap "${keyroot}d" "show_dependencies_popup" "[c]rate [d]eps") + (nmap "K" "show_popup" "[c]rate popup") + ]; + # }}} + } + # }}} + ]; + }; + # }}} + # }}} + # {{{ lean support + lean = { + package = "Julian/lean.nvim"; + name = "lean"; + dependencies.lua = [ + self.lazy.plenary.package + "neovim/nvim-lspconfig" ]; - event = "VeryLazy"; - keys.mapping = ""; - keys.action = "ObsidianQuickSwitch"; + cond = blacklist "vscode"; + ft = "lean"; opts = { - dir = vault; - notes_subdir = "chaos"; - daily_notes = { - folder = "daily"; - date_format = "%Y-%m-%d"; + abbreviations = { + builtin = true; + cmp = true; }; - completion = { - nvim_cmp = true; - min_chars = 2; - new_notes_location = "current_dir"; - prepend_note_id = true; - }; + lsp.capabilites = + lua /* lua */ ''require("my.plugins.lspconfig").capabilities''; - mappings = { }; - disable_frontmatter = true; + lsp3 = false; # We don't want the lean 3 language server! + mappings = true; }; }; + # }}} + # {{{ idris support + idris = { + package = "ShinKage/idris2-nvim"; + name = "idris"; + dependencies.lua = [ + self.lazy.nui.package + "neovim/nvim-lspconfig" + ]; + + cond = blacklist "vscode"; + ft = [ "idris2" "lidris2" "ipkg" ]; + + opts = { + client.hover.use_split = true; + serve.on_attach = tempestBufnr { + # {{{ Keymaps + keys = + let keymap = mapping: action: desc: { + inherit desc; + mapping = "i${mapping}"; + action = lua /* lua */ ''require("idris2.code_action").${action}''; + }; + in + [ + (keymap "C" "make_case" "Make [c]ase") + (keymap "L" "make_lemma" "Make [l]emma") + (keymap "c" "add_clause" "Add [c]lause") + (keymap "e" "expr_search" "[E]xpression search") + (keymap "d" "generate_def" "Generate [d]efinition") + (keymap "s" "case_split" "Case [s]plit") + (keymap "h" "refine_hole" "Refine [h]ole") + ]; + # }}} + }; + }; + }; + # }}} + # {{{ github actions + github-actions = { + package = "yasuhiroki/github-actions-yaml.vim"; + + cond = blacklist "vscode"; + ft = [ "yml" "yaml" ]; + }; + # }}} + # {{{ typst support + typst = { + package = "kaarmu/typst.vim"; + dependencies.nix = [ pkgs.typst-lsp pkgs.typst-fmt ]; + + cond = blacklist "vscode"; + ft = "typst"; + }; + # }}} + # {{{ hyprland + hyprland = { + package = "theRealCarneiro/hyprland-vim-syntax"; + + cond = blacklist "vscode"; + ft = "hypr"; + + config.autocmds = { + event = "BufRead"; + group = "DetectHyprlandConfig"; + pattern = "hyprland.conf"; + action.vim.opt.ft = "hypr"; + }; + }; + # }}} + # }}} + # {{{ external + # These plugins integrate neovim with external services + # {{{ wakatime + wakatime = { + package = "wakatime/vim-wakatime"; + dependencies.nix = [ pkgs.wakatime ]; + + cond = blacklist [ "vscode" "firenvim" ]; + event = "BufReadPost"; + }; + # }}} + # {{{ discord rich presence + discord-rich-presence = { + package = "andweeb/presence.nvim"; + main = "presence"; + + cond = blacklist [ "vscode" "firenvim" ]; + event = "BufReadPost"; + config = true; + }; + # }}} + # {{{ gitlinker + # generate permalinks for code + gitlinker = + let mapping = "yg"; + in + { + package = "ruifm/gitlinker.nvim"; + dependencies.lua = [ self.lazy.plenary.package ]; + + cond = blacklist [ "vscode" "firenvim" ]; + opts.mappings = mapping; + keys = mapping; + }; + # }}} + # {{{ paperplanes + # export to pastebin like services + paperlanes = { + package = "rktjmp/paperplanes.nvim"; + cmd = "PP"; + opts.provider = "paste.rs"; + }; + # }}} + # {{{ obsidian + obsidian = + let vault = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum"; + in + { + package = "epwalsh/obsidian.nvim"; + dependencies.lua = [ self.lazy.plenary.package ]; + + cond = [ + (blacklist [ "vscode" "firenvim" ]) + (lua /* lua */ "vim.loop.cwd() == ${encode vault}") + ]; + event = "VeryLazy"; + + keys.mapping = ""; + keys.action = "ObsidianQuickSwitch"; + + opts = { + dir = vault; + notes_subdir = "chaos"; + daily_notes = { + folder = "daily"; + date_format = "%Y-%m-%d"; + }; + + completion = { + nvim_cmp = true; + min_chars = 2; + new_notes_location = "current_dir"; + prepend_note_id = true; + }; + + mappings = { }; + disable_frontmatter = true; + }; + }; + # }}} + # }}} + }; # }}} - # }}} - }; - # }}} - })); + })); # {{{ extraPackages extraPackages = with pkgs; [ @@ -1290,7 +1365,6 @@ let # Others fd # file finder - update-nix-fetchgit # Useful for nix stuff # Latex setup # texlive.combined.scheme-full # Latex stuff @@ -1305,15 +1379,19 @@ let extraRuntimePaths = [ generatedConfig ]; - extraRuntimeJoinedPaths = pkgs.symlinkJoin { - name = "nixified-neovim-lua-modules"; - paths = extraRuntimePaths; - }; + extraRuntimeJoinedPaths = pkgs.symlinkJoin + { + name = "nixified-neovim-lua-modules"; + paths = extraRuntimePaths; + }; extraRuntime = - let snippets = config.satellite.dev.path "home/features/neovim/snippets"; + let snippets = config.satellite.dev.path + "home/features/neovim/snippets"; in - lib.concatStringsSep "," [ extraRuntimeJoinedPaths snippets ]; + lib.concatStringsSep + "," + [ extraRuntimeJoinedPaths snippets ]; # }}} # {{{ Client wrapper # Wraps a neovim client, providing the dependencies @@ -1346,26 +1424,29 @@ let }; # }}} # {{{ Clients - neovim = wrapClient { - base = - if config.satellite.toggles.neovim-nightly.enable - then pkgs.neovim-nightly - else pkgs.neovim; - name = "nvim"; - }; + neovim = wrapClient + { + base = + if config.satellite.toggles.neovim-nightly.enable + then pkgs.neovim-nightly + else pkgs.neovim; + name = "nvim"; + }; - neovide = wrapClient { - base = pkgs.neovide; - name = "neovide"; - extraArgs = "--set NEOVIDE_MULTIGRID true"; - }; + neovide = wrapClient + { + base = pkgs.neovide; + name = "neovide"; + extraArgs = "--set NEOVIDE_MULTIGRID true"; + }; - firenvim = wrapClient { - base = pkgs.neovim; - name = "firenvim"; - binName = "nvim"; - extraArgs = "--set GIT_DISCOVERY_ACROSS_FILESYSTEM 1"; - }; + firenvim = wrapClient + { + base = pkgs.neovim; + name = "firenvim"; + binName = "nvim"; + extraArgs = "--set GIT_DISCOVERY_ACROSS_FILESYSTEM 1"; + }; # }}} in { diff --git a/modules/common/korora-neovim.nix b/modules/common/korora-neovim.nix index d5c1a02..9cc99ea 100644 --- a/modules/common/korora-neovim.nix +++ b/modules/common/korora-neovim.nix @@ -110,11 +110,12 @@ let tempestConfig = lazyType "lazy tempest config" (_: struct "tempest config" { vim = types.luaValue; - callback = k.union [ k.function types.luaLiteral ]; + callback = k.union [ types.luaLiteral types.tempestConfig ]; setup = k.attrsOf types.luaValue; keys = types.luaEagerOrLazy (types.oneOrMany types.tempestKey); autocmds = types.luaEagerOrLazy (types.oneOrMany types.tempestAutocmd); - mkContext = types.luaLiteral; + mkContext = types.luaValue; + cond = types.oneOrMany types.luaLiteral; } [ ]); # }}} @@ -136,15 +137,14 @@ let let err = type.verify value; in lib.assertMsg (err == null) err; - mkLib = { tempestModule, languageServerModule }: + mkLib = { tempestModule }: assert hasType k.string tempestModule; - assert hasType k.string languageServerModule; rec { inherit (e) encode; # {{{ Common generation helpers lua = value: assert hasType k.string value; { inherit value; __luaEncoderTag = "lua"; }; - import = path: tag: + importFrom = path: tag: assert lib.isPath path; assert hasType k.string tag; lua "dofile(${encode (toString path)}).${tag}"; @@ -157,16 +157,18 @@ let ${context} ) ''; - customLanguageServerOnAttach = given: - assert hasType types.tempestConfig given; - lua /* lua */ '' - function(client, bufnr) - D.tempest.configure(${encode given}, - { client = client; bufnr = bufnr; }) - - D.language_server.on_attach(client, bufnr) - end - ''; + tempestBufnr = given: context: lua '' + D.tempest.configure( + ${encode given}, + { bufnr = ${context}} + ) + ''; + keymap = mode: mapping: action: desc: + { inherit mode mapping action desc; }; + nmap = mapping: action: desc: + { inherit mapping action desc; }; + unmap = mapping: + { inherit mapping; action = ""; }; blacklist = given: assert hasType (types.oneOrMany types.neovimEnv) given; lua /* lua */ '' @@ -210,7 +212,6 @@ let local M = {} local D = { tempest = require(${encode tempestModule}), - langauge_server = require(${encode languageServerModule}) } -- {{{ Pre-plugin config