diff --git a/docs/manual/release-notes/rl-0.9.md b/docs/manual/release-notes/rl-0.9.md index ce0e34a4..b4e4b250 100644 --- a/docs/manual/release-notes/rl-0.9.md +++ b/docs/manual/release-notes/rl-0.9.md @@ -192,6 +192,11 @@ - Lazyload noice.nvim and nvim-web-devicons on `DeferredUIEnter` - Allow nulling treesitter packages for various language modules, filter `null` values in `vim.treesitter.grammars`. +- Added {option}`vim.filetype` module option for registering custom filetypes + via `vim.filetype.add()`, placed in the DAG before `lazyConfigs` so plugins + can lazy-load on registered filetypes. +- Moved `neovim/mappings` to `neovim/init/mappings.nix` to consolidate core + Neovim init options. [jfeo](https://github.com/jfeo): @@ -323,6 +328,11 @@ [Snoweuph](https://github.com/snoweuph) +- Added {option}`vim.lsp.presets.jls.enable` and made it available under + `vim.languages.java.lsp.servers`. + +- Added {option}`vim.languages.java.dap.enable` with the `jls` DAP. + - Allow the usage of `pks.tree-sitter-grammars` in {option}`vim.treesitter.grammars` and language module tree-sitter package options created via `mkGrammarOption`. @@ -355,9 +365,6 @@ more flexibility in nvf and reuse of LSPs across languages. Dropped `deprecatedSingleOrListOf` in favor of `listOf` for the affected LSP options. -- Added {option}`vim.lsp.presets.docker-language-server.enable` for Docker - support. - - Added {option}`vim.lsp.presets.angular-language-server.enable` for Angular Template support. @@ -381,10 +388,18 @@ - Added [Selenen](https://github.com/kampfkarren/selene) for more diagnostics in `languages.lua`. +- Added the [Stimulus LSP](https://github.com/marcoroth/stimulus-lsp) as LSP + preset. + - Added `languages.docker` for Docker and Docker-Compose support. Thanks to [poseidon-rises](https://github.com/poseidon-rises) for creating most of it in [!1104](https://github.com/NotAShelf/nvf/pull/1104). +- Added {option}`vim.lsp.presets.docker-language-server.enable` for Docker + support. + +- Mapped `dockercompose` to be highlighted by treesitter as `yaml`. + - Added [`mdformat`](https://mdformat.rtfd.io/) support to `languages.markdown` with the extensions for [GFM](https://github.github.com/gfm/), [front matter](https://www.markdownlang.com/advanced/frontmatter.html) and diff --git a/flake/pkgs/by-name/jls/package.nix b/flake/pkgs/by-name/jls/package.nix new file mode 100644 index 00000000..a2253b59 --- /dev/null +++ b/flake/pkgs/by-name/jls/package.nix @@ -0,0 +1,101 @@ +# based on +{ + lib, + jdk25_headless, + maven, + lombok, + protobuf_25, + lombokSupport ? true, + makeWrapper, + fetchFromGitHub, +}: let + inherit (lib.meta) getExe; + + jdk = jdk25_headless; + java = getExe jdk; + jlinkVmOptions = + map + (option: '' + --add-flags "${option}" \ + '') + [ + "--add-modules jdk.jdeps" + "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED" + "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" + "--add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED" + ]; + wrapperFlags = '' + ${lib.concatStringsSep " " jlinkVmOptions} \ + --add-flags "\$JLS_JVM_OPTS" \ + --add-flags "-Djava.util.logging.config.file=$out/share/jls/logging.properties" \ + ${lib.optionalString lombokSupport ''--add-flags "-Dorg.javacs.lombokPath=${lombok}/share/lombok.jar"''} \ + --add-flags "-classpath '$out/share/jls/classpath/*'" \ + --set-default JLS_JVM_OPTS "-Xmx2g -Xms512m -XX:MaxHeapFreeRatio=50 -XX:MinHeapFreeRatio=20 -XX:+UseStringDeduplication" \ + ''; +in + maven.buildMavenPackage (finalAttrs: { + pname = "jls"; + version = "0.6.1"; + + src = fetchFromGitHub { + owner = "idelice"; + repo = "jls"; + tag = "v${finalAttrs.version}"; + hash = "sha256-kZ96OsCMtpS3diUT/4+TEnzNb2G4LfDdrrSKuhIM9NU="; + }; + + mvnJdk = jdk; + mvnHash = "sha256-E/ZNOGIB/00dfhPsagwJUV6TWHCY7Jb5Ewlvyxs3sRI="; + mvnParameters = "-DskipTests"; + + nativeBuildInputs = [ + makeWrapper + protobuf_25 + ]; + + preBuild = '' + bash ./scripts/gen_proto.sh + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin $out/share/jls/ + cp -r dist/classpath $out/share/jls/ + install -Dm644 scripts/logging.properties $out/share/jls + + makeWrapper ${java} $out/bin/jls \ + ${wrapperFlags} \ + --add-flags "org.javacs.Main" + makeWrapper ${java} $out/bin/jls-dap \ + ${wrapperFlags} \ + --add-flags "org.javacs.debug.JavaDebugServer" + + runHook postInstall + ''; + + meta = { + description = "Java Language Server for Neovim"; + license = lib.licenses.mit; + mainProgram = "jls"; + }; + }) diff --git a/flake/pkgs/by-name/stimulus-language-server/0001-use-local-hotwired.patch b/flake/pkgs/by-name/stimulus-language-server/0001-use-local-hotwired.patch new file mode 100644 index 00000000..f2fcee53 --- /dev/null +++ b/flake/pkgs/by-name/stimulus-language-server/0001-use-local-hotwired.patch @@ -0,0 +1,15 @@ +--- a/package.json ++++ b/package.json +@@ -13,3 +13,3 @@ + "dependencies": { +- "@hotwired/stimulus": "https://github.com/hotwired/dev-builds/archive/refs/tags/@hotwired/stimulus/8cbca6d.tar.gz", ++ "@hotwired/stimulus": "file:./hotwired-stimulus.tar.gz", + "dedent": "^1.5.1", +--- a/yarn.lock ++++ b/yarn.lock +@@ -27,3 +27,3 @@ +-"@hotwired/stimulus@https://github.com/hotwired/dev-builds/archive/refs/tags/@hotwired/stimulus/8cbca6d.tar.gz": ++"@hotwired/stimulus@file:./hotwired-stimulus.tar.gz": + version "3.2.2" +- resolved "https://github.com/hotwired/dev-builds/archive/refs/tags/@hotwired/stimulus/8cbca6d.tar.gz#bcca3015d4e1a7e6defad94db626e11dc97e69e5" ++ resolved "file:./hotwired-stimulus.tar.gz" diff --git a/flake/pkgs/by-name/stimulus-language-server/0002-add-types-node.patch b/flake/pkgs/by-name/stimulus-language-server/0002-add-types-node.patch new file mode 100644 index 00000000..5b15b8ff --- /dev/null +++ b/flake/pkgs/by-name/stimulus-language-server/0002-add-types-node.patch @@ -0,0 +1,22 @@ +--- a/package.json ++++ b/package.json +@@ -38,2 +38,3 @@ + "devDependencies": { ++ "@types/node": "^20.0.0", + "@types/estree": "^1.0.5", +--- a/yarn.lock ++++ b/yarn.lock +@@ -307,4 +307,13 @@ + vscode-uri@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c" + integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ== ++ ++"@types/node@^20.0.0": ++ version "20.19.0" ++ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.0.tgz#7006b097b15dfea06695c3bbdba98b268797f65b" ++ ++undici-types@~6.19.2: ++ version "6.19.8" ++ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" ++ integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== diff --git a/flake/pkgs/by-name/stimulus-language-server/package.nix b/flake/pkgs/by-name/stimulus-language-server/package.nix new file mode 100644 index 00000000..61e889d3 --- /dev/null +++ b/flake/pkgs/by-name/stimulus-language-server/package.nix @@ -0,0 +1,63 @@ +{ + lib, + stdenvNoCC, + fetchFromGitHub, + fetchYarnDeps, + fetchurl, + yarnConfigHook, + yarnBuildHook, + yarnInstallHook, + nodejs, + runCommand, + patch, + nix-update-script, +}: let + version = "1.1.0"; + + upstream = fetchFromGitHub { + owner = "marcoroth"; + repo = "stimulus-lsp"; + tag = "v${version}"; + hash = "sha256-QAXQKZoFvqhnbAIi9fnJ7pV8fXah0NjwxdrqKB5e5Vw="; + }; + + # `fetchYarnDeps` doesn't support tarballs so we need to patch this manually + stimulusTarball = fetchurl { + url = "https://github.com/hotwired/dev-builds/archive/refs/tags/@hotwired/stimulus/8cbca6d.tar.gz"; + hash = "sha256-2iRIiwXmdcSw7y3CQNIPt6duwZuVvDvdU/FEdqcnzW4="; + }; + + src = runCommand "stimulus-lsp-server-patched" {nativeBuildInputs = [patch];} '' + cp -r ${upstream}/server $out + chmod -R +w $out + cp '${stimulusTarball}' $out/hotwired-stimulus.tar.gz + patch -d $out -p1 < '${./0001-use-local-hotwired.patch}' + patch -d $out -p1 < '${./0002-add-types-node.patch}' + ''; +in + stdenvNoCC.mkDerivation { + pname = "stimulus-language-server"; + inherit version src; + + offlineCache = fetchYarnDeps { + yarnLock = "${src}/yarn.lock"; + hash = "sha256-UvojI/Ow602Q+iiwRpSgxm4DV0IJ0sURicdgghmpBsU="; + }; + + nativeBuildInputs = [ + yarnConfigHook + yarnBuildHook + yarnInstallHook + nodejs + ]; + + passthru.updateScript = nix-update-script {}; + + meta = { + description = "Intelligent Stimulus tooling"; + homepage = "https://hotwire.io/ecosystem/tooling/stimulus-lsp"; + changelog = "https://github.com/marcoroth/stimulus-lsp/releases/tag/v${version}"; + license = lib.licenses.mit; + mainProgram = "stimulus-language-server"; + }; + } diff --git a/modules/modules.nix b/modules/modules.nix index 654cd5ce..63605805 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -10,7 +10,6 @@ # such as spellchecking, mappings, and the init script (init.vim). neovim = map (p: ./neovim + "/${p}") [ "init" - "mappings" ]; # Individual plugin modules, separated by the type of plugin. diff --git a/modules/neovim/init/default.nix b/modules/neovim/init/default.nix index 3f195085..e831fab6 100644 --- a/modules/neovim/init/default.nix +++ b/modules/neovim/init/default.nix @@ -5,8 +5,10 @@ ./clipboard.nix ./debug.nix ./diagnostics.nix + ./filetype.nix ./highlight.nix ./lsp.nix + ./mappings.nix ./spellcheck.nix ./util.nix ]; diff --git a/modules/neovim/init/filetype.nix b/modules/neovim/init/filetype.nix new file mode 100644 index 00000000..f08626fd --- /dev/null +++ b/modules/neovim/init/filetype.nix @@ -0,0 +1,123 @@ +{ + config, + lib, + ... +}: let + inherit (lib.options) mkOption; + inherit (lib.types) nullOr either oneOf attrsOf str listOf submodule ints; + inherit (lib.nvim.types) luaInline; + inherit (lib.nvim.dag) entryBefore; + inherit (lib.nvim.lua) toLuaObject; + + cfg = config.vim; + + # vim.filetype.add() is quite robust, but this makes for a very + # complex type that we have to handle. It takes a string, a Lua function + # or a dictionary with the priority of the extension. + ftOptionType = attrsOf (oneOf [ + str # "filetype" + luaInline # `function(path, bufnr) ... end` + + # { 'dosini', { priority = 10 } }, + (listOf (either (either str luaInline) (submodule { + options = { + priority = mkOption { + type = ints.unsigned; + description = '' + `vim.filetype.add()` can take an optional priority value to resolve + conflicts where a filetype is registered by multiple patterns. When + priority is specified, file with the higher priority value will be + matched first on conflict. + ''; + }; + }; + }))) + ]); +in { + options.vim.filetype = mkOption { + type = submodule { + options = { + extension = mkOption { + type = nullOr ftOptionType; + default = null; + description = "register a new filetype by extension"; + }; + + filename = mkOption { + type = nullOr ftOptionType; + default = null; + description = "register a new filetype by file name"; + }; + + pattern = mkOption { + type = nullOr ftOptionType; + default = null; + description = "register a new filetype by pattern"; + }; + }; + }; + + default = {}; + example = { + filename = { + ".foorc" = "toml"; + "/etc/foo/config" = "toml"; + "todo.txt" = "todotxt"; + }; + + pattern = { + ".*%.scm" = "query"; + ".*README.(%a+)" = '' + function(path, bufnr, ext) + if ext == 'md' then + return 'markdown' + elseif ext == 'rst' then + return 'rst' + end + end, + ''; + }; + + extension = { + mdx = "markdown"; + bar = lib.generators.mkLuaInline '' + { + bar = function(path, bufnr) + if some_condition() then + return 'barscript', function(bufnr) + -- Set a buffer variable + vim.b[bufnr].barscript_version = 2 + end + end + return 'bar' + end, + } + ''; + }; + }; + + description = '' + Additional filetypes to be registered through `vim.filetype.add()` + + Filetype mappings can be added either by extension or by filename. The + key can be either the "tail" or the full file path. The full file path + is checked first, followed by the file name. If a match is not found + using the filename, then the filename is matched against the list of + Lua patterns (sorted by priority) until a match is found. + + If a pattern matching does not find a filetype, then the file extension + is used. + + See `:h vim.filetype.add()` for more details. + ''; + }; + + config = { + # XXX: some plugins can be loaded on filetype, and unless the filetypes + # are registered first, chances are custom filetypes will not be usable + # for lazy-loading on ft. + vim.luaConfigRC.filetype = entryBefore ["lazyConfigs"] '' + vim.filetype.add(${toLuaObject cfg.filetype}) + ''; + }; +} diff --git a/modules/neovim/mappings/options.nix b/modules/neovim/init/mappings.nix similarity index 73% rename from modules/neovim/mappings/options.nix rename to modules/neovim/init/mappings.nix index de19b54d..0f665101 100644 --- a/modules/neovim/mappings/options.nix +++ b/modules/neovim/init/mappings.nix @@ -1,19 +1,32 @@ -{lib, ...}: let - inherit (lib.options) mkEnableOption mkOption literalMD; +{ + config, + lib, + ... +}: let + inherit (lib.modules) mkMerge; + inherit (lib.options) mkOption literalMD; inherit (lib.types) either str listOf attrsOf nullOr submodule; + inherit (lib.attrsets) mapAttrsToList; + inherit (lib.lists) flatten; + inherit (lib.trivial) pipe; + inherit (lib.options) mkEnableOption; inherit (lib.nvim.config) mkBool; mapConfigOptions = { desc = mkOption { type = nullOr str; default = null; - description = "A description of this keybind, to be shown in which-key, if you have it enabled."; + description = '' + Description for the keybind, to be shown in which-key, if you have enabled + in the module system. + ''; }; action = mkOption { type = str; description = "The command to execute."; }; + lua = mkBool false '' If true, `action` is considered to be lua code. Thus, it will not be wrapped in `""`. @@ -55,6 +68,22 @@ }); default = {}; }; + + legacyMapModes = { + normal = ["n"]; + insert = ["i"]; + select = ["s"]; + visual = ["v"]; + terminal = ["t"]; + normalVisualOp = ["n" "v" "o"]; + visualOnly = ["n" "x"]; + operator = ["o"]; + insertCommand = ["i" "c"]; + lang = ["l"]; + command = ["c"]; + }; + + cfg = config.vim; in { options.vim = { vendoredKeymaps.enable = @@ -101,4 +130,27 @@ in { command = legacyMapOption "command-line"; }; }; + + config = { + vim.keymaps = mkMerge [ + ( + pipe cfg.maps + [ + (mapAttrsToList ( + oldMode: keybinds: + mapAttrsToList ( + key: bind: + bind + // { + inherit key; + mode = legacyMapModes.${oldMode}; + } + ) + keybinds + )) + flatten + ] + ) + ]; + }; } diff --git a/modules/neovim/mappings/config.nix b/modules/neovim/mappings/config.nix deleted file mode 100644 index a62a6ca2..00000000 --- a/modules/neovim/mappings/config.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib.modules) mkMerge; - inherit (lib.trivial) pipe; - inherit (lib.attrsets) mapAttrsToList; - inherit (lib.lists) flatten; - - legacyMapModes = { - normal = ["n"]; - insert = ["i"]; - select = ["s"]; - visual = ["v"]; - terminal = ["t"]; - normalVisualOp = ["n" "v" "o"]; - visualOnly = ["n" "x"]; - operator = ["o"]; - insertCommand = ["i" "c"]; - lang = ["l"]; - command = ["c"]; - }; - - cfg = config.vim; -in { - config = { - vim.keymaps = mkMerge [ - ( - pipe cfg.maps - [ - (mapAttrsToList ( - oldMode: keybinds: - mapAttrsToList ( - key: bind: - bind - // { - inherit key; - mode = legacyMapModes.${oldMode}; - } - ) - keybinds - )) - flatten - ] - ) - ]; - }; -} diff --git a/modules/neovim/mappings/default.nix b/modules/neovim/mappings/default.nix deleted file mode 100644 index fe9e1b8e..00000000 --- a/modules/neovim/mappings/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - imports = [ - ./config.nix - ./options.nix - ]; -} diff --git a/modules/plugins/languages/docker.nix b/modules/plugins/languages/docker.nix index 649c51a4..88537e4d 100644 --- a/modules/plugins/languages/docker.nix +++ b/modules/plugins/languages/docker.nix @@ -117,6 +117,9 @@ in { vim.treesitter = { enable = true; grammars = [cfg.treesitter.package]; + filetypeMappings = { + yaml = ["dockercompose"]; + }; }; }) diff --git a/modules/plugins/languages/go.nix b/modules/plugins/languages/go.nix index 14f30314..48df8f03 100644 --- a/modules/plugins/languages/go.nix +++ b/modules/plugins/languages/go.nix @@ -205,7 +205,7 @@ in { dap = { enable = - mkEnableOption "Go Debug Adapter (DAP) via `nvim-dap-go" + mkEnableOption "Go Debug Adapter" // { default = config.vim.languages.enableDAP; defaultText = literalExpression "config.vim.languages.enableDAP"; diff --git a/modules/plugins/languages/html.nix b/modules/plugins/languages/html.nix index 9596d74e..b398b982 100644 --- a/modules/plugins/languages/html.nix +++ b/modules/plugins/languages/html.nix @@ -18,7 +18,7 @@ cfg = config.vim.languages.html; defaultServers = ["superhtml"]; - servers = ["superhtml" "emmet-ls" "angular-language-server"]; + servers = ["superhtml" "emmet-ls" "angular-language-server" "stimulus-language-server"]; defaultFormat = ["superhtml"]; formats = { diff --git a/modules/plugins/languages/java.nix b/modules/plugins/languages/java.nix index 25a78acb..01b38192 100644 --- a/modules/plugins/languages/java.nix +++ b/modules/plugins/languages/java.nix @@ -2,19 +2,45 @@ config, pkgs, lib, + inputs, ... }: let - inherit (lib.options) literalExpression mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; - inherit (lib) genAttrs; - inherit (lib.types) listOf str; - inherit (lib.meta) getExe; + inherit (lib.options) literalExpression mkEnableOption mkOption; + inherit (lib.types) listOf str enum package; + inherit (lib.attrsets) attrNames genAttrs; + inherit (lib.meta) getExe getExe'; inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption enumWithRename; cfg = config.vim.languages.java; defaultServers = ["jdt-language-server"]; - servers = ["jdt-language-server"]; + servers = ["jdt-language-server" "jls"]; + + defaultDebugger = "jls"; + debuggers = { + jls = let + pkg = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.jls; + in { + package = pkg; + config = '' + dap.adapters.jls= { + type = 'executable', + command = '${getExe' pkg "jls-dap"}', + } + dap.configurations.java = { + { + type = "jls", + request = "attach", + name = "Attach", + hostName = "localhost", + port = 5005, + sourceRoots = vim.fn.glob("**/src/main/java", true, true), + }, + } + ''; + }; + }; in { options.vim.languages.java = { enable = mkEnableOption "Java language support"; @@ -48,6 +74,72 @@ in { }; }; + dap = { + enable = + mkEnableOption "Java Debug Adapter" + // { + default = config.vim.languages.enableDAP; + defaultText = literalExpression "config.vim.languages.enableDAP"; + }; + + debugger = mkOption { + type = enum (attrNames debuggers); + default = defaultDebugger; + description = '' + Java debugger to use. + + **JLS** + + For `jls` to work, you need to run your application with debug symbols and networking. + + The `jls` configuration is hardcoded to listen on port `5005`. + This matches the configuration described [upstream](https://github.com/idelice/jls#usage). + You can change this by modifying `vim.debugger.nvim-dap.sources.java-debugger`. + ```nix + vim.debugger.nvim-dap.sources.java-debugger = /* lua */ ''' + dap.adapters.jls= { + type = 'executable', + command = ''\'''${getExe' inputs.self.packages.''${pkgs.stdenv.hostPlatform.system}.jls "jls-dap"}', + } + dap.configurations.java = { + { + type = "jls", + request = "attach", + name = "Attach", + hostName = "localhost", + port = 6969, -- your custom port + sourceRoots = vim.fn.glob("**/src/main/java", true, true), + }, + } + '''; + ``` + + *Examples:* + + - Manual: + 1. Build with debug symbols. + ```sh + javac -g ... + ``` + 1. Run with debug socket. + ```sh + java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar your.jar + ``` + - Springboot Maven: + For Springboot you can just pass the JVM args directly into the `spring-boot:run`. + ```sh + mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" + ``` + ''; + }; + + package = mkOption { + type = package; + default = debuggers.${cfg.dap.debugger}.package; + description = "Java debugger package."; + }; + }; + extensions = { maven-nvim = { enable = mkEnableOption "maven integration"; @@ -88,6 +180,11 @@ in { }; 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 = { presets = genAttrs cfg.lsp.servers (_: {enable = true;}); @@ -97,9 +194,11 @@ in { }; }) - (mkIf cfg.treesitter.enable { - vim.treesitter.enable = true; - vim.treesitter.grammars = [cfg.treesitter.package]; + (mkIf cfg.dap.enable { + vim.debugger.nvim-dap = { + enable = true; + sources.java-debugger = debuggers.${cfg.dap.debugger}.config; + }; }) (mkIf cfg.extensions.maven-nvim.enable { diff --git a/modules/plugins/languages/jinja.nix b/modules/plugins/languages/jinja.nix index e8de65f9..97b2761a 100644 --- a/modules/plugins/languages/jinja.nix +++ b/modules/plugins/languages/jinja.nix @@ -13,7 +13,7 @@ cfg = config.vim.languages.jinja; defaultServers = ["jinja-lsp"]; - servers = ["jinja-lsp" "emmet-ls"]; + servers = ["jinja-lsp" "emmet-ls" "stimulus-language-server"]; in { options.vim.languages.jinja = { enable = mkEnableOption "Jinja template language support"; diff --git a/modules/plugins/languages/ruby.nix b/modules/plugins/languages/ruby.nix index dc6ff702..4c8415d8 100644 --- a/modules/plugins/languages/ruby.nix +++ b/modules/plugins/languages/ruby.nix @@ -16,7 +16,7 @@ cfg = config.vim.languages.ruby; defaultServers = ["solargraph"]; - servers = ["ruby-lsp" "solargraph"]; + servers = ["ruby-lsp" "solargraph" "stimulus-language-server"]; # testing diff --git a/modules/plugins/languages/tera.nix b/modules/plugins/languages/tera.nix index e9388f5f..230a7d9a 100644 --- a/modules/plugins/languages/tera.nix +++ b/modules/plugins/languages/tera.nix @@ -13,7 +13,7 @@ cfg = config.vim.languages.tera; defaultServers = []; - servers = ["emmet-ls"]; + servers = ["emmet-ls" "stimulus-language-server"]; in { options.vim.languages.tera = { enable = mkEnableOption "Tera templating language support"; diff --git a/modules/plugins/languages/twig.nix b/modules/plugins/languages/twig.nix index dd5744a1..59b5d56a 100644 --- a/modules/plugins/languages/twig.nix +++ b/modules/plugins/languages/twig.nix @@ -16,7 +16,7 @@ cfg = config.vim.languages.twig; defaultServers = ["twig-language-server"]; - servers = ["twig-language-server" "emmet-ls"]; + servers = ["twig-language-server" "emmet-ls" "stimulus-language-server"]; defaultFormat = ["djlint"]; formats = { diff --git a/modules/plugins/lsp/presets/default.nix b/modules/plugins/lsp/presets/default.nix index 1b4bdedf..193a1ef1 100644 --- a/modules/plugins/lsp/presets/default.nix +++ b/modules/plugins/lsp/presets/default.nix @@ -28,6 +28,7 @@ ./intelephense.nix ./jdt-language-server.nix ./jinja-lsp.nix + ./jls.nix ./jq-lsp.nix ./julia-languageserver.nix ./just-lsp.nix @@ -61,6 +62,7 @@ ./solargraph.nix ./some-sass-language-server.nix ./sqls.nix + ./stimulus-language-server.nix ./superhtml.nix ./svelte-language-server.nix ./tailwindcss-language-server.nix diff --git a/modules/plugins/lsp/presets/jls.nix b/modules/plugins/lsp/presets/jls.nix new file mode 100644 index 00000000..33e1ecff --- /dev/null +++ b/modules/plugins/lsp/presets/jls.nix @@ -0,0 +1,34 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: let + inherit (lib.meta) getExe; + inherit (lib.modules) mkIf; + inherit (lib.nvim.types) mkLspPresetEnableOption; + + cfg = config.vim.lsp.presets.jls; +in { + options.vim.lsp.presets.jls = { + enable = mkLspPresetEnableOption "jls" "NeoVim Java" []; + }; + + config = mkIf cfg.enable { + vim.lsp.servers.jls = { + enable = true; + cmd = [(getExe inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.jls)]; + root_markers = [ + ".git" + ".java-version" + "pom.xml" + "build.xml" + "build.gradle" + "build.gradle.kts" + "settings.gradle" + "settings.gradle.kts" + ]; + }; + }; +} diff --git a/modules/plugins/lsp/presets/stimulus-language-server.nix b/modules/plugins/lsp/presets/stimulus-language-server.nix new file mode 100644 index 00000000..d647e8c1 --- /dev/null +++ b/modules/plugins/lsp/presets/stimulus-language-server.nix @@ -0,0 +1,26 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: let + inherit (lib.meta) getExe; + inherit (lib.modules) mkIf; + inherit (lib.nvim.types) mkLspPresetEnableOption; + + cfg = config.vim.lsp.presets.stimulus-language-server; +in { + options.vim.lsp.presets.stimulus-language-server = { + enable = mkLspPresetEnableOption "stimulus-language-server" "Stimulus" []; + }; + + config = mkIf cfg.enable { + vim.lsp.servers.stimulus-language-server = { + enable = true; + cmd = [(getExe inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.stimulus-language-server) "--stdio"]; + root_markers = [".git"]; + workspace_required = true; + }; + }; +}