nvf/modules/plugins/languages/hcl.nix
NotAShelf 5bc627f4e4
Some checks failed
Check for typos in the source tree / check-typos (push) Has been cancelled
languages: convert modules to new LSP option set format
2025-03-19 10:20:16 +03:00

147 lines
3.9 KiB
Nix

{
config,
pkgs,
lib,
...
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) package bool enum;
inherit (lib.lists) isList;
inherit (lib.meta) getExe;
inherit (lib.generators) mkLuaInline;
inherit (lib.lua) expToLua toLuaObject;
inherit (lib.nvim.languages) lspOptions;
inherit (lib.nvim.types) mkGrammarOption;
cfg = config.vim.languages.hcl;
defaultServer = "terraform-ls";
servers = {
terraform-ls = {
package = pkgs.terraform-ls;
options = {
capabilities = mkLuaInline "capabilities";
on_attach = mkLuaInline "default_on_attach";
filetypes = ["terraform" "hcl"];
cmd =
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ["${getExe cfg.lsp.package}" "serve"];
};
};
};
defaultFormat = "hclfmt";
formats = {
hclfmt = {
package = pkgs.hclfmt;
nullConfig = ''
table.insert(
ls_sources,
null_ls.builtins.formatting.hclfmt.with({
command = "${lib.getExe cfg.format.package}",
})
)
'';
};
};
in {
options.vim.languages.hcl = {
enable = mkEnableOption "HCL support";
treesitter = {
enable = mkEnableOption "HCL treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "hcl";
};
lsp = {
enable = mkEnableOption "HCL LSP support (terraform-ls)" // {default = config.vim.languages.enableLSP;};
# TODO: (maybe, is it better?) it would be cooler to use vscode-extensions.hashicorp.hcl probably, shouldn't be too hard
package = mkOption {
type = package;
default = servers.${defaultServer}.package;
description = "HCL language server package (terraform-ls)";
};
server = mkOption {
description = "HCL LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
options = mkOption {
type = lspOptions;
default = servers.${cfg.lsp.server}.options;
description = ''
LSP options for HCL language support.
This option is freeform, you may add options that are not set by default
and they will be merged into the final table passed to lspconfig.
'';
};
};
format = {
enable = mkOption {
type = bool;
default = config.vim.languages.enableFormat;
description = "Enable HCL formatting";
};
type = mkOption {
type = enum (attrNames formats);
default = defaultFormat;
description = "HCL formatter to use";
};
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "HCL formatter package";
};
};
};
config = mkIf cfg.enable (mkMerge [
{
# HCL style official: https://developer.hashicorp.com/terraform/language/style#code-formatting
vim.pluginRC.hcl = ''
vim.api.nvim_create_autocmd("FileType", {
pattern = "hcl",
callback = function(opts)
local bo = vim.bo[opts.buf]
bo.tabstop = 2
bo.shiftwidth = 2
bo.softtabstop = 2
end
})
local ft = require('Comment.ft')
ft
.set('hcl', '#%s')
'';
}
(mkIf cfg.treesitter.enable {
vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package];
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig = {
enable = true;
sources.hcl-lsp = lib.optionalString (!config.vim.languages.terraform.lsp.enable) ''
lspconfig.${toLuaObject cfg.lsp.server}.setup(${toLuaObject cfg.lsp.options})
'';
};
})
(mkIf cfg.format.enable {
vim.lsp.null-ls.enable = true;
vim.lsp.null-ls.sources.hcl-format = formats.${cfg.format.type}.nullConfig;
})
]);
}