135 lines
4.3 KiB
Lua
135 lines
4.3 KiB
Lua
|
local util = require 'lspconfig.util'
|
||
|
|
||
|
local function get_default_mavenrepo()
|
||
|
local repo = util.path.join(vim.env.HOME, '.m2', 'repository', 'dk', 'au', 'ece', 'vdmj')
|
||
|
if util.path.exists(repo) then
|
||
|
return repo
|
||
|
else
|
||
|
return util.path.join(vim.env.HOME, '.m2', 'repository', 'com', 'fujitsu')
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function get_jar_path(config, package, version)
|
||
|
return util.path.join(config.options.mavenrepo, package, version, package .. '-' .. version .. '.jar')
|
||
|
end
|
||
|
|
||
|
local function with_precision(version, is_high_precision)
|
||
|
return is_high_precision and version:gsub('([%d.]+)', '%1-P') or version
|
||
|
end
|
||
|
|
||
|
local function get_latest_installed_version(repo)
|
||
|
local path = util.path.join(repo, 'lsp')
|
||
|
local sort = vim.fn.sort
|
||
|
|
||
|
local subdirs = function(file)
|
||
|
local stat = vim.loop.fs_stat(util.path.join(path, file))
|
||
|
return stat.type == 'directory' and 1 or 0
|
||
|
end
|
||
|
|
||
|
local candidates = vim.fn.readdir(path, subdirs)
|
||
|
local sorted = sort(sort(candidates, 'l'), 'N')
|
||
|
return sorted[#sorted]
|
||
|
end
|
||
|
|
||
|
-- Special case, as vdmj store particular settings under root_dir/.vscode
|
||
|
local function find_vscode_ancestor(startpath)
|
||
|
return util.search_ancestors(startpath, function(path)
|
||
|
if util.path.is_dir(util.path.join(path, '.vscode')) then
|
||
|
return path
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
return {
|
||
|
default_config = {
|
||
|
cmd = { 'java' },
|
||
|
filetypes = { 'vdmsl', 'vdmpp', 'vdmrt' },
|
||
|
root_dir = function(fname)
|
||
|
return util.find_git_ancestor(fname) or find_vscode_ancestor(fname)
|
||
|
end,
|
||
|
options = {
|
||
|
java = vim.env.JAVA_HOME and util.path.join(vim.env.JAVA_HOME, 'bin', 'java') or 'java',
|
||
|
java_opts = { '-Xmx3000m', '-Xss1m' },
|
||
|
annotation_paths = {},
|
||
|
mavenrepo = get_default_mavenrepo(),
|
||
|
logfile = util.path.join(vim.fn.stdpath 'cache', 'vdm-lsp.log'),
|
||
|
debugger_port = -1,
|
||
|
high_precision = false,
|
||
|
},
|
||
|
},
|
||
|
docs = {
|
||
|
description = [[
|
||
|
https://github.com/nickbattle/vdmj
|
||
|
|
||
|
The VDMJ language server can be installed by cloning the VDMJ repository and
|
||
|
running `mvn clean install`.
|
||
|
|
||
|
Various options are provided to configure the language server (see below). In
|
||
|
particular:
|
||
|
- `annotation_paths` is a list of folders and/or jar file paths for annotations
|
||
|
that should be used with the language server;
|
||
|
- any value of `debugger_port` less than zero will disable the debugger; note
|
||
|
that if a non-zero value is used, only one instance of the server can be active
|
||
|
at a time.
|
||
|
|
||
|
More settings for VDMJ can be changed in a file called `vdmj.properties` under
|
||
|
`root_dir/.vscode`. For a description of the available settings, see
|
||
|
[Section 7 of the VDMJ User Guide](https://raw.githubusercontent.com/nickbattle/vdmj/master/vdmj/documentation/UserGuide.pdf).
|
||
|
|
||
|
Note: proof obligations and combinatorial testing are not currently supported
|
||
|
by neovim.
|
||
|
]],
|
||
|
default_config = {
|
||
|
cmd = 'Generated from the options given',
|
||
|
root_dir = 'util.find_git_ancestor(fname) or find_vscode_ancestor(fname)',
|
||
|
options = {
|
||
|
java = '$JAVA_HOME/bin/java',
|
||
|
java_opts = { '-Xmx3000m', '-Xss1m' },
|
||
|
annotation_paths = {},
|
||
|
mavenrepo = '$HOME/.m2/repository/dk/au/ece/vdmj',
|
||
|
version = 'The latest version installed in `mavenrepo`',
|
||
|
logfile = "path.join(vim.fn.stdpath 'cache', 'vdm-lsp.log')",
|
||
|
debugger_port = -1,
|
||
|
high_precision = false,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
on_new_config = function(config, root_dir)
|
||
|
local version = with_precision(
|
||
|
config.options.version or get_latest_installed_version(config.options.mavenrepo),
|
||
|
config.options.high_precision
|
||
|
)
|
||
|
|
||
|
local classpath = table.concat({
|
||
|
get_jar_path(config, 'vdmj', version),
|
||
|
get_jar_path(config, 'annotations', version),
|
||
|
get_jar_path(config, 'lsp', version),
|
||
|
util.path.join(root_dir, '.vscode'),
|
||
|
unpack(config.options.annotation_paths),
|
||
|
}, ':')
|
||
|
|
||
|
local java_cmd = {
|
||
|
config.options.java,
|
||
|
config.options.java_opts,
|
||
|
'-Dlsp.log.filename=' .. config.options.logfile,
|
||
|
'-cp',
|
||
|
classpath,
|
||
|
}
|
||
|
|
||
|
local dap = {}
|
||
|
|
||
|
if config.options.debugger_port >= 0 then
|
||
|
-- TODO: LS will fail to start if port is already in use
|
||
|
dap = { '-dap', tostring(config.options.debugger_port) }
|
||
|
end
|
||
|
|
||
|
local vdmj_cmd = {
|
||
|
'lsp.LSPServerStdio',
|
||
|
'-' .. vim.bo.filetype,
|
||
|
dap,
|
||
|
}
|
||
|
|
||
|
config.cmd = vim.tbl_flatten { java_cmd, vdmj_cmd }
|
||
|
end,
|
||
|
}
|