From 806970648eb2053354de624111f998a5e808b017 Mon Sep 17 00:00:00 2001 From: Matias Date: Sat, 1 Mar 2025 15:05:28 +0100 Subject: [PATCH] languages/qml: add QML support --- configuration.nix | 1 + docs/release-notes/rl-0.8.md | 8 ++ modules/plugins/languages/default.nix | 1 + modules/plugins/languages/qml.nix | 118 ++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 modules/plugins/languages/qml.nix diff --git a/configuration.nix b/configuration.nix index 692337db..8fe4a809 100644 --- a/configuration.nix +++ b/configuration.nix @@ -61,6 +61,7 @@ isMaximal: { lua.enable = isMaximal; zig.enable = isMaximal; python.enable = isMaximal; + qml.enable = isMaximal; typst.enable = isMaximal; rust = { enable = isMaximal; diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index 0440f38f..70713307 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -192,3 +192,11 @@ - Add formatters for go: [gofmt](https://go.dev/blog/gofmt), [golines](https://github.com/segmentio/golines) and [gofumpt](https://github.com/mvdan/gofumpt) + +[TheSunCat](https://github.com/TheSunCat) + +[qmlls]: https://doc.qt.io/qt-6/qtqml-tooling-qmlls.html +[qmlformat]: https://doc.qt.io/qt-6/qtqml-tooling-qmlformat.html + +- Add QML LSP and formatter support under `vim.languages.qml` using [qmlls] and + [qmlformat]. diff --git a/modules/plugins/languages/default.nix b/modules/plugins/languages/default.nix index 219e04fb..06a7165c 100644 --- a/modules/plugins/languages/default.nix +++ b/modules/plugins/languages/default.nix @@ -24,6 +24,7 @@ in { ./ocaml.nix ./php.nix ./python.nix + ./qml.nix ./r.nix ./rust.nix ./scala.nix diff --git a/modules/plugins/languages/qml.nix b/modules/plugins/languages/qml.nix new file mode 100644 index 00000000..5765219e --- /dev/null +++ b/modules/plugins/languages/qml.nix @@ -0,0 +1,118 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (builtins) attrNames; + inherit (lib.lists) isList; + inherit (lib.strings) optionalString; + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.types) bool enum package either listOf str nullOr; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.nvim.lua) expToLua; + inherit (lib.nvim.types) mkGrammarOption; + + cfg = config.vim.languages.qml; + + packageToCmd = package: defaultCmd: + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{ "${cfg.lsp.package}/bin/${defaultCmd}" }''; + + defaultServer = "qmlls"; + servers = { + qmlls = { + package = pkgs.kdePackages.qtdeclarative; + lspConfig = '' + lspconfig.qmlls.setup{ + capabilities = capabilities; + on_attach=default_on_attach; + cmd = ${packageToCmd cfg.lsp.package "qmlls"}; + ${optionalString (cfg.lsp.opts != null) "init_options = ${cfg.lsp.opts}"} + } + ''; + }; + }; + + defaultFormat = "qmlformat"; + formats = { + qmlformat = { + package = pkgs.kdePackages.qtdeclarative; + nullConfig = '' + table.insert( + ls_sources, + null_ls.builtins.formatting.qmlformat.with({ + command = "${cfg.format.package}/bin/qmlformat", + }) + ) + ''; + }; + }; +in { + options.vim.languages.qml = { + enable = mkEnableOption "QML language support"; + + treesitter = { + enable = mkEnableOption "QML treesitter" // {default = config.vim.languages.enableTreesitter;}; + package = mkGrammarOption pkgs "qmljs"; + }; + + lsp = { + enable = mkEnableOption "QML LSP support" // {default = config.vim.languages.enableLSP;}; + + server = mkOption { + description = "The QML LSP server to use"; + type = enum (attrNames servers); + default = defaultServer; + }; + + package = mkOption { + description = "QML LSP server package, or the command to run as a list of strings"; + example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]''; + type = either package (listOf str); + default = ["${servers.${cfg.lsp.server}.package}/bin/qmlls" "-E"]; + }; + + opts = mkOption { + description = "Options to pass to QML LSP server"; + type = nullOr str; + default = null; + }; + }; + + format = { + enable = mkEnableOption "QML formatting" // {default = config.vim.languages.enableFormat;}; + + type = mkOption { + description = "QML formatter to use"; + type = enum (attrNames formats); + default = defaultFormat; + }; + + package = mkOption { + description = "QML formatter package"; + type = package; + default = formats.${cfg.format.type}.package; + }; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + (mkIf cfg.treesitter.enable { + vim.treesitter.enable = true; + vim.treesitter.grammars = [cfg.treesitter.package]; + }) + + (mkIf cfg.lsp.enable { + vim.lsp.lspconfig.enable = true; + + vim.lsp.lspconfig.sources.qml = servers.${cfg.lsp.server}.lspConfig; + }) + + (mkIf cfg.format.enable { + vim.lsp.null-ls.enable = true; + vim.lsp.null-ls.sources.qml = formats.${cfg.format.type}.nullConfig; + }) + ]); +}