-
-
Notifications
You must be signed in to change notification settings - Fork 85
Expand file tree
/
Copy pathcmd.lua
More file actions
161 lines (131 loc) · 4.57 KB
/
cmd.lua
File metadata and controls
161 lines (131 loc) · 4.57 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
local List = require('java-core.utils.list')
local path = require('java-core.utils.path')
local Manager = require('pkgm.manager')
local conf = require('java.config')
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 M = {}
local jdtls_root = Manager:get_install_dir('jdtls', conf.jdtls.version)
--- Returns a function that returns the command to start jdtls
---@param opts { use_lombok: boolean }
function M.get_cmd(opts)
---@param dispatchers? vim.lsp.rpc.Dispatchers
---@param config vim.lsp.ClientConfig
return function(dispatchers, config)
local cmd = M.get_jvm_args(opts):concat(M.get_jar_args())
-- 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 conf.jdk.auto_install then
M.validate_java_version(config.cmd_env)
end
log.debug('Starting jdtls with cmd', cmd)
local result = vim.lsp.rpc.start(cmd, dispatchers, {
cwd = config.cmd_cwd,
env = config.cmd_env,
detached = config.detached,
})
return result
end
end
---@private
---@param opts { use_lombok: boolean }
---@return java-core.List
function M.get_jvm_args(opts)
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 conf.jdk.auto_install then
local jdk_root = Manager:get_install_dir('openjdk', conf.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 opts.use_lombok then
local lombok_root = Manager:get_install_dir('lombok', conf.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 cwd? string
---@return java-core.List
function M.get_jar_args(cwd)
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 env table
function M.validate_java_version(env)
local curr_ver = M.get_java_major_version(env)
local exp_ver = java_version_map[conf.jdtls.version]
if not (curr_ver >= exp_ver.to and curr_ver <= exp_ver.from) then
local msg = string.format(
'Java version mismatch: JDTLS %s requires Java %d <= java >= %d, but found Java %d',
conf.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