Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib/vim-plugin: Add support for luaConfig #2624

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/neovim-plugin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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";
};
Expand Down
90 changes: 53 additions & 37 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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));
MattSturgeon marked this conversation as resolved.
Show resolved Hide resolved
}
10 changes: 10 additions & 0 deletions lib/vim-plugin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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;
})
Comment on lines +124 to +127
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial reaction: I'm not a fan of this.

I don't think it makes sense to assign lua code to an option named "globals*".

(lib.optionalAttrs (isColorscheme && (colorscheme != null)) {
colorscheme = lib.mkDefault colorscheme;
})
Expand Down
59 changes: 41 additions & 18 deletions modules/opts.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
};
Comment on lines +49 to +61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the intention is that this is lua code injected pre/post the lua impl for the globals option.

But reading the option name I'd half-expect to be able to assign globals earlier or later than normal.

This feels like working around a poor design rather than an objective improvement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if instead, each plugin should be responsible for using vim.g[k] = itself. Perhaps within luaConfig.init ?

Yes, this would mean vim-plugins aren't taking advantage of the globals option, and consiquently end-users won't see the configured globals when inspecting the option's value. But perhaps that is worth it in order to locate the globals in a more predictable location?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another idea: Perhaps the luaConfig submodule could also be used for non-plugin modules too? E.g. we could have a globalsLuaConfig option, and move the lua impl to globalsLuaConfig.init?

(maybe rename init something like main, content, text, etc?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really a fan of any of the three solutions, tbh. So open to alternative proposals too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if instead, each plugin should be responsible for using vim.g[k] = itself. Perhaps within luaConfig.init ?

Yes, this would mean vim-plugins aren't taking advantage of the globals option, and consiquently end-users won't see the configured globals when inspecting the option's value. But perhaps that is worth it in order to locate the globals in a more predictable location?

I though about that, but I think setting the global options in nix is a bit better, as it allows to do more compile time stuff (though you could still do compile time stuff by accessing the plugin's settings)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another idea: Perhaps the luaConfig submodule could also be used for non-plugin modules too? E.g. we could have a globalsLuaConfig option, and move the lua impl to globalsLuaConfig.init?

(maybe rename init something like main, content, text, etc?)

There could be a use for it, for example to define helpers for keymaps, or options

Copy link
Contributor

@khaneliman khaneliman Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still like the global option interface being used, too. I guess I am not too sure of when a vim plugin would use it, though. Almost feels like we would start blending the mkNeovimPlugin and mkVimPlugin stuff together into one solution that has these arguments to declare what functionality and routing is done. Could just add an argument for whether its a vim or neovim plugin so that we can properly group things and/or gate defaults.


# Added 2024-03-29 (do not remove)
imports = lib.mapAttrsToList (old: new: lib.mkRenamedOptionModule [ old ] [ new ]) {
Expand All @@ -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
Expand Down
10 changes: 10 additions & 0 deletions tests/test-sources/modules/options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
'';
};
}
20 changes: 20 additions & 0 deletions tests/test-sources/plugins/lua-config.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
'';
};
}