feat: nix can manage java runtimes

This commit is contained in:
LordMZTE 2024-04-10 18:03:17 +02:00
parent 86e453ee5b
commit 869b7fe7f6
7 changed files with 62 additions and 8 deletions

View file

@ -4,7 +4,11 @@
, ... , ...
}: }:
{ {
imports = [ ./nvim-tools.nix ./tree-sitter-parsers.nix ]; imports = [
./jvm.nix
./nvim-tools.nix
./tree-sitter-parsers.nix
];
options.cgnix.entries = lib.mkOption { options.cgnix.entries = lib.mkOption {
default = { }; default = { };
@ -16,7 +20,7 @@
name = "nix.lua"; name = "nix.lua";
text = '' text = ''
return { return {
${builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: ''["${k}"] = "${v}",'') config.cgnix.entries)} ${builtins.concatStringsSep "\n " (lib.mapAttrsToList (k: v: ''["${k}"] = "${v}",'') config.cgnix.entries)}
} }
''; '';
}; };

19
cgnix/jvm.nix Normal file
View file

@ -0,0 +1,19 @@
{ lib, pkgs, config, ... }:
let
default-jvms = with pkgs; {
java-8-openjdk = jdk8;
java-17-openjdk = jdk17;
};
in
{
options.cgnix.jvms = lib.mkOption {
default = default-jvms;
};
config.cgnix.entries.jvm = pkgs.linkFarm "jvm" (lib.mapAttrsToList
(k: v: {
name = k;
path = "${v}/lib/openjdk";
})
config.cgnix.jvms);
}

View file

@ -5,7 +5,9 @@ let
# MISSING: glsl_analyzer, haxe_language_server, prosemd_lsp, racket_langserver, yamlls, zls # MISSING: glsl_analyzer, haxe_language_server, prosemd_lsp, racket_langserver, yamlls, zls
# Language Servers # Language Servers
(flakePkg "github:oxalica/nil") (flakePkg "github:oxalica/nil")
(pkgs.linkFarm "clangd" [{ name = "bin/clangd"; path = "${clang-tools}/bin/clangd"; }]) # only clangd (pkgs.linkFarm "clang-nvim" (map
(bin: { name = "bin/${bin}"; path = "${clang-tools}/bin/${bin}"; })
[ "clangd" "clang-format" ])) # Don't include everything from clang-tools
elixir-ls elixir-ls
jdt-language-server jdt-language-server
lua-language-server lua-language-server

View file

@ -24,6 +24,7 @@ pub fn build(b: *std.Build) !void {
nix: struct { nix: struct {
tree_sitter_parsers: ?[:0]u8 = null, tree_sitter_parsers: ?[:0]u8 = null,
nvim_tools: ?[:0]u8 = null, nvim_tools: ?[:0]u8 = null,
jvm: ?[:0]u8 = null,
@"fennel.lua": ?[:0]u8 = null, @"fennel.lua": ?[:0]u8 = null,
}, },
}, b.allocator); }, b.allocator);
@ -32,6 +33,7 @@ pub fn build(b: *std.Build) !void {
opts.addOption([]const u8, "font", cg_opt.term_font); opts.addOption([]const u8, "font", cg_opt.term_font);
opts.addOption(?[:0]const u8, "tree_sitter_parsers", cg_opt.nix.tree_sitter_parsers); opts.addOption(?[:0]const u8, "tree_sitter_parsers", cg_opt.nix.tree_sitter_parsers);
opts.addOption(?[:0]const u8, "nvim_tools", cg_opt.nix.nvim_tools); opts.addOption(?[:0]const u8, "nvim_tools", cg_opt.nix.nvim_tools);
opts.addOption(?[:0]const u8, "jvm", cg_opt.nix.jvm);
opts.addOption(?[:0]const u8, "fennel.lua", cg_opt.nix.@"fennel.lua"); opts.addOption(?[:0]const u8, "fennel.lua", cg_opt.nix.@"fennel.lua");
lib.root_module.addImport("opts", opts.createModule()); lib.root_module.addImport("opts", opts.createModule());

View file

@ -1,6 +1,8 @@
//! Module for the JDTLS java language server, including utilities //! Module for the JDTLS java language server, including utilities
//! for setting up nvim-jdtls //! for setting up nvim-jdtls
const std = @import("std"); const std = @import("std");
const opts = @import("opts");
const ser = @import("../ser.zig"); const ser = @import("../ser.zig");
const ffi = @import("../ffi.zig"); const ffi = @import("../ffi.zig");
const c = ffi.c; const c = ffi.c;
@ -17,7 +19,11 @@ const Runtime = struct {
version: [:0]const u8, version: [:0]const u8,
name: [:0]const u8, name: [:0]const u8,
}; };
// Name is not arbitrary and must match `enum ExecutionEnvironment`.
// See: https://github.com/eclipse-jdtls/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line#initialize-request
const runtime_map = [_]Runtime{ const runtime_map = [_]Runtime{
.{ .version = "19", .name = "JavaSE-19" },
.{ .version = "18", .name = "JavaSE-18" }, .{ .version = "18", .name = "JavaSE-18" },
.{ .version = "17", .name = "JavaSE-17" }, .{ .version = "17", .name = "JavaSE-17" },
.{ .version = "16", .name = "JavaSE-16" }, .{ .version = "16", .name = "JavaSE-16" },
@ -35,7 +41,15 @@ const runtime_map = [_]Runtime{
}; };
fn lFindRuntimes(l: *c.lua_State) !c_int { fn lFindRuntimes(l: *c.lua_State) !c_int {
var jvmdir = try std.fs.openDirAbsolute("/usr/lib/jvm/", .{ .iterate = true }); const jvmpath = opts.jvm orelse "/usr/lib/jvm";
var jvmdir = std.fs.openDirAbsolute(jvmpath, .{ .iterate = true }) catch |e| switch (e) {
error.FileNotFound => {
std.log.warn("JVM Path @ '{s}' does not exist! Not registering any runtimes!", .{jvmpath});
c.lua_newtable(l);
return 1;
},
else => return e,
};
defer jvmdir.close(); defer jvmdir.close();
c.lua_newtable(l); c.lua_newtable(l);
@ -44,7 +58,8 @@ fn lFindRuntimes(l: *c.lua_State) !c_int {
var idx: c_int = 1; var idx: c_int = 1;
var iter = jvmdir.iterate(); var iter = jvmdir.iterate();
while (try iter.next()) |jvm| { while (try iter.next()) |jvm| {
if (jvm.kind != .directory or !std.mem.startsWith(u8, jvm.name, "java-")) if ((jvm.kind != .directory and jvm.kind != .sym_link) or
!std.mem.startsWith(u8, jvm.name, "java-"))
continue; continue;
for (runtime_map) |rt| { for (runtime_map) |rt| {
@ -55,7 +70,7 @@ fn lFindRuntimes(l: *c.lua_State) !c_int {
// and a path field (path to the runtime's home) // and a path field (path to the runtime's home)
ser.luaPushAny(l, .{ ser.luaPushAny(l, .{
.name = rt.name, .name = rt.name,
.path = try std.fmt.bufPrintZ(&buf, "/usr/lib/jvm/{s}/", .{jvm.name}), .path = try std.fmt.bufPrintZ(&buf, jvmpath ++ "/{s}/", .{jvm.name}),
}); });
// append table to list // append table to list

View file

@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const common = @import("common");
pub fn build(b: *std.Build) void { pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{}); const optimize = b.standardOptimizeOption(.{});
@ -11,7 +12,17 @@ pub fn build(b: *std.Build) void {
.optimize = optimize, .optimize = optimize,
}); });
const cgopt = try common.confgenGet(struct {
nix: struct {
jvm: ?[:0]const u8 = null,
},
}, b.allocator);
const opts = b.addOptions();
opts.addOption(?[:0]const u8, "jvm", cgopt.nix.jvm);
exe.root_module.addImport("common", b.dependency("common", .{}).module("common")); exe.root_module.addImport("common", b.dependency("common", .{}).module("common"));
exe.root_module.addImport("opts", opts.createModule());
b.installArtifact(exe); b.installArtifact(exe);

View file

@ -1,4 +1,5 @@
const std = @import("std"); const std = @import("std");
const opts = @import("opts");
pub const std_options = std.Options{ pub const std_options = std.Options{
.log_level = .debug, .log_level = .debug,
@ -21,7 +22,7 @@ pub fn main() !u8 {
if (env.getPtr("PATH")) |path_p| { if (env.getPtr("PATH")) |path_p| {
const newpath = try std.fmt.allocPrint( const newpath = try std.fmt.allocPrint(
alloc, alloc,
"/usr/lib/jvm/{s}/bin:{s}", (opts.jvm orelse "/usr/lib/jvm") ++ "/{s}/bin:{s}",
.{ std.os.argv[1], path_p.* }, .{ std.os.argv[1], path_p.* },
); );
alloc.free(path_p.*); alloc.free(path_p.*);