diff --git a/configuration.nix b/configuration.nix index 256f0b51..4bebddab 100644 --- a/configuration.nix +++ b/configuration.nix @@ -90,6 +90,7 @@ isMaximal: { fsharp.enable = false; just.enable = false; qml.enable = false; + dockerfile.enable = false; tailwind.enable = false; svelte.enable = false; diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index 7c92ee80..305b7ba4 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -502,6 +502,9 @@ [qmk-nvim]: https://github.com/codethread/qmk.nvim [qmlls]: https://doc.qt.io/qt-6/qtqml-tooling-qmlls.html [qmlformat]: https://doc.qt.io/qt-6/qtqml-tooling-qmlformat.html +[docker-language-server]: https://github.com/docker/docker-language-server +[dockerfmt]: https://github.com/reteps/dockerfmt +[hadolint]: https://github.com/hadolint/hadolint - Add [nvim-biscuits] support under `vim.utility.nvim-biscuits`. - Add just support under `vim.languages.just` using [just-lsp]. @@ -512,6 +515,8 @@ [htmlHINT]. - Add QMK support under `vim.utility.qmk-nvim` via [qmk-nvim]. - Add QML support under `vim.languages.qml` using [qmlls] and [qmlformat]. +- Add Dockerfile support under `vim.languages.dockerfile` using + [docker-language-server], [dockerfmt], and [hadolint]. [Morsicus](https://github.com/Morsicus): @@ -521,4 +526,3 @@ [diced](https://github.com/diced): - Fixed `typescript` treesitter grammar not being included by default. - diff --git a/modules/plugins/languages/default.nix b/modules/plugins/languages/default.nix index fd45758f..fed346f4 100644 --- a/modules/plugins/languages/default.nix +++ b/modules/plugins/languages/default.nix @@ -11,6 +11,7 @@ in { ./clang.nix ./clojure.nix ./css.nix + ./dockerfile.nix ./elixir.nix ./fsharp.nix ./gleam.nix diff --git a/modules/plugins/languages/dockerfile.nix b/modules/plugins/languages/dockerfile.nix new file mode 100644 index 00000000..da1d7892 --- /dev/null +++ b/modules/plugins/languages/dockerfile.nix @@ -0,0 +1,133 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (builtins) attrNames; + inherit (lib.meta) getExe; + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.types) enum package; + inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf; + inherit (lib.nvim.attrsets) mapListToAttrs; + + cfg = config.vim.languages.dockerfile; + + defaultServers = ["docker-language-server"]; + servers = { + docker-language-server = { + cmd = [(getExe pkgs.docker-language-server) "start" "--stdio"]; + filetypes = ["dockerfile" "yaml.docker-compose"]; + root_markers = [ + "Dockerfile" + "docker-compose.yaml" + "docker-compose.yml" + "compose.yaml" + "compose.yml" + "docker-bake.json" + "docker-bake.hcl" + ]; + }; + }; + + defaultFormat = "dockerfmt"; + formats = { + dockerfmt = { + package = pkgs.dockerfmt; + }; + }; + + defaultDiagnosticsProvider = ["hadolint"]; + diagnosticsProviders = { + hadolint = { + config.cmd = getExe (pkgs.writeShellApplication { + name = "hadolint"; + runtimeInputs = [pkgs.hadolint]; + text = "hadolint -"; + }); + }; + }; +in { + options.vim.languages.dockerfile = { + enable = mkEnableOption "Dockerfile language support"; + treesitter = { + enable = mkEnableOption "Dockerfile treesitter support"; + package = mkGrammarOption pkgs "dockerfile"; + }; + + lsp = { + enable = mkEnableOption "Dockerfile LSP support" // {default = config.vim.lsp.enable;}; + servers = mkOption { + type = singleOrListOf (enum (attrNames servers)); + default = defaultServers; + description = "Dockerfile LSP server to use"; + }; + }; + + format = { + enable = mkEnableOption "Dockerfile formatting" // {default = config.vim.languages.enableFormat;}; + + type = mkOption { + type = enum (attrNames formats); + default = defaultFormat; + description = "Dockerfile formatter to use"; + }; + + package = mkOption { + type = package; + default = formats.${cfg.format.type}.package; + description = "Dockerfile formatter package"; + }; + }; + + extraDiagnostics = { + enable = mkEnableOption "extra Dockerfile diagnostics" // {default = config.vim.languages.enableExtraDiagnostics;}; + + types = diagnostics { + langDesc = "Dockerfile"; + inherit diagnosticsProviders; + inherit defaultDiagnosticsProvider; + }; + }; + }; + + config = mkMerge [ + (mkIf cfg.treesitter.enable { + vim.treesitter = { + enable = true; + grammars = [cfg.treesitter.package]; + }; + }) + + (mkIf cfg.lsp.enable { + vim.lsp.servers = + mapListToAttrs (n: { + name = n; + value = servers.${n}; + }) + cfg.lsp.servers; + }) + + (mkIf (cfg.format.enable) { + vim.formatter.conform-nvim = { + enable = true; + setupOpts.formatters_by_ft.dockerfile = [cfg.format.type]; + setupOpts.formatters.${cfg.format.type} = { + command = getExe cfg.format.package; + }; + }; + }) + + (mkIf cfg.extraDiagnostics.enable { + vim.diagnostics.nvim-lint = { + enable = true; + linters_by_ft.dockerfile = cfg.extraDiagnostics.types; + linters = mkMerge (map (name: { + ${name} = diagnosticsProviders.${name}.config; + }) + cfg.extraDiagnostics.types); + }; + }) + ]; +}