mirror of
https://github.com/mfussenegger/nvim-jdtls
synced 2024-09-16 14:34:13 +02:00
Add support for decompiling .class files
Requires https://github.com/eclipse/eclipse.jdt.ls/pull/2515
This commit is contained in:
parent
34202bc141
commit
f8fb45e05e
3 changed files with 51 additions and 67 deletions
|
@ -120,16 +120,15 @@ M.jol({mode?}, {classname?}) *jdtls.jol*
|
||||||
{classname?} (string) fully qualified class name. Defaults to the current class.
|
{classname?} (string) fully qualified class name. Defaults to the current class.
|
||||||
|
|
||||||
|
|
||||||
M.open_jdt_link() *jdtls.open_jdt_link*
|
M.open_classfile({fname}) *jdtls.open_classfile*
|
||||||
Reads the uri into the current buffer
|
Open `jdt://` uri or decompile class contents and load them into the buffer
|
||||||
|
|
||||||
This requires at least one open buffer that is connected to the jdtls
|
|
||||||
language server.
|
|
||||||
|
|
||||||
nvim-jdtls by defaults configures a `BufReadCmd` event which uses this function.
|
nvim-jdtls by defaults configures a `BufReadCmd` event which uses this function.
|
||||||
You shouldn't need to call this manually.
|
You shouldn't need to call this manually.
|
||||||
|
|
||||||
@param uri string expected to be a `jdt://` uri
|
|
||||||
|
Parameters: ~
|
||||||
|
{fname} (string)
|
||||||
|
|
||||||
|
|
||||||
M.set_runtime({runtime}) *jdtls.set_runtime*
|
M.set_runtime({runtime}) *jdtls.set_runtime*
|
||||||
|
|
104
lua/jdtls.lua
104
lua/jdtls.lua
|
@ -1092,77 +1092,61 @@ function M.jol(mode, classname)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Reads the uri into the current buffer
|
--- Open `jdt://` uri or decompile class contents and load them into the buffer
|
||||||
---
|
|
||||||
--- This requires at least one open buffer that is connected to the jdtls
|
|
||||||
--- language server.
|
|
||||||
---
|
---
|
||||||
--- nvim-jdtls by defaults configures a `BufReadCmd` event which uses this function.
|
--- nvim-jdtls by defaults configures a `BufReadCmd` event which uses this function.
|
||||||
--- You shouldn't need to call this manually.
|
--- You shouldn't need to call this manually.
|
||||||
---
|
---
|
||||||
--- @param uri string expected to be a `jdt://` uri
|
---@param fname string
|
||||||
function M.open_jdt_link(uri)
|
function M.open_classfile(fname)
|
||||||
local client
|
local uri
|
||||||
for _, c in ipairs(vim.lsp.get_active_clients()) do
|
local use_cmd
|
||||||
if c.config.init_options
|
if vim.startswith(fname, "jdt://") then
|
||||||
and c.config.init_options.extendedClientCapabilities
|
uri = fname
|
||||||
and c.config.init_options.extendedClientCapabilities.classFileContentsSupport then
|
use_cmd = false
|
||||||
|
|
||||||
client = c
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
assert(client, 'Must have a buffer open with a language client connected to eclipse.jdt.ls to load JDT URI')
|
|
||||||
local buf = api.nvim_get_current_buf()
|
|
||||||
local params = {
|
|
||||||
uri = uri
|
|
||||||
}
|
|
||||||
local response = nil
|
|
||||||
local cb = function(err, result)
|
|
||||||
response = {err, result}
|
|
||||||
end
|
|
||||||
local ok, request_id = client.request('java/classFileContents', params, cb, buf)
|
|
||||||
assert(ok, 'Request to `java/classFileContents` must succeed to open JDT URI. Client shutdown?')
|
|
||||||
local timeout_ms = M.settings.jdt_uri_timeout_ms
|
|
||||||
local wait_ok, reason = vim.wait(timeout_ms, function() return response end)
|
|
||||||
local log_path = require('jdtls.path').join(vim.fn.stdpath('cache'), 'lsp.log')
|
|
||||||
local buf_content
|
|
||||||
if wait_ok and #response == 2 and response[2] then
|
|
||||||
local content = response[2]
|
|
||||||
if content == "" then
|
|
||||||
buf_content = {
|
|
||||||
'Received response from server, but it was empty. Check the log file for errors', log_path}
|
|
||||||
else
|
|
||||||
buf_content = vim.split(response[2], '\n', { plain = true })
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
local error_msg
|
uri = vim.uri_from_fname(fname)
|
||||||
if not wait_ok then
|
use_cmd = true
|
||||||
client.cancel_request(request_id)
|
if not vim.startswith(uri, "file://") then
|
||||||
local wait_failure = {
|
return
|
||||||
[-1] = 'timeout';
|
|
||||||
[-2] = 'interrupted';
|
|
||||||
[-3] = 'error'
|
|
||||||
}
|
|
||||||
error_msg = wait_failure[reason]
|
|
||||||
else
|
|
||||||
error_msg = response[1]
|
|
||||||
end
|
end
|
||||||
buf_content = {
|
|
||||||
'Failed to load content for uri',
|
|
||||||
uri,
|
|
||||||
'',
|
|
||||||
'Error was: ',
|
|
||||||
}
|
|
||||||
vim.list_extend(buf_content, vim.split(vim.inspect(error_msg), '\n'))
|
|
||||||
vim.list_extend(buf_content, {'', 'Check the log file for errors', log_path})
|
|
||||||
end
|
end
|
||||||
|
local buf = api.nvim_get_current_buf()
|
||||||
vim.bo[buf].modifiable = true
|
vim.bo[buf].modifiable = true
|
||||||
vim.bo[buf].swapfile = false
|
vim.bo[buf].swapfile = false
|
||||||
vim.bo[buf].buftype = 'nofile'
|
vim.bo[buf].buftype = 'nofile'
|
||||||
api.nvim_buf_set_lines(buf, 0, -1, false, buf_content)
|
-- This triggers FileType event which should fire up the lsp client if not already running
|
||||||
vim.bo[buf].filetype = 'java'
|
vim.bo[buf].filetype = 'java'
|
||||||
vim.bo[buf].modifiable = false
|
local timeout_ms = M.settings.jdt_uri_timeout_ms
|
||||||
|
vim.wait(timeout_ms, function()
|
||||||
|
return next(vim.lsp.get_active_clients({ name = "jdtls", bufnr = buf })) ~= nil
|
||||||
|
end)
|
||||||
|
local client = vim.lsp.get_active_clients({ name = "jdtls", bufnr = buf })[1]
|
||||||
|
assert(client, 'Must have a `jdtls` client to load class file or jdt uri')
|
||||||
|
|
||||||
|
local content
|
||||||
|
local function handler(err, result)
|
||||||
|
assert(not err, vim.inspect(err))
|
||||||
|
content = result
|
||||||
|
api.nvim_buf_set_lines(buf, 0, -1, false, vim.split(result, "\n", { plain = true }))
|
||||||
|
vim.bo[buf].modifiable = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_cmd then
|
||||||
|
local command = {
|
||||||
|
command = "java.decompile",
|
||||||
|
arguments = { uri }
|
||||||
|
}
|
||||||
|
execute_command(command, handler)
|
||||||
|
else
|
||||||
|
local params = {
|
||||||
|
uri = uri
|
||||||
|
}
|
||||||
|
client.request("java/classFileContents", params, handler, buf)
|
||||||
|
end
|
||||||
|
-- Need to block. Otherwise logic could run that sets the cursor to a position
|
||||||
|
-- that's still missing.
|
||||||
|
vim.wait(timeout_ms, function() return content ~= nil end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ if exists('g:nvim_jdtls')
|
||||||
endif
|
endif
|
||||||
let g:nvim_jdtls = 1
|
let g:nvim_jdtls = 1
|
||||||
|
|
||||||
au BufReadCmd jdt://* lua require('jdtls').open_jdt_link(vim.fn.expand('<amatch>'))
|
au BufReadCmd jdt://* lua require('jdtls').open_classfile(vim.fn.expand('<amatch>'))
|
||||||
|
au BufReadCmd *.class lua require("jdtls").open_classfile(vim.fn.expand("<amatch>"))
|
||||||
command! JdtWipeDataAndRestart lua require('jdtls.setup').wipe_data_and_restart()
|
command! JdtWipeDataAndRestart lua require('jdtls.setup').wipe_data_and_restart()
|
||||||
command! JdtShowLogs lua require('jdtls.setup').show_logs()
|
command! JdtShowLogs lua require('jdtls.setup').show_logs()
|
||||||
|
|
Loading…
Reference in a new issue