diff --git a/home/features/cli/fish/default.nix b/home/features/cli/fish/default.nix index c636470..3508aeb 100644 --- a/home/features/cli/fish/default.nix +++ b/home/features/cli/fish/default.nix @@ -1,8 +1,28 @@ { pkgs, config, lib, ... }: { + # {{{ Fzf + programs.fzf = { + enable = true; + defaultOptions = [ "--no-scrollbar" ]; + + + changeDirWidgetOptions = [ + "--preview '${lib.getExe pkgs.eza} --icons --tree --color=always {}'" + ]; + + fileWidgetOptions = [ + "--preview '${lib.getExe pkgs.bat} --number --color=always {}'" + ]; + }; + + stylix.targets.fzf.enable = true; + # }}} + # {{{ Fish programs.fish = { enable = true; + interactiveShellInit = builtins.readFile ./config.fish; + # {{{ Plugins plugins = let plugins = with pkgs.fishPlugins; [ @@ -12,7 +32,6 @@ puffer # Text expansion (i.e. expanding .... to ../../../) sponge # Remove failed commands and whatnot from history forgit # Git tui thingy? (I'm still trying this one out) - fzf-fish # Fuzzy finder for things like files colored-man-pages # Self explainatory:) ]; in @@ -22,12 +41,12 @@ name = plugin.pname; inherit (plugin) src; }); - - interactiveShellInit = builtins.readFile ./config.fish; + # }}} }; satellite.persistence.at.state.apps.fish.directories = [ "${config.xdg.dataHome}/fish" "${config.xdg.dataHome}/z" # The z fish plugin ]; + # }}} } diff --git a/home/features/neovim/config/ftplugin/tex.lua b/home/features/neovim/config/ftplugin/tex.lua index 84b604b..4e8ad72 100644 --- a/home/features/neovim/config/ftplugin/tex.lua +++ b/home/features/neovim/config/ftplugin/tex.lua @@ -6,28 +6,6 @@ require("my.abbreviations.math").setup() vim.opt.conceallevel = 0 --- {{{ Older functions for calculating things inside vim --- vim.keymap.set("n", "lg", function() --- if not pcall(function() --- local a = tonumber(vim.fn.input("A: ")) --- local b = tonumber(vim.fn.input("B: ")) --- --- local g, x, y = require("my.helpers.math.mod").gcd(a, b) --- --- vim.fn.input("Result: " .. g .. " " .. x .. " " .. y) --- end) then vim.fn.input("No results exist") end --- end, { buffer = true, desc = "Gcd calculator" }) --- --- vim.keymap.set("n", "li", function() --- if not pcall(function() --- local class = tonumber(vim.fn.input("Mod class: ")) --- local num = tonumber(vim.fn.input("Number: ")) --- --- vim.fn.input("Result: " .. require("my.helpers.math.mod").modinverse(num, class)) --- end) then vim.fn.input("No results exist") end --- end, { buffer = true, desc = "Mod inverse calculator" }) --- }}} - local abbreviations = { -- Other fancy symvols { "tmat", "^T" }, -- Tranpose of a matrix diff --git a/home/features/neovim/config/lazy-lock.json b/home/features/neovim/config/lazy-lock.json index 147d9a5..50b7e11 100644 --- a/home/features/neovim/config/lazy-lock.json +++ b/home/features/neovim/config/lazy-lock.json @@ -2,7 +2,7 @@ "LuaSnip": { "branch": "master", "commit": "409535b8fc54c650eb845b0c35e0cc7f08810284" }, "alpha-nvim": { "branch": "main", "commit": "63a860e7ed3ae41ee92481ea65a48fb35431ae21" }, "catppuccin": { "branch": "main", "commit": "490078b1593c6609e6a50ad5001e7902ea601824" }, - "clipboard-image.nvim": { "branch": "main", "commit": "af8fdaad7e6fed0741e18dbf2f57bdc7494adaee" }, + "clipboard-image": { "branch": "main", "commit": "485de5493d196154db30f85665f8ac480ce116a2" }, "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" }, "cmp-cmdline": { "branch": "main", "commit": "8ee981b4a91f536f52add291594e89fb6645e451" }, "cmp-emoji": { "branch": "main", "commit": "19075c36d5820253d32e2478b6aaf3734aeaafa0" }, @@ -10,7 +10,7 @@ "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" }, "cmp_luasnip": { "branch": "master", "commit": "18095520391186d634a0045dacaa346291096566" }, "conform": { "branch": "master", "commit": "5bf1405fd234d469243ea6f394e0aeec9ea53bd8" }, - "crates.nvim": { "branch": "main", "commit": "d5caf28aba49e81ac4099426231f3cf3c151013a" }, + "crates": { "branch": "main", "commit": "b8ea20fda2e1029fbbb1bae7a9eab35c84037ca0" }, "dhall-vim": { "branch": "master", "commit": "68500ef46ff3706f46c99db3be7a0c8abcf6a3ae" }, "dressing.nvim": { "branch": "master", "commit": "6bde51adabba06f7fd4a469885a85f36d78a5f52" }, "fidget.nvim": { "branch": "main", "commit": "0ba1e16d07627532b6cae915cc992ecac249fb97" }, @@ -19,7 +19,7 @@ "gitlinker.nvim": { "branch": "master", "commit": "cc59f732f3d043b626c8702cb725c82e54d35c25" }, "gitsigns.nvim": { "branch": "main", "commit": "af0f583cd35286dd6f0e3ed52622728703237e50" }, "harpoon": { "branch": "master", "commit": "21f4c47c6803d64ddb934a5b314dcb1b8e7365dc" }, - "haskell-tools.nvim": { "branch": "master", "commit": "b19df600da8ef5fb4fb280815415ebd2a4228f0f" }, + "haskell-tools": { "branch": "master", "commit": "92e097c6832405fb64e4c44a7ce8bebe7836cae6" }, "hydra.nvim": { "branch": "master", "commit": "3ced42c0b6a6c85583ff0f221635a7f4c1ab0dd0" }, "hyprland-vim-syntax": { "branch": "main", "commit": "8488a24b50882da969979103b4d668c70e7995b9" }, "idris2-nvim": { "branch": "main", "commit": "3a2b4d2b5ffeab9e47298456c59c31b4e1ddebc9" }, @@ -48,7 +48,7 @@ "nvim-cmp": { "branch": "main", "commit": "51f1e11a89ec701221877532ee1a23557d291dd5" }, "nvim-comment": { "branch": "main", "commit": "e9ac16ab056695cad6461173693069ec070d2b23" }, "nvim-lspconfig": { "branch": "master", "commit": "a981d4447b92c54a4d464eb1a76b799bc3f9a771" }, - "nvim-tree.lua": { "branch": "master", "commit": "18c7a3119839adc4599d838726deae662859c8b2" }, + "nvim-tree": { "branch": "master", "commit": "7d1760f892951dd6a118dae1d7a1d8df5f029edf" }, "nvim-treesitter": { "branch": "master", "commit": "0791b5ebb590a2d44e20640c52679df1fc42e8ab" }, "nvim-treesitter-context": { "branch": "master", "commit": "a17c31268b56d53624fdc9cb03a225d4a17cabdb" }, "nvim-treesitter-textobjects": { "branch": "master", "commit": "9e519b6146512c8e2e702faf8ac48420f4f5deec" }, @@ -59,6 +59,7 @@ "presence.nvim": { "branch": "main", "commit": "87c857a56b7703f976d3a5ef15967d80508df6e6" }, "purescript-vim": { "branch": "main", "commit": "82348352e6568fcc0385bd7c99a8ead3a479feea" }, "rasi.vim": { "branch": "main", "commit": "eac9969cf935cd4380987dc99bfa10d69d3f34a6" }, + "rust-tools": { "branch": "master", "commit": "0cc8adab23117783a0292a0c8a2fbed1005dc645" }, "rust-tools.nvim": { "branch": "master", "commit": "0cc8adab23117783a0292a0c8a2fbed1005dc645" }, "scrap.nvim": { "branch": "main", "commit": "16db44ae9403ec9c4b140394f294475d1af80a18" }, "smart-splits.nvim": { "branch": "master", "commit": "7aad6019dee974a01333523a5b8e122b7e7da454" }, diff --git a/home/features/neovim/config/lua/my/abbreviations/unicode.lua b/home/features/neovim/config/lua/my/abbreviations/unicode.lua index 6a103e9..7d70556 100644 --- a/home/features/neovim/config/lua/my/abbreviations/unicode.lua +++ b/home/features/neovim/config/lua/my/abbreviations/unicode.lua @@ -6,10 +6,7 @@ local M = {} M.unicode = { -- {{{ Logic { "frl", "∀" }, -- [f]o[r]al[l] - - - - { "exs", "∃" }, -- [e][x]ist[s] + { "exs", "∃" }, -- [e][x]ist[s] { "land", "∧" }, -- [l]ogical [and] { "Land", "⋀" }, -- arbitrary [l]ogical [and] { "lor", "∨" }, -- [l]ogical [or] @@ -23,6 +20,7 @@ M.unicode = { -- }}} -- {{{ Set theory { "nolla", "∅" }, + { "carprod", "×" }, -- cartesian product { "sect", "∩" }, -- set intersection { "Sect", "⋂" }, -- arbitrary set intersection { "dsect", "⊓" }, -- disjoint set intersection (whatever that means lol) diff --git a/home/features/neovim/config/lua/my/helpers/math/mod.lua b/home/features/neovim/config/lua/my/helpers/math/mod.lua deleted file mode 100644 index 50de361..0000000 --- a/home/features/neovim/config/lua/my/helpers/math/mod.lua +++ /dev/null @@ -1,15 +0,0 @@ -local M = {} - -function M.modinverse(b, m) - local g, x, _ = M.gcd(b, m) - if g ~= 1 then return nil end - return x % m -end - -function M.gcd(a, b) - if a == 0 then return b, 0, 1 end - local g, x1, y1 = M.gcd(b % a, a) - return g, y1 - (math.floor(b / a)) * x1, x1 -end - -return M diff --git a/home/features/neovim/config/lua/my/plugins/clipboard-image.lua b/home/features/neovim/config/lua/my/plugins/clipboard-image.lua deleted file mode 100644 index 8bb09ee..0000000 --- a/home/features/neovim/config/lua/my/plugins/clipboard-image.lua +++ /dev/null @@ -1,42 +0,0 @@ -local M = { - "postfen/clipboard-image.nvim", - cmd = "PasteImg", -} - -local function img_name() - vim.fn.inputsave() - local name = vim.fn.input("Name: ") - vim.fn.inputrestore() - - if name == nil or name == "" then - return os.date("%y-%m-%d-%H-%M-%S") - end - return name -end - -function M.init() - vim.keymap.set( - "n", - "p", - ":PasteImg", - { desc = "[P]aste image from clipboard" } - ) -end - -function M.config() - require("clipboard-image").setup({ - default = { - img_name = img_name, - }, - tex = { - img_dir = { "%:p:h", "img" }, - affix = "\\includegraphics[width=\\textwidth]{%s}", - }, - typst = { - img_dir = { "%:p:h", "img" }, - affix = '#image("%s", width: 100)', - }, - }) -end - -return M diff --git a/home/features/neovim/config/lua/my/plugins/cmp.lua b/home/features/neovim/config/lua/my/plugins/cmp.lua index 425cd26..8d60f4b 100644 --- a/home/features/neovim/config/lua/my/plugins/cmp.lua +++ b/home/features/neovim/config/lua/my/plugins/cmp.lua @@ -117,7 +117,6 @@ function M.config() { name = "cmdline" }, }), }) - end return M diff --git a/home/features/neovim/config/lua/my/plugins/crates.lua b/home/features/neovim/config/lua/my/plugins/crates.lua deleted file mode 100644 index f095fca..0000000 --- a/home/features/neovim/config/lua/my/plugins/crates.lua +++ /dev/null @@ -1,51 +0,0 @@ -local K = require("my.keymaps") -local M = { - "saecki/crates.nvim", - event = "BufReadPost Cargo.toml", - dependencies = { "nvim-lua/plenary.nvim" }, - config = function() - local crates = require("crates") - - crates.setup({ - null_ls = { - enabled = true, - name = "crates.nvim", - }, - }) - - vim.api.nvim_create_autocmd("InsertEnter", { - group = vim.api.nvim_create_augroup("CmpSourceCargo", {}), - pattern = "Cargo.toml", - callback = function() - require("cmp").setup.buffer({ sources = { { name = "crates" } } }) - end, - }) - - local function nmap(from, to, desc) - K.nmap(from, to, desc, true, true) - end - - nmap("lct", crates.toggle, "[c]rates [t]oggle") - nmap("lcr", crates.reload, "[c]rates [r]efresh") - - nmap("lcH", crates.open_homepage, "[c]rates [H]omepage") - nmap("lcR", crates.open_repository, "[c]rates [R]repository") - nmap("lcD", crates.open_documentation, "[c]rates [D]ocumentation") - nmap("lcC", crates.open_crates_io, "[c]rates [C]rates.io") - - nmap("lcv", crates.show_versions_popup, "[c]rates [v]ersions") - nmap("lcf", crates.show_features_popup, "[c]rates [f]eatures") - nmap("lcd", crates.show_dependencies_popup, "[c]rates [d]eps") - nmap("K", crates.show_popup, "crates popup") - - local wk = require("which-key") - - wk.register({ - ["lc"] = { - name = "[l]ocal [c]rates", - }, - }) - end, -} - -return M diff --git a/home/features/neovim/config/lua/my/plugins/haskell-tools.lua b/home/features/neovim/config/lua/my/plugins/haskell-tools.lua deleted file mode 100644 index 9d16960..0000000 --- a/home/features/neovim/config/lua/my/plugins/haskell-tools.lua +++ /dev/null @@ -1,32 +0,0 @@ -local lspconfig = require("my.plugins.lspconfig") -local M = { - "mrcjkb/haskell-tools.nvim", - dependencies = { - "nvim-lua/plenary.nvim", - }, - version = "^2", - ft = { "haskell", "lhaskell", "cabal", "cabalproject" }, -} - -function M.config() - vim.g.haskell_tools = { - hls = { - on_attach = lspconfig.on_attach, - 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 } } }, - }, - }, - }, - tools = { - hover = { - enable = false, - }, - }, - } -end - -return M diff --git a/home/features/neovim/config/lua/my/plugins/lspconfig.lua b/home/features/neovim/config/lua/my/plugins/lspconfig.lua index 5fa7ced..c207256 100644 --- a/home/features/neovim/config/lua/my/plugins/lspconfig.lua +++ b/home/features/neovim/config/lua/my/plugins/lspconfig.lua @@ -30,27 +30,13 @@ local M = { function M.on_attach(client, bufnr) -- {{{ Keymap helpers local opts = function(desc) - return { noremap = true, silent = true, desc = desc, buffer = bufnr } + return { silent = true, desc = desc, buffer = bufnr } end local nmap = function(from, to, desc) vim.keymap.set("n", from, to, opts(desc)) end -- }}} - -- {{{ Auto format - local function format() - vim.lsp.buf.format({ async = false, bufnr = bufnr }) - end - - -- if client.supports_method("textDocument/formatting") then - -- nmap("F", format, "[F]ormat") - -- vim.api.nvim_create_autocmd("BufWritePre", { - -- group = vim.api.nvim_create_augroup("LspFormatting", { clear = false }), - -- buffer = bufnr, - -- callback = format, - -- }) - -- 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") @@ -131,7 +117,7 @@ local servers = { Lua = { ---@diagnostic disable-next-line: missing-fields format = { - enable = true + enable = true, }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { @@ -215,9 +201,9 @@ function lspconfig.config() diagnostics_icons() -- -- {{{ Change on-hover borders vim.lsp.handlers["textDocument/hover"] = - vim.lsp.with(vim.lsp.handlers.hover, { border = "single" }) + vim.lsp.with(vim.lsp.handlers.hover, { border = "single" }) vim.lsp.handlers["textDocument/signatureHelp"] = - vim.lsp.with(vim.lsp.handlers.signature_help, { border = "single" }) + vim.lsp.with(vim.lsp.handlers.signature_help, { border = "single" }) -- -- }}} local capabilities = M.capabilities() @@ -230,7 +216,7 @@ function lspconfig.config() require("lspconfig")[lsp].setup({ on_attach = details.on_attach, - settings = details.settings, -- Specific per-language settings + settings = details.settings, -- Specific per-language settings flags = { debounce_text_changes = 150, -- This will be the default in neovim 0.7+ }, diff --git a/home/features/neovim/config/lua/my/plugins/rust-tools.lua b/home/features/neovim/config/lua/my/plugins/rust-tools.lua deleted file mode 100644 index 9b7597a..0000000 --- a/home/features/neovim/config/lua/my/plugins/rust-tools.lua +++ /dev/null @@ -1,25 +0,0 @@ -local K = require("my.keymaps") -local lspconfig = require("my.plugins.lspconfig") - -local M = { - "simrat39/rust-tools.nvim", - config = function() - require("rust-tools").setup({ - server = { - on_attach = function(client, bufnr) - K.nmap( - "lc", - "RustOpenCargo", - "Open [c]argo.toml", - true, - true - ) - - lspconfig.on_attach(client, bufnr) - end, - }, - }) - end, -} - -return M diff --git a/home/features/neovim/config/lua/my/plugins/vimtex.lua b/home/features/neovim/config/lua/my/plugins/vimtex.lua deleted file mode 100644 index 580c1b6..0000000 --- a/home/features/neovim/config/lua/my/plugins/vimtex.lua +++ /dev/null @@ -1,26 +0,0 @@ -local M = { - "lervag/vimtex", -- latex support - ft = "tex", - enabled = false -} - -function M.config() - vim.g.vimtex_view_method = "zathura" - vim.g.Tex_DefaultTargetFormat = "pdf" - vim.g.vimtex_compiler_latexmk = { - options = { - "-pdf", - "-shell-escape", - "-verbose", - "-file-line-error", - "-synctex=1", - "-interaction=nonstopmode", - }, - } - - vim.g.vimtex_fold_enabled = 0 - vim.g.vimtex_imaps_enabled = 0 - vim.g.vimtex_syntax_conceal_disable = 1 -end - -return M diff --git a/home/features/neovim/config/lua/my/runtime.lua b/home/features/neovim/config/lua/my/runtime.lua new file mode 100644 index 0000000..5bc1401 --- /dev/null +++ b/home/features/neovim/config/lua/my/runtime.lua @@ -0,0 +1,132 @@ +local M = {} + +-- {{{ General helpers +local function string_chars(str) + local chars = {} + for i = 1, #str do + table.insert(chars, str:sub(i, i)) + end + return chars +end + +local function with_default(default, given) + if given == nil then + return default + else + return given + end +end +-- }}} +-- {{{ API wrappers +-- {{{ Keymaps +function M.set_keymap(opts, context) + if context == nil then + context = {} + end + + local buffer = nil + + if context.bufnr ~= nil then + buffer = context.bufnr + end + + vim.keymap.set( + string_chars(with_default("n", opts.mode)), + opts.mapping, + opts.action, + { + desc = opts.desc, + buffer = with_default(buffer, opts.buffer), + expr = opts.expr, + silent = with_default(true, opts.silent), + } + ) +end +-- }}} +-- {{{ Autocmds +function M.create_autocmd(opts) + local callback + + if type(opts.callback) == "function" then + callback = opts.callback + end + + if type(opts.callback) == "table" then + callback = function(event) + M.configure(opts.callback, event) + end + end + + vim.api.nvim_create_autocmd(opts.event, { + group = vim.api.nvim_create_augroup(opts.group, {}), + pattern = opts.pattern, + callback = callback, + }) +end +-- }}} +-- }}} +-- {{{ Main config runtime +local function recursive_assign(source, destination) + for key, value in pairs(source) do + if type(value) == "table" then + destination[key] = destination[key] or {} + recursive_assign(value, destination[key]) + else + destination[key] = value + end + end +end + +function M.configure(opts, context) + if type(opts.vim) == "table" then + recursive_assign(opts, vim) + end + + if type(opts.keys) == "table" then + local keys = opts.keys + + -- Detect single key passed instead of array + if keys.mapping ~= nil then + keys = { keys } + end + + for _, keymap in ipairs(keys) do + M.set_keymap(keymap, context) + end + end + + if type(opts.autocmds) == "table" then + local autocmds = opts.autocmds + + -- Detect single autocmd passed instead of array + if autocmds.pattern ~= nil then + autocmds = { autocmds } + end + + for _, autocmd in ipairs(autocmds) do + M.create_autocmd(autocmd) + end + end + + if type(opts.setup) == "table" then + for key, arg in pairs(opts.setup) do + require(key).setup(arg) + end + end + + if + type(context) == "table" + and context.opts ~= nil + and context.lazy ~= nil + then + -- This is a terrible way to do it :/ + require(context.lazy.name).setup(context.opts) + end + + if type(opts.callback) == "function" then + opts.callback(context) + end +end +-- }}} + +return M diff --git a/home/features/neovim/default.nix b/home/features/neovim/default.nix index 69f2da1..e39f159 100644 --- a/home/features/neovim/default.nix +++ b/home/features/neovim/default.nix @@ -62,8 +62,8 @@ let # Latex setup texlive.combined.scheme-full # Latex stuff python38Packages.pygments # required for latex syntax highlighting - sage - sagetex # sage in latex + # sage + # sagetex # sage in latex # required for the telescope fzf extension gnumake @@ -208,28 +208,32 @@ in }; }; # }}} - # {{{ Custom module testing + # {{{ Plugins satellite.neovim.styluaConfig = ../../../stylua.toml; - satellite.neovim.env.module = "my.helpers.env"; + satellite.neovim.runtime = { + env = "my.helpers.env"; + languageServerOnAttach = "my.plugins.lspconfig"; + tempest = "my.runtime"; + }; - # {{{ Nvim-tree + # {{{ ui + # {{{ nvim-tree satellite.neovim.lazy.nvim-tree = { package = "kyazdani42/nvim-tree.lua"; + env.blacklist = [ "vscode" "firenvim" ]; setup = true; - cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; keys.mapping = ""; keys.desc = "Toggle [n]vim-tree"; keys.action = "NvimTreeToggle"; }; # }}} - # {{{ Lualine + # {{{ lualine satellite.neovim.lazy.lualine = { package = "nvim-lualine/lualine.nvim"; - name = "lualine"; - cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; + env.blacklist = [ "vscode" "firenvim" ]; event = "VeryLazy"; opts = { @@ -254,71 +258,17 @@ in }; }; # }}} - # {{{ Winbar + # {{{ winbar satellite.neovim.lazy.winbar = { package = "fgheng/winbar.nvim"; - name = "winbar"; - cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; + env.blacklist = [ "vscode" "firenvim" ]; event = "VeryLazy"; opts.enabled = true; }; # }}} - # {{{ Flash - satellite.neovim.lazy.flash = { - package = "folke/flash.nvim"; - name = "flash"; - - cond = nlib.blacklistEnv [ "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; - }; - # }}} - # {{{ Conform.nvim - satellite.neovim.lazy.conform = { - package = "stevearc/conform.nvim"; - name = "conform"; - - cond = nlib.blacklistEnv [ "vscode" ]; - event = "BufReadPost"; - - opts.format_on_save.lsp_fallback = true; - opts.formatters_by_ft = { - lua = [ "stylua" ]; - python = [ "ruff_format" ]; - javascript = [ [ "prettierd" "prettier" ] ]; - }; - }; - # }}} - # {{{ Neoconf - satellite.neovim.lazy.neoconf = { - package = "folke/neoconf.nvim"; - name = "neoconf"; - - 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 - }; - }; - # }}} - # {{{ Harpoon + # {{{ harpoon satellite.neovim.lazy.harpoon = { package = "ThePrimeagen/harpoon"; keys = @@ -355,4 +305,212 @@ in }; # }}} # }}} + # {{{ editing + # {{{ flash + satellite.neovim.lazy.flash = { + package = "folke/flash.nvim"; + + env.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; + }; + # }}} + # {{{ clipboard-image + satellite.neovim.lazy.clipboard-image = { + package = "postfen/clipboard-image.nvim"; + + env.blacklist = [ "firenvim" ]; + cmd = "PasteImg"; + + keys = { + mapping = "p"; + action = "PasteImg"; + desc = "[P]aste image from clipboard"; + }; + + 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)''; + }; + }; + # }}} + # }}} + # {{{ ide + # {{{ conform + satellite.neovim.lazy.conform = { + package = "stevearc/conform.nvim"; + + env.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 + satellite.neovim.lazy.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 + }; + }; + # }}} + # }}} + # {{{ language support + # {{{ haskell + satellite.neovim.lazy.haskell-tools = { + package = "mrcjkb/haskell-tools.nvim"; + dependencies.lua = [ "nvim-lua/plenary.nvim" ]; + version = "^2"; + + env.blacklist = [ "vscode" ]; + ft = [ "haskell" "lhaskell" "cabal" "cabalproject" ]; + + setup.vim.g.haskell_tools = { + hls = { + on_attach = nlib.lua /* lua */ ''require("my.plugins.lspconfig").on_attach''; + 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; + }; + }; + # }}} + # {{{ rust + # {{{ rust-tools + satellite.neovim.lazy.rust-tools = { + package = "simrat39/rust-tools.nvim"; + + env.blacklist = [ "vscode" ]; + ft = "rust"; + + opts.server.on_attach = nlib.languageServerOnAttach { + keys = { + mapping = "lc"; + action = "RustOpenCargo"; + desc = "Open [c]argo.toml"; + }; + }; + }; + # }}} + # {{{ crates + satellite.neovim.lazy.crates = { + package = "saecki/crates.nvim"; + dependencies.lua = [ "nvim-lua/plenary.nvim" ]; + + env.blacklist = [ "vscode" ]; + event = "BufReadPost Cargo.toml"; + + # {{{ Set up null_ls source + opts.null_ls = { + enabled = true; + name = "crates"; + }; + # }}} + + setup.autocmds = [ + # {{{ Load cmp source on insert + { + event = "InsertEnter"; + group = "CargoCmpSource"; + pattern = "Cargo.toml"; + callback = nlib.thunkString /* lua */ '' + require("cmp").setup.buffer({ sources = { { name = "crates" } } }) + ''; + } + # }}} + # {{{ Load keybinds on attach + { + event = "BufReadPost"; + group = "CargoKeybinds"; + pattern = "Cargo.toml"; + # {{{ Register which-key info + callback.callback = nlib.contextThunk /* lua */ '' + require("which-key").register({ + ["lc"] = { + name = "[l]ocal [c]rates", + bufnr = context.bufnr + }, + }) + ''; + # }}} + + callback.keys = + let + # {{{ Keymap helpers + keymap = mapping: action: desc: { + inherit mapping desc; + action = nlib.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") + ]; + # }}} + } + # }}} + ]; + }; + # }}} + # }}} + # }}} + # }}} } diff --git a/home/features/neovim/plugins/clipboard-image.lua b/home/features/neovim/plugins/clipboard-image.lua new file mode 100644 index 0000000..2922ce2 --- /dev/null +++ b/home/features/neovim/plugins/clipboard-image.lua @@ -0,0 +1,15 @@ +local M = {} + +function M.img_name() + vim.fn.inputsave() + local name = vim.fn.input("Name: ") + vim.fn.inputrestore() + + if name == nil or name == "" then + return os.date("%y-%m-%d-%H-%M-%S") + end + + return name +end + +return M diff --git a/home/tethys.nix b/home/tethys.nix index c4a05ca..bf7e2c1 100644 --- a/home/tethys.nix +++ b/home/tethys.nix @@ -27,7 +27,7 @@ # {{{ Editors for different formats gimp # Image editing lmms # Music software - kicad # PCB editing + # kicad # PCB editing libreoffice # Free office suite # }}} # {{{ Gaming @@ -41,7 +41,7 @@ obsidian # Notes peek # GIF recorder mpv # Video player - plover.dev # steno engine + # plover.dev # steno engine qbittorrent # Torrent client # google-chrome # Not my primary browser, but sometimes needed in webdev # obs-studio # video recorder diff --git a/modules/common/neovim.nix b/modules/common/neovim.nix index b4cd745..a24ffec 100644 --- a/modules/common/neovim.nix +++ b/modules/common/neovim.nix @@ -1,4 +1,5 @@ -# Additional theming primitives not provided by stylix +# This module provides personalised helpers for managing plugins +# using lazy.nvim and a set of custom runtime primitives. { pkgs, lib, config, ... }: let inherit (lib) types; @@ -7,22 +8,24 @@ let # {{{ Custom types myTypes = { - zeroOrMore = t: types.nullOr (types.either t (types.listOf t)); + oneOrMany = t: types.either t (types.listOf t); + zeroOrMore = t: types.nullOr (myTypes.oneOrMany t); + # {{{ Lua code luaCode = types.nullOr (types.oneOf [ types.str types.path myTypes.luaLiteral ]); - luaLiteral = types.submodule (_: { + luaLiteral = types.submodule { options.__luaEncoderTag = lib.mkOption { type = types.enum [ "lua" ]; }; options.value = lib.mkOption { type = types.str; }; - }); + }; luaValue = types.nullOr (types.oneOf [ types.str @@ -31,12 +34,12 @@ let (types.attrsOf myTypes.luaValue) (types.listOf myTypes.luaValue) ]); - - # {{{ Key type + # }}} + # {{{ Lazy key lazyKey = types.oneOf [ types.str (types.submodule - (_: { + { options.mapping = lib.mkOption { type = types.str; description = "The lhs of the neovim mapping"; @@ -67,11 +70,151 @@ let type = types.nullOr types.str; description = "Description for the current keymapping"; }; - })) + }) ]; # }}} - # {{{ Lazy module type - lazyModule = lib.fix (lazyModule: types.submodule (_: { + # {{{ Tempest key + tempestKey = types.submodule { + options = { + mapping = lib.mkOption { + example = "a"; + type = types.str; + description = "The lhs of the neovim mapping"; + }; + + action = lib.mkOption { + example = ""; + type = types.either types.str myTypes.luaLiteral; + description = "The rhs of the neovim mapping"; + }; + + bufnr = lib.mkOption { + default = null; + example = true; + type = types.nullOr + (types.oneOf [ + types.bool + types.integer + myTypes.luaLiteral + ]); + description = '' + The index of the buffer to apply local keymaps to. Can be set to + `true` to refer to the current buffer + ''; + }; + + mode = lib.mkOption { + default = null; + example = "nov"; + type = types.nullOr types.str; + description = "The vim modes the mapping should take effect in"; + }; + + silent = lib.mkOption { + default = null; + example = true; + type = types.nullOr types.bool; + description = "Whether the logs emitted by the keymap should be supressed"; + }; + + expr = lib.mkOption { + default = null; + example = true; + type = types.nullOr types.bool; + description = "If set to `true`, the mapping is treated as an action factory"; + }; + + desc = lib.mkOption { + default = null; + type = types.nullOr types.str; + description = "Description for the current keymapping"; + }; + }; + }; + # }}} + # {{{ Tempest autocmd + tempestAutocmd = types.submodule { + options = { + event = lib.mkOption { + example = "InsertEnter"; + type = myTypes.oneOrMany types.str; + description = "Events to bind autocmd to"; + }; + + pattern = lib.mkOption { + example = "Cargo.toml"; + type = myTypes.oneOrMany types.str; + description = "File name patterns to run autocmd on"; + }; + + group = lib.mkOption { + example = "CargoCmpSource"; + type = types.str; + description = "Name of the group to create and assign autocmd to"; + }; + + callback = lib.mkOption { + example.vim.opt.cmdheight = 1; + type = types.oneOf [ + myTypes.tempestConfiguration + myTypes.luaCode + ]; + description = '' + Code to run when the respctive event occurs. Will pass the event + object as context, which might be used for things like assigning + a buffer number to local keymaps automatically. + ''; + }; + }; + }; + # }}} + # {{{ Tempest configuration + tempestConfiguration = types.submodule { + options = { + vim = lib.mkOption { + default = null; + type = myTypes.luaValue; + example.opt.cmdheight = 0; + description = "Values to assign to the `vim` lua global object"; + }; + + keys = lib.mkOption { + default = null; + type = myTypes.zeroOrMore myTypes.tempestKey; + description = '' + Arbitrary key mappings to create. The keymappings might + automatically be buffer specific depending on the context. For + instance, keymappings created inside autocmds will be local unless + otherwise specified. + ''; + }; + + autocmds = lib.mkOption { + default = null; + type = myTypes.zeroOrMore myTypes.tempestAutocmd; + description = "Arbitrary autocmds to create"; + }; + + setup = lib.mkOption { + default = null; + type = types.nullOr (types.attrsOf myTypes.luaValue); + example.lualine.opts.theme = "auto"; + description = '' + Key-pair mappings for options to pass to .setup functions imported + from different modules + ''; + }; + + callback = lib.mkOption { + default = null; + type = types.nullOr myTypes.luaCode; + description = "Arbitrary code to run after everything else has been configured"; + }; + }; + }; + # }}} + # {{{ Lazy module + lazyModule = lib.fix (lazyModule: types.submodule ({ name ? null, ... }: { options = { package = lib.mkOption { type = types.oneOf [ @@ -83,7 +226,7 @@ let }; name = lib.mkOption { - default = null; + default = name; type = types.nullOr types.str; description = "Custom name to use for the module"; example = "lualine"; @@ -116,7 +259,7 @@ let dependencies.lua = lib.mkOption { default = [ ]; - type = types.listOf lazyModule; + type = types.listOf (types.either types.str lazyModule); description = "Lazy.nvim module dependencies"; }; @@ -132,12 +275,23 @@ let description = "Condition based on which to enable/disbale loading the package"; }; + env.blacklist = lib.mkOption { + default = [ ]; + type = types.listOf (types.enum [ "firenvim" "vscode" "neovide" ]); + description = "Environments to blacklist plugin on"; + }; + setup = lib.mkOption { default = null; - type = types.oneOf [ myTypes.luaCode types.bool ]; + type = types.nullOr (types.oneOf [ + myTypes.tempestConfiguration + myTypes.luaCode + types.bool + ]); description = '' Lua function (or module) to use for configuring the package. - Used instead of the canonically named `config` because said property has a special name in nix''; + Used instead of the canonically named `config` because said name has a special meaning in nix + ''; }; event = lib.mkOption { @@ -187,29 +341,41 @@ let }; # }}} # {{{ Lua encoders - mkRawLuaObject = chunks: - '' - { - ${lib.concatStringsSep "," (lib.filter (s: s != "") chunks)} - } - ''; - + # We provide a custom set of helpers for generating lua code for nix.enable + # # An encoder is a function from some nix value to a string containing lua code. # This object provides combinators for writing such encoders. luaEncoders = { + # {{{ "Raw" helpers + mkRawLuaObject = chunks: + '' + { + ${lib.concatStringsSep "," (lib.filter (s: s != "") chunks)} + } + ''; + # }}} # {{{ General helpers identity = given: given; + # `const` is mostly useful together with `bind`. See the lua encoder for + # lazy modules for example usage. + const = code: _: code; + # Conceptually, this is the monadic bind operation for encoders. + # This implementation is isomoprhic to that of the reader monad in haskell. bind = encoder: given: encoder given given; + # This is probably the most useful combinnator defined in this entire object. + # Most of the combinators in the other categories are based on this. conditional = predicate: caseTrue: caseFalse: luaEncoders.bind (given: if predicate given then caseTrue else caseFalse); + # This is simply left-composition of functions map = f: encoder: given: encoder (f given); + # This is simply right-composition of functions + postmap = f: encoder: given: f (encoder given); + # This is mostly useful for debugging trace = message: luaEncoders.map (f: lib.traceSeq message (lib.traceVal f)); fail = mkMessage: v: builtins.throw (mkMessage v); - const = code: _: code; # }}} # {{{ Base types - # TODO: figure out escaping and whatnot - string = string: ''"${string}"''; + string = given: ''"${lib.escape ["\"" "\\"] (toString given)}"''; bool = bool: if bool then "true" else "false"; number = toString; nil = _: "nil"; @@ -217,6 +383,10 @@ let boolOr = luaEncoders.conditional lib.isBool luaEncoders.bool; numberOr = luaEncoders.conditional (e: lib.isFloat e || lib.isInt e) luaEncoders.number; nullOr = luaEncoders.conditional (e: e == null) luaEncoders.nil; + # We pipe a combinator which always fail through a bunch of + # `(thing)or : encoder -> encoder` functions, building up a combinator which + # can handle more and more kinds of values, until we eventually build up + # something that should be able to handle everything we throw at it. anything = lib.pipe (luaEncoders.fail (v: "Cannot figure out how to encode value ${builtins.toJSON v}")) [ (luaEncoders.attrsetOfOr luaEncoders.anything) (luaEncoders.listOfOr luaEncoders.anything) @@ -228,31 +398,43 @@ let ]; # }}} # {{{ Lua code - luaCode = tag: - luaEncoders.luaCodeOr - (luaEncoders.conditional lib.isPath - (path: "dofile(${luaEncoders.string path}).${tag}") - luaEncoders.identity); + # Tagged lua code can be combined with other combinators without worrying + # about conflicts regarding how strings are interpreted. luaCodeOr = luaEncoders.conditional (e: lib.isAttrs e && (e.__luaEncoderTag or null) == "lua") (obj: obj.value); + # This is the most rudimentary (and currently only) way of handling paths. + luaImportOr = tag: + luaEncoders.conditional lib.isPath + (path: "dofile(${luaEncoders.string path}).${tag}"); + # Accepts both tagged and untagged strings of lua code. + luaString = luaEncoders.luaCodeOr luaEncoders.identity; + # This simply combines the above combinators into one. + luaCode = tag: luaEncoders.luaImportOr tag luaEncoders.luaString; # }}} # {{{ Lists listOf = encoder: list: - mkRawLuaObject (lib.lists.map encoder list); - tryNonemptyList = encoder: luaEncoders.conditional - (l: l == [ ]) - luaEncoders.nil - (luaEncoders.listOf encoder); + luaEncoders.mkRawLuaObject (lib.lists.map encoder list); listOfOr = encoder: luaEncoders.conditional lib.isList (luaEncoders.listOf encoder); + # Returns nil when given empty lists + tryNonemptyList = encoder: luaEncoders.conditional + (l: l == [ ]) + luaEncoders.nil + (luaEncoders.listOf encoder); oneOrMany = encoder: luaEncoders.listOfOr encoder encoder; + # Can encode: + # - zero values as nil + # - one value as itself + # - multiple values as a list zeroOrMany = encoder: luaEncoders.nullOr (luaEncoders.oneOrMany encoder); + # Coerces non list values to lists of one element. oneOrManyAsList = encoder: luaEncoders.map (given: if lib.isList given then given else [ given ]) (luaEncoders.listOf encoder); + # Coerces lists of one element to said element. listAsOneOrMany = encoder: luaEncoders.map (l: if lib.length l == 1 then lib.head l else l) @@ -260,7 +442,7 @@ let # }}} # {{{ Attrsets attrsetOf = encoder: object: - mkRawLuaObject (lib.mapAttrsToList + luaEncoders.mkRawLuaObject (lib.mapAttrsToList (name: value: let result = encoder value; in @@ -270,7 +452,14 @@ let object ); attrsetOfOr = of: luaEncoders.conditional lib.isAttrs (luaEncoders.attrsetOf of); - attrset = noNils: listOrder: listSpec: spec: attrset: + # This is the most general combinator provided in this section. + # + # We accept: + # - a `noNils` flag which will automatically remove any nil properties + # - order of props that should be interpreted as list elements + # - spec of props that should be interpreted as list elements + # - record of props that should be interpreted as attribute props + attrset = noNils: listOrder: spec: attrset: let shouldKeep = given: if noNils then @@ -280,7 +469,7 @@ let listChunks = lib.lists.map (attr: - let result = listSpec.${attr} (attrset.${attr} or null); + let result = spec.${attr} (attrset.${attr} or null); in lib.optionalString (shouldKeep result) result ) @@ -289,17 +478,18 @@ let (attr: encoder: let result = encoder (attrset.${attr} or null); in - lib.optionalString (shouldKeep result) + lib.optionalString (!(lib.elem attr listOrder) && shouldKeep result) "${attr} = ${result}" ) spec; in - mkRawLuaObject (listChunks ++ objectChunks); + luaEncoders.mkRawLuaObject (listChunks ++ objectChunks); # }}} }; e = luaEncoders; # }}} + # {{{ Helpers # Format and write a lua file to disk writeLuaFile = path: name: text: let @@ -312,18 +502,21 @@ let cp --no-preserve=mode ${unformatted} $out/${destination} ${lib.getExe pkgs.stylua} --config-path ${cfg.styluaConfig} $out/${destination} ''; + # }}} in { + # {{{ Option declaration options.satellite.neovim = { lazy = lib.mkOption { default = { }; - description = "Record of persistent locations (eg: /persist)"; + description = "Record of plugins to install using lazy.nvim"; type = types.attrsOf myTypes.lazyModule; }; + # {{{ Generated generated = { lazy = lib.mkOption { - type = types.attrsOf (types.submodule (_: { + type = types.attrsOf (types.submodule { options = { raw = lib.mkOption { type = types.lines; @@ -335,7 +528,7 @@ in description = "The lua script generated using the other options"; }; }; - })); + }); description = "Attrset containing every module generated from the lazy configuration"; }; @@ -351,8 +544,10 @@ in description = "List of packages to give neovim access to"; }; }; - + # }}} + # {{{ Lua generation lib lib = { + # {{{ Basic lua generators lua = lib.mkOption { default = value: { inherit value; __luaEncoderTag = "lua"; }; type = types.functionTo myTypes.luaLiteral; @@ -364,67 +559,166 @@ in type = types.functionTo (types.functionTo myTypes.luaLiteral); description = "import some identifier from some module"; }; + # }}} + # {{{ Encoders + encode = lib.mkOption { + default = luaEncoders.anything; + type = types.functionTo types.str; + description = "Encode a nix value to a lua string"; + }; - blacklistEnv = lib.mkOption { - default = given: cfg.lib.lua '' - require(${e.string cfg.env.module}).blacklist(${e.listOf e.string given}) + encodeTempestConfiguration = lib.mkOption { + default = given: + e.attrset true [ ] + { + vim = e.anything; + callback = e.nullOr e.luaString; + setup = e.nullOr (e.attrsetOf e.anything); + keys = e.zeroOrMany (e.attrset true [ ] { + mapping = e.string; + action = e.luaCodeOr e.string; + desc = e.nullOr e.string; + expr = e.nullOr e.bool; + mode = e.nullOr e.string; + silent = e.nullOr e.bool; + buffer = e.nullOr (e.luaCodeOr (e.boolOr e.number)); + }); + autocmds = e.zeroOrMany (e.attrset true [ ] { + event = e.oneOrMany e.string; + pattern = e.oneOrMany e.string; + group = e.string; + callback = e.conditional lib.isAttrs + cfg.lib.encodeTempestConfiguration + e.luaString; + }); + } + given; + type = types.functionTo types.str; + description = "Generate a lua object for passing to my own lua runtime for configuration"; + }; + # }}} + # {{{ Thunks + # This version of `nlib.thunk` is required in ceratain cases because + # of issues with `types.oneOf [types.submodule ..., types.submodule]` not + # working as intended atm. + thunkString = lib.mkOption { + default = given: /* lua */ '' + function() ${e.luaString given} end ''; - type = types.functionTo myTypes.luaLiteral; - description = "Generate a lazy.cond predicate which disables a module if one of the given envs is active"; + type = types.functionTo types.str; + description = "Wrap a lua expression into a lua function as a string"; }; thunk = lib.mkOption { - default = given: cfg.lib.lua '' - function() return ${given} end - ''; + default = given: cfg.lib.lua (cfg.lib.thunkString given); type = types.functionTo myTypes.luaLiteral; description = "Wrap a lua expression into a lua function"; }; - }; - env = { - module = lib.mkOption { + + contextThunk = lib.mkOption { + default = given: cfg.lib.lua /* lua */ '' + function(context) ${e.luaString given} end + ''; + type = types.functionTo myTypes.luaLiteral; + description = "Wrap a lua expression into a lua function taking an argument named `context`"; + }; + # }}} + # {{{ Language server on attach + languageServerOnAttach = lib.mkOption { + default = given: cfg.lib.lua /* lua */ '' + function(client, bufnr) + require(${e.string cfg.runtime.tempest}).configure(${cfg.lib.encodeTempestConfiguration given}, + { client = client; bufnr = bufnr; }) + + require(${e.string cfg.runtime.languageServerOnAttach}).on_attach(client, bufnr) + end + ''; + type = types.functionTo myTypes.luaCode; + description = "Attach a language server and run some additional code"; + }; + # }}} + }; + # }}} + # {{{ Neovim runtime module paths + runtime = { + env = lib.mkOption { type = types.str; example = "my.helpers.env"; - description = "Module where to import env flags from"; + description = "Module to import env flags from"; + }; + + tempest = lib.mkOption { + type = types.str; + example = "my.runtime.tempest"; + description = "Module to import the tempest runtime from"; + }; + + languageServerOnAttach = lib.mkOption { + type = types.str; + example = "my.runtime.lspconfig"; + description = "Module to import langauge server .on_attach function from"; }; }; + # }}} styluaConfig = lib.mkOption { type = types.path; description = "Config to use for formatting lua modules"; }; }; - + # }}} + # {{{ Config generation + # {{{ Lazy module generation config.satellite.neovim.generated.lazy = let + # {{{ Lazy key encoder lazyKeyEncoder = - e.stringOr (e.attrset true [ "mapping" "action" ] - { - mapping = e.string; - action = e.nullOr (e.luaCodeOr e.string); - } - { - mode = e.nullOr - (e.map - lib.strings.stringToCharacters - (e.listAsOneOrMany e.string)); - desc = e.nullOr e.string; - ft = e.zeroOrMany e.string; - }); - + e.stringOr (e.attrset true [ "mapping" "action" ] { + mapping = e.string; + action = e.nullOr (e.luaCodeOr e.string); + mode = e.nullOr + (e.map + lib.strings.stringToCharacters + (e.listAsOneOrMany e.string)); + desc = e.nullOr e.string; + ft = e.zeroOrMany e.string; + }); + # }}} + # {{{ Lazy spec encoder lazyObjectEncoder = e.bind (opts: e.attrset true [ "package" ] - { package = e.string; } { + package = e.string; name = e.nullOr e.string; main = e.nullOr e.string; tag = e.nullOr e.string; version = e.nullOr e.string; - dependencies = e.map (d: d.lua) (e.tryNonemptyList lazyObjectEncoder); + dependencies = e.map (d: d.lua) (e.tryNonemptyList (e.stringOr lazyObjectEncoder)); lazy = e.nullOr e.bool; - cond = e.nullOr (e.luaCode "cond"); - config = e.const (e.nullOr (e.boolOr (e.luaCode "config")) opts.setup); + cond = + if opts.env.blacklist != [ ] then + assert lib.asserts.assertMsg (opts.cond == null) + "env.blacklist overrides plugin condition"; + e.const /* lua */ '' + require(${e.string cfg.runtime.env}).blacklist(${e.listOf e.string opts.env.blacklist}) + '' + else + e.nullOr (e.luaCode "cond"); + + config = _: + let + wrap = given: /* lua */'' + function(lazy, opts) + require(${e.string cfg.runtime.tempest}).configure(${given}, + { lazy = lazy; opts = opts; }) + end + ''; + in + e.conditional lib.isAttrs + (e.postmap wrap cfg.lib.encodeTempestConfiguration) + (e.nullOr (e.boolOr (e.luaCode "config"))) + opts.setup; init = e.nullOr (e.luaCode "init"); event = e.zeroOrMany e.string; cmd = e.zeroOrMany e.string; @@ -433,9 +727,10 @@ in passthrough = e.anything; opts = e.anything; }); + # }}} makeLazyScript = opts: '' - -- This file was generated by nix + -- ❄️ This file was generated using nix ^~^ return ${lazyObjectEncoder opts} ''; in @@ -451,12 +746,15 @@ in name = "lazy-nvim-modules"; paths = lib.attrsets.mapAttrsToList (_: m: m.module) cfg.generated.lazy; }; + # }}} config.satellite.neovim.generated.dependencies = lib.pipe cfg.lazy [ (lib.attrsets.mapAttrsToList (_: m: m.dependencies.nix)) lib.lists.flatten - ] - ; + ]; + # }}} } + + diff --git a/overlays/default.nix b/overlays/default.nix index 5e9b0ed..4055913 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -11,7 +11,7 @@ # }); # {{{ Discordchatexporter - discordchatexporter-cli = prev.discordchatexporter-cli.overrideAttrs (_: rec { + discordchatexporter-cli = prev.discordchatexporter-cli.overrideAttrs (_: { version = "unstable-2023-06-21"; src = prev.fetchFromGitHub { owner = "tyrrrz";