A Neovim plugin designed to streamline Minecraft mod development with Fabric Loom.
- Fabric Loom DAP Adapter: Launch and attach to Minecraft dev instances directly from Neovim via
./gradlew. - Launch Configurations: Load custom run configurations generated by Gradle (
.nvim/launch.json). - ASM & Bytecode Inspection: Easily inspect class bytecode or ASM API generation code.
- Bundled Syntax Highlighting: Includes syntax highlighting for OW2 ASM Textifier bytecode output (
asm-java). - Clean
jdt://URI Formatting: Automatically resolves rawjdt://URIs into readable Java class names in your statusline and quickfix list. - Isolated
jdtlsWorkspaces: Automatically configures project-isolated workspace cache directories forjdtls.
- Neovim v0.10+
- mfussenegger/nvim-jdtls
- mfussenegger/nvim-dap
jdtlsexecutable installed (e.g. via mason.nvim)java-debug-adapter(required for debugging support)
- JavaHello/java-deps.nvim – View project Java dependencies.
- tunaflsh/follow-md-links.nvim – Open
jdt://URIs when following links.
To generate Neovim launch configurations (.nvim/launch.json) that minecraft-dev.nvim and nvim-dap can consume, add the neovim Gradle task to your build.gradle file:
import groovy.json.JsonOutput
tasks.register('neovim') {
group = 'ide'
description = 'Generates Neovim launch configurations.'
doLast {
def runsData = loom.runs.collect { run ->
def taskName = "run${run.name.capitalize()}"
[
type: "fabric-loom",
taskName: taskName,
name: "${run.configName} (gradlew ${taskName})",
request: "launch",
console: "integratedTerminal"
]
}
def rootData = [
version: "1.0.0",
configurations: runsData
]
def outputFile = file(".nvim/launch.json")
outputFile.parentFile.mkdirs()
outputFile.text = JsonOutput.prettyPrint(JsonOutput.toJson(rootData))
}
}Then generate your configurations by running:
./gradlew neovimSometimes jdtls gets your project name wrong. Put this at the top of your build.gradle:
plugins {
id 'eclipse'
}
eclipse {
project {
name = rootProject.name
}
}Below is an example configuration using vim.pack.add, incorporating nvim-jdtls, nvim-dap, mason.nvim, and related Java utilities:
vim.pack.add({
'https://github.com/tunaflsh/minecraft-dev.nvim',
'https://codeberg.org/mfussenegger/nvim-jdtls',
'https://codeberg.org/mfussenegger/nvim-dap',
'https://github.com/JavaHello/java-deps.nvim',
'https://mason-org/mason.nvim',
{
src = 'https://github.com/tunaflsh/follow-md-links.nvim',
version = 'custom-handler',
},
}, { load = true })
-- Enable opening jdt:// URIs in LSP hovers
require('follow-md-links').handler = function(link)
if vim.startswith(link, 'jdt://') then
vim.cmd.split(vim.fn.fnameescape(link))
return true
end
end
-- Preview Java dependencies
local javadeps = require('java-deps')
javadeps.setup({
keymaps = { toggle_fold = '<cr>' },
position = 'left',
})
local mcdev = require('minecraft-dev')
local mason_dir = require('mason.settings').current.install_root_dir
local jdtls = require('jdtls')
mcdev.setup({
statusline = vim.o.statusline,
-- See api-win_config
win_config = { win = -1, split = 'right' }, -- split far right
-- Envars for the Minecraft instance can be set here
env = { -- E.g. to ensure Minecraft is running on a NVIDIA dGPU
__NV_PRIME_RENDER_OFFLOAD = 1,
__VK_LAYER_NV_optimus = 'NVIDIA_only',
__GLX_VENDOR_LIBRARY_NAME = 'nvidia',
},
-- See nvim-jdtls
jdtls_config = {
init_options = {
bundles = {
vim.fn.glob( -- :MasonInstall java-debug-adapter
mason_dir .. '/share/java-debug-adapter/com.microsoft.java.debug.plugin-*.jar',
true
),
vim.fn.glob( -- :MasonInstall vscode-java-dependencies
mason_dir .. '/share/vscode-java-dependency/com.microsoft.jdtls.ext.core-*.jar',
true
),
},
},
on_attach = function(client, bufnr)
local command = function(name, cmd, desc)
vim.api.nvim_buf_create_user_command(bufnr, name, cmd, { desc = desc })
end
command('Asmify', mcdev.asmify, 'View ASM API calls')
command('Bytecode', mcdev.bytecode, 'View ASM bytecode')
command('Deps', javadeps.toggle_outline, 'View dependencies')
local map = function(lhs, rhs)
vim.keymap.set('', lhs, rhs, { buf = bufnr })
end
-- These are additional capabilities provided by jdtls
-- For built-in LSP mappings, check `:help lsp-defaults`
map('gro', jdtls.organize_imports)
map('grv', jdtls.extract_variable_all)
map('grc', jdtls.extract_constant)
map('grm', jdtls.extract_method)
end,
},
})require('minecraft-dev').setup({
-- Filetypes to which jdtls will attach
filetypes = { 'java', 'groovy', 'kotlin', 'jproperties' },
-- Format statusline occurrences of %f, %F, or %t resolving jdt:// URIs
statusline = nil,
-- Resolve jdt:// URIs in quickfix list to fully qualified class names
quickfixtextfunc = true,
-- Window configuration for opening ASM / Bytecode split windows
win_config = nil,
-- Environment variables passed when launching Minecraft
env = {},
-- Configuration passed directly to jdtls.start_or_attach()
jdtls_config = {
cmd = { 'jdtls' },
},
})You can verify your setup at any time by running:
:checkhealth minecraft-devThis checks for required plugins (nvim-jdtls, nvim-dap), external tools (jdtls), debug adapters (java-debug-adapter), and project configuration files (.nvim/launch.json).