-
-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathcmd.lua
More file actions
177 lines (147 loc) · 5.2 KB
/
cmd.lua
File metadata and controls
177 lines (147 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
local List = require('java-core.utils.list')
local path = require('java-core.utils.path')
local Manager = require('pkgm.manager')
local system = require('java-core.utils.system')
local log = require('java-core.utils.log2')
local err = require('java-core.utils.errors')
local java_version_map = require('java-core.constants.java_version')
local lsp_utils = require('java-core.utils.lsp')
local str = require('java-core.utils.str')
local M = {}
--- Returns a function that returns the command to start jdtls
---@param config java.Config
function M.get_cmd(config)
---@param dispatchers? vim.lsp.rpc.Dispatchers
---@param lsp_config vim.lsp.ClientConfig
return function(dispatchers, lsp_config)
local cmd = M.get_jvm_args(config):concat(M.get_jar_args(config))
-- NOTE: eventhough we are setting the PATH env var, due to a bug, it's not
-- working on Windows. So just lanching 'java' will result in executing the
-- system java. So as a workaround, we use the absolute path to java instead
-- So following check is not needed when we have auto_install set to true
-- @see https://github.com/neovim/neovim/issues/36818
if not config.jdk.auto_install then
M.validate_java_version(config, lsp_config.cmd_env)
end
log.debug('Starting jdtls with cmd', cmd)
local result = vim.lsp.rpc.start(cmd, dispatchers, {
cwd = lsp_config.cmd_cwd,
env = lsp_config.cmd_env,
detached = lsp_config.detached,
})
return result
end
end
---@private
---@param config java.Config
---@return java-core.List
function M.get_jvm_args(config)
local use_lombok = config.lombok.enable
local jdtls_root = Manager:get_install_dir('jdtls', config.jdtls.version)
local jdtls_config = path.join(jdtls_root, system.get_config_suffix())
local java_exe = 'java'
-- NOTE: eventhough we are setting the PATH env var, due to a bug, it's not
-- working on Windows. So we are using the absolute path to java instead
-- @see https://github.com/neovim/neovim/issues/36818
if config.jdk.auto_install then
local jdk_root = Manager:get_install_dir('openjdk', config.jdk.version)
local java_home
if system.get_os() == 'mac' then
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*', 'Contents', 'Home'))
else
java_home = vim.fn.glob(path.join(jdk_root, 'jdk-*'))
end
java_exe = path.join(java_home, 'bin', 'java')
end
local jvm_args = List:new({
java_exe,
'-Declipse.application=org.eclipse.jdt.ls.core.id1',
'-Dosgi.bundles.defaultStartLevel=4',
'-Declipse.product=org.eclipse.jdt.ls.core.product',
'-Dosgi.checkConfiguration=true',
'-Dosgi.sharedConfiguration.area=' .. jdtls_config,
'-Dosgi.sharedConfiguration.area.readOnly=true',
'-Dosgi.configuration.cascaded=true',
'-Xms1G',
'--add-modules=ALL-SYSTEM',
'--add-opens',
'java.base/java.util=ALL-UNNAMED',
'--add-opens',
'java.base/java.lang=ALL-UNNAMED',
})
-- Adding lombok
if use_lombok then
local lombok_root = Manager:get_install_dir('lombok', config.lombok.version)
local lombok_path = vim.fn.glob(path.join(lombok_root, 'lombok*.jar'))
jvm_args:push('-javaagent:' .. lombok_path)
end
return jvm_args
end
---@private
---@param config java.Config
---@param cwd? string
---@return java-core.List
function M.get_jar_args(config, cwd)
local jdtls_root = Manager:get_install_dir('jdtls', config.jdtls.version)
cwd = cwd or vim.fn.getcwd()
local launcher_reg = path.join(jdtls_root, 'plugins', 'org.eclipse.equinox.launcher_*.jar')
local equinox_launcher = vim.fn.glob(path.join(jdtls_root, 'plugins', 'org.eclipse.equinox.launcher_*.jar'))
if equinox_launcher == '' then
-- stylua: ignore
local msg = string.format('JDTLS equinox launcher not found. Expected path: %s. ', launcher_reg)
err.throw(msg)
end
return List:new({
'-jar',
equinox_launcher,
'-configuration',
lsp_utils.get_jdtls_cache_conf_path(),
'-data',
lsp_utils.get_jdtls_cache_data_path(cwd),
})
end
---@private
---@param config java.Config
---@param env table
function M.validate_java_version(config, env)
local curr_ver = M.get_java_major_version(env)
local exp_ver = java_version_map[config.jdtls.version]
if not exp_ver then
err.throw(
str.multiline(
'We maintain a jdlts to java version map to provide a better error message.',
'The jdtls version you are using is not supported yet',
'Please open an issue on https://github.com/nvim-java/nvim-java/issues',
'OR submit a PR',
'Version map:',
'https://github.com/nvim-java/nvim-java/blob/main/lua/java-core/constants/java_version.lua'
)
)
end
if not (curr_ver >= exp_ver.from and curr_ver <= exp_ver.to) then
local msg = string.format(
'Java version mismatch: JDTLS %s requires Java %d <= java >= %d, but found Java %d',
config.jdtls.version,
exp_ver.from,
exp_ver.to,
curr_ver
)
err.throw(msg)
end
end
---@private
---@param env table
function M.get_java_major_version(env)
local proc = vim.system({ 'java', '-version' }, { env = env }):wait()
local version = proc.stderr or proc.stdout or ''
local major = version:match('version (%d+)')
or version:match('version "(%d+)')
or version:match('openjdk (%d+)')
or version:match('java (%d+)')
if major then
return tonumber(major)
end
local msg = 'Could not determine java version from::' .. version
err.throw(msg)
end
return M