From 1b9f33157453aa6508743ec73913eb2b59f9a504 Mon Sep 17 00:00:00 2001 From: Quentin Boyer Date: Mon, 9 Dec 2024 21:06:14 +0100 Subject: [PATCH 1/2] modules/options: Allow to add code around the globals This will be used to implement `luaConfig` for plugins that use global variables for their configuration --- modules/opts.nix | 59 ++++++++++++++++++-------- tests/test-sources/modules/options.nix | 10 +++++ 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/modules/opts.nix b/modules/opts.nix index 4ca93d6356..985467bbc3 100644 --- a/modules/opts.nix +++ b/modules/opts.nix @@ -36,15 +36,29 @@ let }; in { - options = lib.mapAttrs ( - _: - { description, ... }: - lib.mkOption { - type = with lib.types; attrsOf anything; - default = { }; - inherit description; - } - ) optionsAttrs; + options = + (lib.mapAttrs ( + _: + { description, ... }: + lib.mkOption { + type = with lib.types; attrsOf anything; + default = { }; + inherit description; + } + ) optionsAttrs) + // { + globalsPre = lib.mkOption { + type = lib.types.lines; + default = ""; + internal = true; + }; + + globalsPost = lib.mkOption { + type = lib.types.lines; + default = ""; + internal = true; + }; + }; # Added 2024-03-29 (do not remove) imports = lib.mapAttrsToList (old: new: lib.mkRenamedOptionModule [ old ] [ new ]) { @@ -68,18 +82,27 @@ in let varName = "nixvim_${luaVariableName}"; optionDefinitions = helpers.toLuaObject config.${optionName}; + ifGlobals = lib.optionalString (optionName == "globals"); in - lib.optionalString (optionDefinitions != "{ }") '' - -- Set up ${prettyName} {{{ - do - local ${varName} = ${optionDefinitions} + lib.optionalString (optionDefinitions != "{ }") ( + '' + -- Set up ${prettyName} {{{ + '' + + (ifGlobals config.globalsPre) + + '' + do + local ${varName} = ${optionDefinitions} - for k,v in pairs(${varName}) do - vim.${luaApi}[k] = v + for k,v in pairs(${varName}) do + vim.${luaApi}[k] = v + end end - end - -- }}} - '' + '' + + (ifGlobals config.globalsPost) + + '' + -- }}} + '' + ) ) optionsAttrs ); in diff --git a/tests/test-sources/modules/options.nix b/tests/test-sources/modules/options.nix index 7866a87fa0..876f1e93de 100644 --- a/tests/test-sources/modules/options.nix +++ b/tests/test-sources/modules/options.nix @@ -23,10 +23,20 @@ }; globals = { + globalsPre = '' + dummy = 45 + ''; globals = { + with_pre.__raw = "dummy"; loaded_ruby_provider = 0; loaded_perl_provider = 0; loaded_python_provider = 0; }; + globalsPost = # lua + '' + if vim.g.with_pre ~= dummy then + print("Mismatch for vim.g.with_pre, expected " .. dummy .. " got " .. vim.g.with_pre) + end + ''; }; } From 3542fd56a61ad816971bff6f413439238fe2b86a Mon Sep 17 00:00:00 2001 From: Quentin Boyer Date: Mon, 9 Dec 2024 21:32:34 +0100 Subject: [PATCH 2/2] lib/vim-plugin: Add a luaConfig option similar to mkNeovimPlugin --- lib/neovim-plugin.nix | 2 +- lib/types.nix | 90 +++++++++++++---------- lib/vim-plugin.nix | 10 +++ tests/test-sources/plugins/lua-config.nix | 20 +++++ 4 files changed, 84 insertions(+), 38 deletions(-) diff --git a/lib/neovim-plugin.nix b/lib/neovim-plugin.nix index bbb5324b37..e8049837e3 100644 --- a/lib/neovim-plugin.nix +++ b/lib/neovim-plugin.nix @@ -123,7 +123,7 @@ } // lib.optionalAttrs hasConfigAttrs { luaConfig = lib.mkOption { - type = lib.types.pluginLuaConfig; + type = lib.types.pluginLuaConfig { hasContent = true; }; default = { }; description = "The plugin's lua configuration"; }; diff --git a/lib/types.nix b/lib/types.nix index 9a5e637b66..2a266df5c9 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -137,47 +137,63 @@ rec { }"; }; - pluginLuaConfig = types.submodule ( - { config, ... }: + pluginLuaConfig = + { hasContent }: let inherit (builtins) toString; inherit (lib.nixvim.utils) mkBeforeSection mkAfterSection; - in - { - options = { - pre = lib.mkOption { - type = with types; nullOr lines; - default = null; - description = '' - Lua code inserted at the start of the plugin's configuration. - This is the same as using `lib.nixvim.utils.mkBeforeSection` when defining `content`. - ''; - }; - post = lib.mkOption { - type = with types; nullOr lines; - default = null; - description = '' - Lua code inserted at the end of the plugin's configuration. - This is the same as using `lib.nixvim.utils.mkAfterSection` when defining `content`. - ''; - }; - content = lib.mkOption { - type = types.lines; - default = ""; - description = '' - Configuration of the plugin. - - If `pre` and/or `post` are non-null, they will be merged using the order priorities - ${toString (mkBeforeSection null).priority} and ${toString (mkBeforeSection null).priority} - respectively. - ''; + + commonModule = { + options = { + pre = lib.mkOption { + type = with types; nullOr lines; + default = null; + description = + '' + Lua code inserted at the start of the plugin's configuration. + '' + + lib.optionalString hasContent '' + This is the same as using `lib.nixvim.utils.mkBeforeSection` when defining `content`. + ''; + }; + post = lib.mkOption { + type = with types; nullOr lines; + default = null; + description = + '' + Lua code inserted at the end of the plugin's configuration. + '' + + lib.optionalString hasContent '' + This is the same as using `lib.nixvim.utils.mkAfterSection` when defining `content`. + ''; + }; }; }; - config.content = lib.mkMerge ( - lib.optional (config.pre != null) (mkBeforeSection config.pre) - ++ lib.optional (config.post != null) (mkAfterSection config.post) - ); - } - ); + contentModule = + { config, ... }: + { + options = { + content = lib.mkOption { + type = types.lines; + default = ""; + description = '' + Configuration of the plugin. + + If `pre` and/or `post` are non-null, they will be merged using the order priorities + ${toString (mkBeforeSection null).priority} and ${toString (mkBeforeSection null).priority} + respectively. + ''; + }; + }; + + config = { + content = lib.mkMerge ( + lib.optional (config.pre != null) (mkBeforeSection config.pre) + ++ lib.optional (config.post != null) (mkAfterSection config.post) + ); + }; + }; + in + types.submodule ([ commonModule ] ++ (lib.optional hasContent contentModule)); } diff --git a/lib/vim-plugin.nix b/lib/vim-plugin.nix index 2e564b4d1b..1bbad9606a 100644 --- a/lib/vim-plugin.nix +++ b/lib/vim-plugin.nix @@ -49,6 +49,12 @@ - `other_toggle = false` -> `:setglobal no${globalPrefix}other_toggle` ''; }; + + luaConfig = lib.mkOption { + type = lib.types.pluginLuaConfig { hasContent = false; }; + default = { }; + description = "The plugin's lua configuration"; + }; }; module = @@ -115,6 +121,10 @@ ]; globals = lib.mapAttrs' (n: lib.nameValuePair (globalPrefix + n)) (cfg.settings or { }); } + (lib.optionalAttrs createSettingsOption { + globalsPre = lib.nixvim.mkIfNonNull cfg.luaConfig.pre; + globalsPost = lib.nixvim.mkIfNonNull cfg.luaConfig.post; + }) (lib.optionalAttrs (isColorscheme && (colorscheme != null)) { colorscheme = lib.mkDefault colorscheme; }) diff --git a/tests/test-sources/plugins/lua-config.nix b/tests/test-sources/plugins/lua-config.nix index 54bbabd7b6..e0c1240d01 100644 --- a/tests/test-sources/plugins/lua-config.nix +++ b/tests/test-sources/plugins/lua-config.nix @@ -23,4 +23,24 @@ end ''; }; + lua-config-vim-plugin = { + plugins.typst-vim = { + enable = true; + luaConfig.pre = # lua + '' + local command = "typst-wrapped" -- Let's say we got it through env vars + ''; + settings.cmd.__raw = "command"; + luaConfig.post = # lua + '' + local globals_cmd = vim.g.typst_cmd + ''; + }; + + extraConfigLuaPost = '' + if globals_cmd ~= command then + print("globals_cmd different than command: " .. globals_cmd .. ", " .. command) + end + ''; + }; }