diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index 78c3ba42..110fd5d7 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -480,9 +480,13 @@ [roslyn-ls]: https://github.com/dotnet/vscode-csharp [jsonls]: https://github.com/microsoft/vscode/tree/1.101.2/extensions/json-language-features/server [jsonfmt]: https://github.com/caarlos0/jsonfmt +[superhtml]: https://github.com/kristoff-it/superhtml +[htmlHTML]: https://github.com/htmlhint/HTMLHint [qmk-nvim]: https://github.com/codethread/qmk.nvim - Add just support under `vim.languages.just` using [just-lsp]. - Add [roslyn-ls] to the `vim.languages.csharp` module. - Add JSON support under `vim.languages.json` using [jsonls] and [jsonfmt]. -- Add QMK support under `vim.utility.qmk-nvim` via [qmk-nvim]. +- Add advanced HTML support under `vim.languages.html` using [superhtml] and + [htmlHINT]. +- Add QMK support under `vim.utility.qmk-nvim` via [qmk-nvim]. \ No newline at end of file diff --git a/modules/plugins/languages/html.nix b/modules/plugins/languages/html.nix index 0bef2767..bcc6b842 100644 --- a/modules/plugins/languages/html.nix +++ b/modules/plugins/languages/html.nix @@ -4,14 +4,44 @@ lib, ... }: let + inherit (builtins) attrNames; + inherit (lib.meta) getExe; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) bool; + inherit (lib.types) bool enum package; inherit (lib.lists) optional; - inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.html; + + defaultServers = ["superhtml"]; + servers = { + superhtml = { + cmd = [(getExe pkgs.superhtml) "lsp"]; + filetypes = ["html" "shtml" "htm"]; + root_markers = ["index.html" ".git"]; + }; + }; + + defaultFormat = "superhtml"; + formats = { + superhtml = { + package = pkgs.writeShellApplication { + name = "superhtml_fmt"; + runtimeInputs = [pkgs.superhtml]; + text = "superhtml fmt -"; + }; + }; + }; + + defaultDiagnosticsProvider = ["htmlhint"]; + diagnosticsProviders = { + htmlhint = { + config.cmd = getExe pkgs.htmlhint; + }; + }; in { options.vim.languages.html = { enable = mkEnableOption "HTML language support"; @@ -19,9 +49,44 @@ in { enable = mkEnableOption "HTML treesitter support" // {default = config.vim.languages.enableTreesitter;}; package = mkGrammarOption pkgs "html"; autotagHtml = mkOption { - description = "Enable autoclose/autorename of html tags (nvim-ts-autotag)"; type = bool; default = true; + description = "Enable autoclose/autorename of html tags (nvim-ts-autotag)"; + }; + }; + + lsp = { + enable = mkEnableOption "HTML LSP support" // {default = config.vim.lsp.enable;}; + servers = mkOption { + type = singleOrListOf (enum (attrNames servers)); + default = defaultServers; + description = "HTML LSP server to use"; + }; + }; + + format = { + enable = mkEnableOption "HTML formatting" // {default = config.vim.languages.enableFormat;}; + + type = mkOption { + type = enum (attrNames formats); + default = defaultFormat; + description = "HTML formatter to use"; + }; + + package = mkOption { + type = package; + default = formats.${cfg.format.type}.package; + description = "HTML formatter package"; + }; + }; + + extraDiagnostics = { + enable = mkEnableOption "extra HTML diagnostics" // {default = config.vim.languages.enableExtraDiagnostics;}; + + types = diagnostics { + langDesc = "HTML"; + inherit diagnosticsProviders; + inherit defaultDiagnosticsProvider; }; }; }; @@ -41,5 +106,35 @@ in { ''); }; }) + + (mkIf cfg.lsp.enable { + vim.lsp.servers = + mapListToAttrs (n: { + name = n; + value = servers.${n}; + }) + cfg.lsp.servers; + }) + + (mkIf (cfg.format.enable && !cfg.lsp.enable) { + vim.formatter.conform-nvim = { + enable = true; + setupOpts.formatters_by_ft.html = [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.html = cfg.extraDiagnostics.types; + linters = mkMerge (map (name: { + ${name} = diagnosticsProviders.${name}.config; + }) + cfg.extraDiagnostics.types); + }; + }) ]); } diff --git a/modules/plugins/languages/json.nix b/modules/plugins/languages/json.nix index cd3ae17f..26349710 100644 --- a/modules/plugins/languages/json.nix +++ b/modules/plugins/languages/json.nix @@ -6,7 +6,7 @@ }: let inherit (builtins) attrNames; inherit (lib.options) mkOption mkEnableOption; - inherit (lib.meta) getExe; + inherit (lib.meta) getExe' getExe; inherit (lib.modules) mkIf mkMerge; inherit (lib.types) enum package; inherit (lib.nvim.types) mkGrammarOption singleOrListOf; @@ -17,7 +17,7 @@ defaultServers = ["jsonls"]; servers = { jsonls = { - cmd = [(getExe pkgs.vscode-json-languageserver) "--stdio"]; + cmd = [(getExe' pkgs.vscode-langservers-extracted "vscode-json-languageserver") "--stdio"]; filetypes = ["json" "jsonc"]; init_options = {provideFormatter = true;}; root_markers = [".git"]; @@ -37,7 +37,7 @@ }; in { options.vim.languages.json = { - enable = mkEnableOption "JSON langauge support"; + enable = mkEnableOption "JSON language support"; treesitter = { enable = mkEnableOption "JSON treesitter" // {default = config.vim.languages.enableTreesitter;};