From 445c5965c655eb5f365c7ae317d2d350c6a08bf0 Mon Sep 17 00:00:00 2001 From: Matei Adriel Date: Sat, 2 Dec 2023 12:16:33 +0100 Subject: [PATCH] Move more nvim modules to nix --- home/features/neovim/config/lazy-lock.json | 5 +- .../neovim/config/lua/my/helpers/env.lua | 16 +- .../neovim/config/lua/my/plugins/flash.lua | 36 ---- .../neovim/config/lua/my/plugins/lualine.lua | 32 --- home/features/neovim/default.nix | 74 ++++++- modules/common/neovim.nix | 197 +++++++++++++----- 6 files changed, 239 insertions(+), 121 deletions(-) delete mode 100644 home/features/neovim/config/lua/my/plugins/flash.lua delete mode 100644 home/features/neovim/config/lua/my/plugins/lualine.lua diff --git a/home/features/neovim/config/lazy-lock.json b/home/features/neovim/config/lazy-lock.json index c89aea3..1e85622 100644 --- a/home/features/neovim/config/lazy-lock.json +++ b/home/features/neovim/config/lazy-lock.json @@ -13,7 +13,7 @@ "dhall-vim": { "branch": "master", "commit": "68500ef46ff3706f46c99db3be7a0c8abcf6a3ae" }, "dressing.nvim": { "branch": "master", "commit": "6bde51adabba06f7fd4a469885a85f36d78a5f52" }, "fidget.nvim": { "branch": "main", "commit": "0ba1e16d07627532b6cae915cc992ecac249fb97" }, - "flash.nvim": { "branch": "main", "commit": "967117690bd677cb7b6a87f0bc0077d2c0be3a27" }, + "flash": { "branch": "main", "commit": "48817af25f51c0590653bbc290866e4890fe1cbe" }, "formatter.nvim": { "branch": "master", "commit": "44c89f09dcc220dc2a9b056e93c3a87c86e79804" }, "github-actions-yaml.vim": { "branch": "master", "commit": "f2f16243447cea174daa6b4a9ffd3ff9213814ef" }, "gitlinker.nvim": { "branch": "master", "commit": "cc59f732f3d043b626c8702cb725c82e54d35c25" }, @@ -31,7 +31,7 @@ "lean.nvim": { "branch": "main", "commit": "67580fab5bed73920fa3fdd712fc8e805c389c3d" }, "live-command.nvim": { "branch": "main", "commit": "d460067d47948725a6f25b20f31ea8bbfdfe4622" }, "lspkind.nvim": { "branch": "master", "commit": "57610d5ab560c073c465d6faf0c19f200cb67e6e" }, - "lualine.nvim": { "branch": "master", "commit": "45e27ca739c7be6c49e5496d14fcf45a303c3a63" }, + "lualine": { "branch": "master", "commit": "2248ef254d0a1488a72041cfb45ca9caada6d994" }, "magma-nvim": { "branch": "main", "commit": "ff3deba8a879806a51c005e50782130246143d06" }, "mini.files": { "branch": "main", "commit": "dea80a8147aa4e3025c34d2e2aaa6f2aeb7b21dd" }, "mini.operators": { "branch": "main", "commit": "15f137f28412517e2248d39cf0663bd3a87aa24a" }, @@ -72,5 +72,6 @@ "vim-wakatime": { "branch": "master", "commit": "018fa9a80c27ccf2a8967b9e27890372e5c2fb4f" }, "vimux": { "branch": "master", "commit": "616fcb4799674a7a809b14ca2dc155bb6ba25788" }, "which-key.nvim": { "branch": "main", "commit": "7ccf476ebe0445a741b64e36c78a682c1c6118b7" }, + "winbar": { "branch": "main", "commit": "13739fdb31be51a1000486189662596f07a59a31" }, "yuck.vim": { "branch": "master", "commit": "9b5e0370f70cc30383e1dabd6c215475915fe5c3" } } \ No newline at end of file diff --git a/home/features/neovim/config/lua/my/helpers/env.lua b/home/features/neovim/config/lua/my/helpers/env.lua index ba3756f..e5807a9 100644 --- a/home/features/neovim/config/lua/my/helpers/env.lua +++ b/home/features/neovim/config/lua/my/helpers/env.lua @@ -2,7 +2,7 @@ local function makeEnv(cond) return { -- I am doing this to get type hints! active = function() - return cond + return cond() end, not_active = function() return not cond() @@ -20,7 +20,7 @@ local function makeEnv(cond) } end -return { +local M = { vscode = makeEnv(function() return vim.g.vscode ~= nil end), @@ -41,3 +41,15 @@ return { end) end, } + +M.blacklist = function(list) + for _, key in pairs(list) do + if M[key].active() then + return false + end + end + + return true +end + +return M diff --git a/home/features/neovim/config/lua/my/plugins/flash.lua b/home/features/neovim/config/lua/my/plugins/flash.lua deleted file mode 100644 index 2462a75..0000000 --- a/home/features/neovim/config/lua/my/plugins/flash.lua +++ /dev/null @@ -1,36 +0,0 @@ -local function keybind(keys, action, desc, modes) - if modes == nil then - modes = { "n", "x", "o" } - end - - return { - keys, - mode = modes, - function() - require("flash")[action]() - end, - desc = desc, - } -end - -local M = { - "folke/flash.nvim", - event = "VeryLazy", - ---@type Flash.Config - opts = { - modes = { - char = { - enabled = false, - }, - }, - }, - keys = { - keybind("s", "jump", "Flash"), - keybind("S", "treesitter", "Flash Treesitter"), - keybind("r", "remote", "Remote Flash", { "o" }), - keybind("R", "treesitter_search", "Treesitter Search", { "o", "x" }), - keybind("", "toggle", "Toggle Flash Search", { "c" }), - }, -} - -return M diff --git a/home/features/neovim/config/lua/my/plugins/lualine.lua b/home/features/neovim/config/lua/my/plugins/lualine.lua deleted file mode 100644 index 8f40349..0000000 --- a/home/features/neovim/config/lua/my/plugins/lualine.lua +++ /dev/null @@ -1,32 +0,0 @@ -local env = require("my.helpers.env") - -local M = { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - cond = env.vscode.not_active() and env.firenvim.not_active(), -} - -function M.config() - require("lualine").setup({ - options = { - component_separators = { left = "", right = "" }, - section_separators = { left = "", right = "" }, - theme = "auto", - disabled_filetypes = { - "undotree", - }, - }, - sections = { - lualine_a = { "branch" }, - lualine_b = { "filename" }, - lualine_c = { "filetype" }, - lualine_x = { "diagnostics" }, - lualine_y = {}, - lualine_z = {}, - }, - -- Integration with other plugins - extensions = { "nvim-tree" }, - }) -end - -return M diff --git a/home/features/neovim/default.nix b/home/features/neovim/default.nix index a314e8f..6b6b2d0 100644 --- a/home/features/neovim/default.nix +++ b/home/features/neovim/default.nix @@ -144,6 +144,8 @@ let extraArgs = "--set GIT_DISCOVERY_ACROSS_FILESYSTEM 1"; }; # }}} + + nlib = config.satellite.neovim.lib; in { # {{{ Basic config @@ -208,12 +210,82 @@ in # }}} # {{{ Custom module testing satellite.neovim.styluaConfig = ../../../stylua.toml; + satellite.neovim.env.module = "my.helpers.env"; + + # {{{ Nvim-tree satellite.neovim.lazy.nvim-tree = { - setup = true; package = "kyazdani42/nvim-tree.lua"; + setup = true; keys.mapping = ""; keys.desc = "Toggle [n]vim-tree"; keys.action = "NvimTreeToggle"; + cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; }; # }}} + # {{{ Lualine + satellite.neovim.lazy.lualine = { + package = "nvim-lualine/lualine.nvim"; + name = "lualine"; + + cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; + event = "VeryLazy"; + + opts = { + options = { + component_separators = { left = ""; right = ""; }; + section_separators = { left = ""; right = ""; }; + theme = "auto"; + disabled_filetypes = [ "undotree" ]; + }; + + sections = { + lualine_a = [ "branch" ]; + lualine_b = [ "filename" ]; + lualine_c = [ "filetype" ]; + lualine_x = [ "diagnostics" "diff" ]; + lualine_y = [ ]; + lualine_z = [ ]; + }; + + # Integration with other plugins + extensions = [ "nvim-tree" ]; + }; + }; + # }}} + # {{{ Winbar + satellite.neovim.lazy.winbar = { + package = "fgheng/winbar.nvim"; + name = "winbar"; + + cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; + event = "VeryLazy"; + + opts.enabled = true; + }; + # }}} + # {{{ Flash + satellite.neovim.lazy.flash = { + package = "folke/flash.nvim"; + name = "flash"; + + cond = nlib.blacklistEnv [ "vscode" "firenvim" ]; + keys = + let keybind = mode: mapping: action: desc: { + inherit mapping desc mode; + action = nlib.lua ''function () require("flash").${action}() end''; + }; + 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; + }; + # }}} + # }}} } diff --git a/modules/common/neovim.nix b/modules/common/neovim.nix index 8e60d0e..fd97414 100644 --- a/modules/common/neovim.nix +++ b/modules/common/neovim.nix @@ -10,6 +10,24 @@ let luaCode = types.nullOr (types.oneOf [ types.str types.path + myTypes.luaLiteral + ]); + + 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 + types.number + types.bool + (types.attrsOf myTypes.luaValue) + (types.listOf myTypes.luaValue) ]); fileTypes = types.nullOr (types.oneOf [ @@ -27,7 +45,10 @@ let }; options.action = lib.mkOption { - type = types.str; + type = types.nullOr (types.oneOf [ + types.str + myTypes.luaLiteral + ]); }; options.ft = lib.mkOption { @@ -38,8 +59,7 @@ let options.mode = lib.mkOption { default = null; - # Only added the types I'm using in my config atm - type = types.nullOr (types.enum [ "n" "v" ]); + type = types.nullOr types.str; }; options.desc = lib.mkOption { @@ -61,6 +81,20 @@ let example = "nvim-telescope/telescope.nvim"; }; + name = lib.mkOption { + default = null; + type = types.nullOr types.str; + description = "Custom name to use for the module"; + example = "lualine"; + }; + + main = lib.mkOption { + default = null; + type = types.nullOr types.str; + description = "The name of the lua entrypoint for the plugin (usually auto-detected)"; + example = "lualine"; + }; + version = lib.mkOption { default = null; type = types.nullOr types.str; @@ -130,6 +164,12 @@ let description = "Attach additional things to the lazy module"; }; + opts = lib.mkOption { + default = null; + type = myTypes.luaValue; + description = "Custom data to pass to the plugin .setup function"; + }; + keys = lib.mkOption { default = null; type = @@ -138,8 +178,6 @@ let (types.listOf myTypes.lazyKey) ]); }; - - opts = { }; }; })); # }}} @@ -162,38 +200,72 @@ let conditional = predicate: caseTrue: caseFalse: luaEncoders.bind (given: if predicate given then caseTrue else caseFalse); map = f: encoder: given: encoder (f given); - trace = message: luaEncoders.map (f: lib.traceSeq message f); + 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}"''; bool = bool: if bool then "true" else "false"; + number = toString; nil = _: "nil"; stringOr = luaEncoders.conditional lib.isString luaEncoders.string; 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; + anything = lib.pipe (luaEncoders.fail (v: "Cannot figure out how to encode value ${builtins.toJSON v}")) [ + luaEncoders.luaCodeOr + luaEncoders.nullOr + luaEncoders.boolOr + luaEncoders.numberOr + luaEncoders.stringOr + (luaEncoders.listOfOr luaEncoders.anything) + (luaEncoders.attrsetOfOr luaEncoders.anything) + ]; # }}} - # {{{ Advanced types + # {{{ Lua code luaCode = tag: - luaEncoders.conditional lib.isPath - (path: "require(${path}).${tag}") - luaEncoders.identity; - + luaEncoders.luaCodeOr + (luaEncoders.conditional lib.isPath + (path: "dofile(${luaEncoders.string path}).${tag}") + luaEncoders.identity); + luaCodeOr = + luaEncoders.conditional (e: lib.isAttrs e && (e.__luaEncoderTag or null) == "lua") + (obj: obj.value); + # }}} + # {{{ Lists listOf = encoder: list: mkRawLuaObject (lib.lists.map encoder list); tryNonemptyList = encoder: luaEncoders.conditional (l: l == [ ]) luaEncoders.nil (luaEncoders.listOf encoder); - oneOrMany = encoder: + listOfOr = encoder: luaEncoders.conditional lib.isList - (luaEncoders.listOf encoder) - encoder; + (luaEncoders.listOf encoder); + oneOrMany = encoder: luaEncoders.listOfOr encoder encoder; oneOrManyAsList = encoder: luaEncoders.map (given: if lib.isList given then given else [ given ]) (luaEncoders.listOf encoder); - + listAsOneOrMany = encoder: + luaEncoders.map + (l: if lib.length l == 1 then lib.head l else l) + (luaEncoders.oneOrMany encoder); + # }}} + # {{{ Attrsets + attrsetOf = encoder: object: + mkRawLuaObject (lib.mapAttrsToList + (name: value: + let result = encoder value; + in + lib.optionalString (result != "nil") + "${name} = ${result}" + ) + object + ); + attrsetOfOr = of: luaEncoders.conditional lib.isAttrs (luaEncoders.attrsetOf of); attrset = noNils: listOrder: listSpec: spec: attrset: let shouldKeep = given: @@ -224,7 +296,6 @@ let e = luaEncoders; # }}} - # Format and write a lua file to disk writeLuaFile = path: name: text: let @@ -246,27 +317,59 @@ in type = types.attrsOf myTypes.lazyModule; }; - generated.lazy = lib.mkOption { - type = types.attrsOf (types.submodule (_: { - options = { - raw = lib.mkOption { - type = types.lines; - description = "The lua script generated using the other options"; - }; + generated = { + lazy = lib.mkOption { + type = types.attrsOf (types.submodule (_: { + options = { + raw = lib.mkOption { + type = types.lines; + description = "The lua script generated using the other options"; + }; - module = lib.mkOption { - type = types.package; - description = "The lua script generated using the other options"; + module = lib.mkOption { + type = types.package; + description = "The lua script generated using the other options"; + }; }; - }; - })); - description = "Attrset containing every module generated from the lazy configuration"; + })); + description = "Attrset containing every module generated from the lazy configuration"; + }; + + all = lib.mkOption { + default = { }; + type = types.package; + description = "Derivation building all the given nix modules"; + }; }; - generated.all = lib.mkOption { - default = { }; - type = types.package; - description = "Derivation building all the given nix modules"; + lib = { + lua = lib.mkOption { + default = value: { inherit value; __luaEncoderTag = "lua"; }; + type = types.functionTo myTypes.luaLiteral; + description = "include some raw lua code inside module configuration"; + }; + + import = lib.mkOption { + default = path: tag: cfg.lib.lua "dofile(${e.string path}).${tag}"; + type = types.functionTo (types.functionTo myTypes.luaLiteral); + description = "import some identifier from some module"; + }; + + blacklistEnv = lib.mkOption { + default = given: cfg.lib.lua '' + require(${e.string cfg.env.module}).blacklist(${e.listOf e.string given}) + ''; + type = types.functionTo myTypes.luaLiteral; + description = "Generate a lazy.cond predicate which disables a module if one of the given envs is active"; + }; + }; + + env = { + module = lib.mkOption { + type = types.str; + example = "my.helpers.env"; + description = "Module where to import env flags from"; + }; }; styluaConfig = lib.mkOption { @@ -281,37 +384,35 @@ in e.stringOr (e.attrset true [ "mapping" "action" ] { mapping = e.string; - action = e.nullOr e.string; + action = e.nullOr (e.luaCodeOr e.string); } { - mode = e.nullOr e.string; + mode = e.nullOr + (e.map + lib.strings.stringToCharacters + (e.listAsOneOrMany e.string)); desc = e.nullOr e.string; ft = e.nullOr (e.oneOrMany e.string); }); - renameKey = from: to: lib.mapAttrs' (name: value: - if name == from then { inherit value; name = to; } - else { inherit name value; }); - - - lazyObjectEncoder = e.map (renameKey "setup" "config") - (e.attrset true [ "package" ] - { - package = e.string; - } + lazyObjectEncoder = e.bind + (opts: e.attrset true [ "package" ] + { 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); lazy = e.nullOr e.bool; - # TODO: add sugar for enabling/disabling under certain envs cond = e.nullOr (e.luaCode "cond"); - config = e.nullOr (e.boolOr (e.luaCode "config")); + config = e.const (e.nullOr (e.boolOr (e.luaCode "config")) opts.setup); init = e.nullOr (e.luaCode "init"); event = e.nullOr (e.oneOrMany e.string); ft = e.nullOr (e.oneOrMany e.string); keys = e.nullOr (e.oneOrManyAsList lazyKeyEncoder); - # TODO: passthrough + passthrough = e.anything; + opts = e.anything; }); makeLazyScript = opts: ''