Compare commits

...

3 commits

Author SHA1 Message Date
df14086eef
neovim/init: add autocommands API
Some checks failed
Check for typos in the source tree / check-typos (push) Has been cancelled
2025-02-06 16:36:54 +03:00
6b98217df8
diagnostics/nvim-lint: rough initial implementation 2025-02-06 12:28:49 +03:00
7d8e2f7669
formatter/conform-nvim: use listOf anything 2025-02-06 12:28:03 +03:00
5 changed files with 189 additions and 7 deletions

View file

@ -0,0 +1,152 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) submodule attrsOf listOf str bool;
inherit (lib.nvim.types) luaInline;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAfter;
autocommandType = submodule {
options = {
enable =
mkEnableOption ""
// {
default = true;
description = "Whether to enable this autocommand";
};
event = mkOption {
type = listOf str;
example = ["BufRead" "BufWritePre"];
description = "The event(s) that trigger the autocommand.";
};
pattern = mkOption {
type = listOf str;
example = ["*.lua" "*.vim"];
description = "The file pattern(s) that determine when the autocommand applies).";
};
callback = mkOption {
type = luaInline;
example = ''
function()
print("Saving a Lua file...")
end,
'';
description = "The file pattern(s) that determine when the autocommand applies).";
};
command = mkOption {
type = str;
description = "Vim command string instead of a Lua function.";
};
group = mkOption {
type = str;
example = "MyAutoCmdGroup";
description = "An optional autocommand group to manage related autocommands.";
};
desc = mkOption {
type = str;
example = "Notify when saving a Lua file";
description = "A description for the autocommand.";
};
once = mkOption {
type = bool;
default = false;
description = "Whether autocommand run only once.";
};
nested = mkOption {
type = bool;
default = false;
description = "Whether to allow nested autocommands to trigger.";
};
};
};
autogroupType = submodule {
options = {
name = mkOption {
type = str;
example = "MyAutoCmdGroup";
description = "The name of the autocommand group.";
};
clear = mkOption {
type = bool;
default = true;
description = ''
Whether to clear existing autocommands in this group before defining new ones.
This helps avoid duplicate autocommands.
'';
};
};
};
cfg = config.vim;
in {
options.vim = {
autogroups = mkOption {
type = listOf autogroupType;
default = [];
description = ''
A list of Neovim autogroups, which are used to organize and manage related
autocommands together. Groups allow multiple autocommands to be cleared
or redefined collectively, preventing duplicate definitions.
Each autogroup consists of a name, a boolean indicating whether to clear
existing autocommands, and a list of associated autocommands.
'';
};
autocommands = mkOption {
type = listOf autocommandType;
default = [];
description = ''
A list of Neovim autocommands to be registered. Each entry defines an
autocommand, specifying events, patterns, and optional callbacks, commands,
groups, and execution settings.
'';
};
};
config.vim = let
enabledAutocommands = lib.filter (cmd: cmd.enable) cfg.autocommands;
in {
luaConfigRC = {
autogroups = entryAfter ["pluginConfigs"] (lib.optionalString (enabledAutocommands != []) ''
local nvf_autogroups = ${toLuaObject cfg.autogroups}
for group_name, options in pairs(nvf_autogroups) do
vim.api.nvim_create_augroup(group_name, options)
end
'');
autocommands = entryAfter ["pluginConfigs"] (lib.optionalString (cfg.autocommands != []) ''
local nvf_autocommands = ${toLuaObject enabledAutocommands}
for _, autocmd in ipairs(nvf_autocommands) do
vim.api.nvim_create_autocmd(
autocmd.event,
{
group = autocmd.group,
pattern = autocmd.pattern,
buffer = autocmd.buffer,
desc = autocmd.desc,
callback = autocmd.callback,
command = autocmd.command,
once = autocmd.once,
nested = autocmd.nested
}
)
end
'');
};
};
}

View file

@ -1,5 +1,6 @@
{
imports = [
./autocommands.nix
./basic.nix
./debug.nix
./highlight.nix

View file

@ -12,9 +12,31 @@ in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["nvim-lint"];
pluginRC.nvim-lint = entryAnywhere ''
require("lint").setup(${toLuaObject cfg.setupOpts})
'';
pluginRC.nvim-lint = let
mappedLinters =
lib.concatMapAttrsStringSep "\n" (name: value: ''
local linter_${name} = lint.linters.${name}
linter_${name}.args = ${toLuaObject value}
'')
cfg.configuredLinters;
in
entryAnywhere ''
local lint = require("lint")
${mappedLinters}
lint.linters_by_ft = ${toLuaObject cfg.setupOpts.linters_by_ft};
-- TODO: one way of doing this dynamically is to use take required
-- parameters like fts, commands, arguments and everything expected
-- by nvim-lint to simply construct multiple autocommands. nvim-lint
-- doesn't seem to be able to handle that by itself.
vim.api.nvim_create_autocmd({ "BufWritePost" }, {
callback = function()
-- try_lint without arguments runs the linters defined in `linters_by_ft`
-- for the current filetype
require("lint").try_lint()
end,
})
'';
};
};
}

View file

@ -1,14 +1,21 @@
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) attrsOf listOf str;
inherit (lib.types) attrsOf listOf str anything;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
options.vim.diagnostics.nvim-lint = {
enable = mkEnableOption "asynchronous linter plugin for Neovim [nvim-lint]";
configuredLinters = mkOption {
type = attrsOf anything;
default = {};
description = "";
};
setupOpts = mkPluginSetupOption "nvim-lint" {
linters_by_ft = mkOption {
type = attrsOf (listOf str);
default = {};
default = {markdown = ["value"];};
example = {
text = ["vale"];
markdown = ["vale"];

View file

@ -4,7 +4,7 @@
...
}: let
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) attrsOf anything list either;
inherit (lib.types) attrsOf anything listOf either;
inherit (lib.nvim.types) mkPluginSetupOption luaInline;
cfg = config.vim.formatter.conform-nvim;
@ -42,7 +42,7 @@ in {
};
formatters_by_ft = mkOption {
type = either (attrsOf list) luaInline;
type = either (attrsOf (listOf anything)) luaInline;
default = {};
example = {lua = ["stylua"];};
description = ''