Skip to content

Commit f1ae757

Browse files
committed
feat: add apply refactoring command handler
1 parent 934a312 commit f1ae757

File tree

4 files changed

+254
-12
lines changed

4 files changed

+254
-12
lines changed

lua/java-refactor/lsp-refactor-commands.lua

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
-- local ui = require('java.utils.ui')
1+
local runner = require('async.runner')
2+
local get_error_handler = require('java-refactor.utils.error_handler')
3+
local RefactorCommands = require('java-refactor.refactor-commands')
24

35
local M = {
46

57
commands = {
6-
-- ['java.action.applyRefactoringCommand'] = function() end,
7-
88
---@class java-refactor.RenameAction
99
---@field length number
1010
---@field offset number
@@ -32,6 +32,30 @@ local M = {
3232
})
3333
end
3434
end,
35+
36+
---@class java-refactor.ApplyRefactoringCommandInfo
37+
---@field bufnr number
38+
---@field client_id number
39+
---@field method string
40+
---@field params lsp.CodeActionContext
41+
42+
---comment
43+
---@param command lsp.Command
44+
---@param command_info java-refactor.ApplyRefactoringCommandInfo
45+
['java.action.applyRefactoringCommand'] = function(command, command_info)
46+
runner(function()
47+
local refactor_type = command.arguments[1] --[[@as jdtls.CodeActionCommand]]
48+
local context = command_info.params
49+
50+
local client = vim.lsp.get_client_by_id(command_info.client_id)
51+
52+
---@type java-refactor.RefactorCommands
53+
local refactor_commands = RefactorCommands(client)
54+
refactor_commands:refactor(refactor_type, context)
55+
end)
56+
.catch(get_error_handler('Failed to run refactoring command'))
57+
.run()
58+
end,
3559
},
3660
}
3761

@@ -49,3 +73,8 @@ id = vim.api.nvim_create_autocmd('LspAttach', {
4973
end
5074
end,
5175
})
76+
77+
---@class java-refactor.RefactorContext
78+
---@field context { diagnostics: any[], triggerKind: number }
79+
---@field range nvim.Range
80+
---@field textDocument { uri: string }

lua/java-refactor/refactor-commands.lua

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@ local notify = require('java-core.utils.notify')
33
local JdtlsClient = require('java-core.ls.clients.jdtls-client')
44

55
---@class java-refactor.RefactorCommands
6-
---@field client vim.lsp.Client
76
---@field jdtls_client java-core.JdtlsClient
87
local RefactorCommands = class()
98

109
---@param client vim.lsp.Client
1110
function RefactorCommands:_init(client)
12-
self.client = client
1311
self.jdtls_client = JdtlsClient(client)
1412
end
1513

1614
---Run refactor command
1715
---@param refactor_type jdtls.CodeActionCommand
18-
function RefactorCommands:refactor(refactor_type)
19-
local context = vim.lsp.util.make_range_params(0)
20-
context.context = {}
21-
context.context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(0)
16+
---@param context lsp.CodeActionContext
17+
function RefactorCommands:refactor(refactor_type, context)
18+
if not context then
19+
context = vim.lsp.util.make_range_params(0)
20+
context.context = {}
21+
context.context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(0)
22+
end
2223

2324
local formatting_options = {
2425
tabSize = vim.bo.tabstop,
@@ -27,8 +28,15 @@ function RefactorCommands:refactor(refactor_type)
2728

2829
local buffer = vim.api.nvim_get_current_buf()
2930

30-
local selection =
31-
self.jdtls_client:java_infer_selection(refactor_type, context, buffer)
31+
local selection = {}
32+
33+
if
34+
context.range.start.character == context.range['end'].character
35+
and context.range.start.line == context.range['end'].line
36+
then
37+
selection =
38+
self.jdtls_client:java_infer_selection(refactor_type, context, buffer)
39+
end
3240

3341
local edit = self.jdtls_client:java_get_refactor_edit(
3442
refactor_type,
@@ -38,6 +46,11 @@ function RefactorCommands:refactor(refactor_type)
3846
buffer
3947
)
4048

49+
if not edit then
50+
notify.warn('No edits suggested for action')
51+
return
52+
end
53+
4154
vim.lsp.util.apply_workspace_edit(edit.edit, 'utf-8')
4255

4356
RefactorCommands.run_lsp_client_command(
@@ -47,7 +60,6 @@ function RefactorCommands:refactor(refactor_type)
4760
end
4861

4962
function RefactorCommands.run_lsp_client_command(command_name, arguments)
50-
-- vim.print(command_name, arguments)
5163
local command = vim.lsp.commands[command_name]
5264

5365
if not command then
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
local notify = require('java-core.utils.notify')
2+
local log = require('java-refactor.utils.log')
3+
4+
local function table_tostring(tbl)
5+
local str = ''
6+
for _, v in ipairs(tbl) do
7+
str = str .. '\n' .. tostring(v)
8+
end
9+
10+
return str
11+
end
12+
13+
---Returns a error handler
14+
---@param msg string messages to show in the error
15+
---@return fun(err: any) # function that log and notify the error
16+
local function get_error_handler(msg)
17+
return function(err)
18+
local trace = debug.traceback()
19+
20+
local log_obj = { msg }
21+
table.insert(log_obj, err)
22+
table.insert(log_obj, trace)
23+
24+
local log_str = table_tostring(log_obj)
25+
26+
log.error(log_str)
27+
notify.error(log_str)
28+
error(log_str)
29+
end
30+
end
31+
32+
return get_error_handler

lua/java-refactor/utils/log.lua

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
--[[
2+
--FROM: https://github.com/tjdevries/vlog.nvim
3+
--]]
4+
5+
-- log.lua
6+
--
7+
-- Inspired by rxi/log.lua
8+
-- Modified by tjdevries and can be found at github.com/tjdevries/vlog.nvim
9+
--
10+
-- This library is free software; you can redistribute it and/or modify it
11+
-- under the terms of the MIT license. See LICENSE for details.
12+
13+
-- User configuration section
14+
local default_config = {
15+
-- Name of the plugin. Prepended to log messages
16+
plugin = 'nvim-java-refactor',
17+
18+
-- Should print the output to neovim while running
19+
use_console = false,
20+
21+
-- Should highlighting be used in console (using echohl)
22+
highlights = true,
23+
24+
-- Should write to a file
25+
use_file = true,
26+
27+
-- Any messages above this level will be logged.
28+
level = 'trace',
29+
30+
-- Level configuration
31+
modes = {
32+
{ name = 'trace', hl = 'Comment' },
33+
{ name = 'debug', hl = 'Comment' },
34+
{ name = 'info', hl = 'None' },
35+
{ name = 'warn', hl = 'WarningMsg' },
36+
{ name = 'error', hl = 'ErrorMsg' },
37+
{ name = 'fatal', hl = 'ErrorMsg' },
38+
},
39+
40+
-- Can limit the number of decimals displayed for floats
41+
float_precision = 0.01,
42+
}
43+
44+
-- {{{ NO NEED TO CHANGE
45+
local log = {}
46+
47+
local unpack = unpack or table.unpack
48+
49+
log.new = function(config, standalone)
50+
config = vim.tbl_deep_extend('force', default_config, config)
51+
52+
local outfile = string.format(
53+
'%s/%s.log',
54+
vim.api.nvim_call_function('stdpath', { 'data' }),
55+
config.plugin
56+
)
57+
58+
local obj
59+
if standalone then
60+
obj = log
61+
else
62+
obj = {}
63+
end
64+
65+
local levels = {}
66+
for i, v in ipairs(config.modes) do
67+
levels[v.name] = i
68+
end
69+
70+
local round = function(x, increment)
71+
increment = increment or 1
72+
x = x / increment
73+
return (x > 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)) * increment
74+
end
75+
76+
local make_string = function(...)
77+
local t = {}
78+
for i = 1, select('#', ...) do
79+
local x = select(i, ...)
80+
81+
if type(x) == 'number' and config.float_precision then
82+
x = tostring(round(x, config.float_precision))
83+
elseif type(x) == 'table' then
84+
x = vim.inspect(x)
85+
else
86+
x = tostring(x)
87+
end
88+
89+
t[#t + 1] = x
90+
end
91+
return table.concat(t, ' ')
92+
end
93+
94+
local log_at_level = function(level, level_config, message_maker, ...)
95+
-- Return early if we're below the config.level
96+
if level < levels[config.level] then
97+
return
98+
end
99+
local nameupper = level_config.name:upper()
100+
101+
local msg = message_maker(...)
102+
local info = debug.getinfo(2, 'Sl')
103+
local lineinfo = info.short_src .. ':' .. info.currentline
104+
105+
-- Output to console
106+
if config.use_console then
107+
local console_string = string.format(
108+
'[%-6s%s] %s: %s',
109+
nameupper,
110+
os.date('%H:%M:%S'),
111+
lineinfo,
112+
msg
113+
)
114+
115+
if config.highlights and level_config.hl then
116+
vim.cmd(string.format('echohl %s', level_config.hl))
117+
end
118+
119+
local split_console = vim.split(console_string, '\n')
120+
for _, v in ipairs(split_console) do
121+
vim.cmd(
122+
string.format(
123+
[[echom "[%s] %s"]],
124+
config.plugin,
125+
vim.fn.escape(v, '"')
126+
)
127+
)
128+
end
129+
130+
if config.highlights and level_config.hl then
131+
vim.cmd('echohl NONE')
132+
end
133+
end
134+
135+
-- Output to log file
136+
if config.use_file then
137+
local fp = io.open(outfile, 'a')
138+
local str =
139+
string.format('[%-6s%s] %s: %s\n', nameupper, os.date(), lineinfo, msg)
140+
assert(fp, 'cannot open file: ' .. ' to write logs')
141+
fp:write(str)
142+
fp:close()
143+
end
144+
end
145+
146+
for i, x in ipairs(config.modes) do
147+
obj[x.name] = function(...)
148+
return log_at_level(i, x, make_string, ...)
149+
end
150+
151+
obj[('fmt_%s'):format(x.name)] = function(...)
152+
local passed = { ... }
153+
return log_at_level(i, x, function()
154+
local fmt = table.remove(passed, 1)
155+
local inspected = {}
156+
for _, v in ipairs(passed) do
157+
table.insert(inspected, vim.inspect(v))
158+
end
159+
return string.format(fmt, unpack(inspected))
160+
end)
161+
end
162+
end
163+
164+
return obj
165+
end
166+
167+
log.new(default_config, true)
168+
169+
return log

0 commit comments

Comments
 (0)