From 98c3a04f93456ec2831848bb2373a4f410a8848a Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Mon, 1 Jun 2026 23:17:31 +0200 Subject: [PATCH 1/3] jls: package in flake --- flake/pkgs/by-name/jls/package.nix | 101 +++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 flake/pkgs/by-name/jls/package.nix 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"; + }; + }) From f8b3f04c86466544e484f3cb714048db68f82d17 Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Mon, 1 Jun 2026 23:20:33 +0200 Subject: [PATCH 2/3] lsp/presets/jls: init --- docs/manual/release-notes/rl-0.9.md | 3 +++ modules/plugins/languages/java.nix | 2 +- modules/plugins/lsp/presets/default.nix | 1 + modules/plugins/lsp/presets/jls.nix | 34 +++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 modules/plugins/lsp/presets/jls.nix diff --git a/docs/manual/release-notes/rl-0.9.md b/docs/manual/release-notes/rl-0.9.md index ce0e34a4..cd57ef1c 100644 --- a/docs/manual/release-notes/rl-0.9.md +++ b/docs/manual/release-notes/rl-0.9.md @@ -323,6 +323,9 @@ [Snoweuph](https://github.com/snoweuph) +- Added {option}`vim.lsp.presets.jls.enable` and made it available under + `vim.languages.java.lsp.servers`. + - Allow the usage of `pks.tree-sitter-grammars` in {option}`vim.treesitter.grammars` and language module tree-sitter package options created via `mkGrammarOption`. diff --git a/modules/plugins/languages/java.nix b/modules/plugins/languages/java.nix index 25a78acb..6da8dba5 100644 --- a/modules/plugins/languages/java.nix +++ b/modules/plugins/languages/java.nix @@ -14,7 +14,7 @@ cfg = config.vim.languages.java; defaultServers = ["jdt-language-server"]; - servers = ["jdt-language-server"]; + servers = ["jdt-language-server" "jls"]; in { options.vim.languages.java = { enable = mkEnableOption "Java language support"; diff --git a/modules/plugins/lsp/presets/default.nix b/modules/plugins/lsp/presets/default.nix index 1b4bdedf..66a8d9ef 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 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" + ]; + }; + }; +} From 20ff0827d1d2cfcb16d0c6c2d3bd5cac9a80f712 Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Fri, 5 Jun 2026 00:37:08 +0200 Subject: [PATCH 3/3] languages/java: add dap support via JLS --- docs/manual/release-notes/rl-0.9.md | 2 + modules/plugins/languages/go.nix | 2 +- modules/plugins/languages/java.nix | 115 ++++++++++++++++++++++++++-- 3 files changed, 111 insertions(+), 8 deletions(-) diff --git a/docs/manual/release-notes/rl-0.9.md b/docs/manual/release-notes/rl-0.9.md index cd57ef1c..a8df0f6b 100644 --- a/docs/manual/release-notes/rl-0.9.md +++ b/docs/manual/release-notes/rl-0.9.md @@ -326,6 +326,8 @@ - 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`. 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/java.nix b/modules/plugins/languages/java.nix index 6da8dba5..07cf54bc 100644 --- a/modules/plugins/languages/java.nix +++ b/modules/plugins/languages/java.nix @@ -2,19 +2,47 @@ 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" "jls"]; + + defaultDebugger = "jls"; + debuggers = { + jls = let + pkg = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.jls; + in { + package = pkg; + config = + # Lua + '' + 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 +76,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 +182,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 +196,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 {