2020-04-19 14:43:55 +02:00
|
|
|
local api = vim.api
|
|
|
|
|
local fn = vim.fn
|
2020-04-19 16:00:26 +02:00
|
|
|
local luv = vim.loop
|
2020-04-19 14:43:55 +02:00
|
|
|
|
2020-05-08 11:22:59 +02:00
|
|
|
local utils = require'nvim-treesitter.utils'
|
2020-06-19 13:45:33 +02:00
|
|
|
local parsers = require'nvim-treesitter.parsers'
|
2020-04-19 16:00:26 +02:00
|
|
|
|
2020-05-08 11:22:59 +02:00
|
|
|
local M = {}
|
2020-04-19 14:43:55 +02:00
|
|
|
|
2020-06-22 11:56:55 +02:00
|
|
|
local function iter_cmd(cmd_list, i, lang)
|
|
|
|
|
if i == #cmd_list + 1 then return print('Treesitter parser for '..lang..' has been installed') end
|
2020-04-20 22:01:52 +02:00
|
|
|
|
2020-04-27 15:27:59 +02:00
|
|
|
local attr = cmd_list[i]
|
2020-04-20 22:01:52 +02:00
|
|
|
if attr.info then print(attr.info) end
|
|
|
|
|
|
2020-05-01 10:30:25 +02:00
|
|
|
local handle
|
|
|
|
|
|
2020-04-19 16:00:26 +02:00
|
|
|
handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code)
|
|
|
|
|
handle:close()
|
2020-05-01 10:30:25 +02:00
|
|
|
if code ~= 0 then return api.nvim_err_writeln(attr.err) end
|
2020-06-22 11:56:55 +02:00
|
|
|
iter_cmd(cmd_list, i + 1, lang)
|
2020-04-19 16:00:26 +02:00
|
|
|
end))
|
2020-04-19 14:43:55 +02:00
|
|
|
end
|
|
|
|
|
|
2020-06-29 16:07:16 +02:00
|
|
|
local function get_command(cmd)
|
|
|
|
|
local ret = ''
|
|
|
|
|
if cmd.opts and cmd.opts.cwd then
|
|
|
|
|
ret = string.format('cd %s;\n', cmd.opts.cwd)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
ret = string.format('%s%s ', ret, cmd.cmd)
|
|
|
|
|
|
|
|
|
|
local options = ""
|
|
|
|
|
if cmd.opts and cmd.opts.args then
|
|
|
|
|
for _, opt in ipairs(cmd.opts.args) do
|
|
|
|
|
options = string.format("%s %s", options, opt)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return string.format('%s%s', ret, options)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function iter_cmd_sync(cmd_list)
|
|
|
|
|
for _, cmd in ipairs(cmd_list) do
|
|
|
|
|
if cmd.info then
|
|
|
|
|
print(cmd.info)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
vim.fn.system(get_command(cmd))
|
|
|
|
|
if vim.v.shell_error ~= 0 then
|
|
|
|
|
api.nvim_err_writeln(cmd.err)
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function run_install(cache_folder, package_path, lang, repo, with_sync)
|
2020-06-22 11:56:55 +02:00
|
|
|
local project_name = 'tree-sitter-'..lang
|
2020-04-21 19:10:01 +02:00
|
|
|
local project_repo = cache_folder..'/'..project_name
|
2020-04-21 19:28:23 +02:00
|
|
|
-- compile_location only needed for typescript installs.
|
|
|
|
|
local compile_location = cache_folder..'/'..(repo.location or project_name)
|
2020-06-22 11:56:55 +02:00
|
|
|
local parser_lib_name = package_path.."/parser/"..lang..".so"
|
2020-04-19 16:00:26 +02:00
|
|
|
local command_list = {
|
|
|
|
|
{
|
|
|
|
|
cmd = 'rm',
|
|
|
|
|
opts = {
|
|
|
|
|
args = { '-rf', project_repo },
|
2020-06-29 16:07:16 +02:00
|
|
|
},
|
2020-04-19 16:00:26 +02:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
cmd = 'git',
|
|
|
|
|
info = 'Downloading...',
|
|
|
|
|
err = 'Error during download, please verify your internet connection',
|
|
|
|
|
opts = {
|
2020-04-21 19:10:01 +02:00
|
|
|
args = { 'clone', '--single-branch', '--branch', 'master', '--depth', '1', repo.url, project_name },
|
2020-04-19 16:00:26 +02:00
|
|
|
cwd = cache_folder,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
cmd = 'cc',
|
|
|
|
|
info = 'Compiling...',
|
|
|
|
|
err = 'Error during compilation',
|
|
|
|
|
opts = {
|
2020-04-21 21:05:44 +02:00
|
|
|
args = vim.tbl_flatten({
|
|
|
|
|
'-o',
|
|
|
|
|
'parser.so',
|
2020-04-27 15:27:59 +02:00
|
|
|
'-I./src',
|
|
|
|
|
repo.files,
|
2020-04-21 21:05:44 +02:00
|
|
|
'-shared',
|
2020-04-27 15:27:59 +02:00
|
|
|
'-Os',
|
2020-04-21 21:05:44 +02:00
|
|
|
'-lstdc++',
|
2020-04-23 13:48:20 +08:00
|
|
|
'-fPIC',
|
2020-04-21 21:05:44 +02:00
|
|
|
}),
|
2020-04-21 19:28:23 +02:00
|
|
|
cwd = compile_location
|
2020-04-19 16:00:26 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
cmd = 'mv',
|
|
|
|
|
opts = {
|
2020-04-21 19:28:23 +02:00
|
|
|
args = { compile_location..'/parser.so', parser_lib_name }
|
2020-04-19 16:00:26 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
cmd = 'rm',
|
|
|
|
|
opts = {
|
|
|
|
|
args = { '-rf', project_repo }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-29 16:07:16 +02:00
|
|
|
if with_sync then
|
2020-07-12 17:31:34 +02:00
|
|
|
if iter_cmd_sync(command_list) == true then
|
2020-06-29 16:07:16 +02:00
|
|
|
print('Treesitter parser for '..lang..' has been installed')
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
iter_cmd(command_list, 1, lang)
|
|
|
|
|
end
|
2020-04-19 16:00:26 +02:00
|
|
|
end
|
|
|
|
|
|
2020-06-29 16:16:18 +02:00
|
|
|
local function install_lang(lang, ask_reinstall, cache_folder, package_path, with_sync)
|
|
|
|
|
if #api.nvim_get_runtime_file('parser/'..lang..'.so', false) > 0 then
|
|
|
|
|
if not ask_reinstall then return end
|
|
|
|
|
|
|
|
|
|
local yesno = fn.input(lang .. ' parser already available: would you like to reinstall ? y/n: ')
|
|
|
|
|
print('\n ') -- mandatory to avoid messing up command line
|
|
|
|
|
if not string.match(yesno, '^y.*') then return end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local parser_config = parsers.get_parser_configs()[lang]
|
|
|
|
|
if not parser_config then
|
|
|
|
|
return api.nvim_err_writeln('Parser not available for language '..lang)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local install_info = parser_config.install_info
|
|
|
|
|
vim.validate {
|
|
|
|
|
url={ install_info.url, 'string' },
|
|
|
|
|
files={ install_info.files, 'table' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_install(cache_folder, package_path, lang, install_info, with_sync)
|
|
|
|
|
end
|
|
|
|
|
|
2020-04-19 16:00:26 +02:00
|
|
|
-- TODO(kyazdani): this should work on windows too
|
2020-06-30 08:51:52 +02:00
|
|
|
local function install(with_sync, ask_reinstall)
|
2020-06-29 16:07:16 +02:00
|
|
|
return function (...)
|
|
|
|
|
if fn.has('win32') == 1 then
|
|
|
|
|
return api.nvim_err_writeln('This command is not available on windows at the moment.')
|
|
|
|
|
end
|
2020-04-19 14:43:55 +02:00
|
|
|
|
2020-06-29 16:07:16 +02:00
|
|
|
if fn.executable('git') == 0 then
|
|
|
|
|
return api.nvim_err_writeln('Git is required on your system to run this command')
|
|
|
|
|
end
|
2020-04-19 14:43:55 +02:00
|
|
|
|
2020-06-29 16:07:16 +02:00
|
|
|
local package_path, err = utils.get_package_path()
|
|
|
|
|
if err then return api.nvim_err_writeln(err) end
|
2020-04-19 14:43:55 +02:00
|
|
|
|
2020-06-29 16:07:16 +02:00
|
|
|
local cache_folder, err = utils.get_cache_dir()
|
|
|
|
|
if err then return api.nvim_err_writeln(err) end
|
2020-04-19 14:43:55 +02:00
|
|
|
|
2020-06-29 16:58:33 +02:00
|
|
|
local languages
|
2020-06-30 08:51:52 +02:00
|
|
|
local ask
|
2020-06-29 16:07:16 +02:00
|
|
|
if ... == 'all' then
|
|
|
|
|
languages = parsers.available_parsers()
|
2020-06-30 08:51:52 +02:00
|
|
|
ask = false
|
2020-06-29 16:58:33 +02:00
|
|
|
else
|
|
|
|
|
languages = vim.tbl_flatten({...})
|
2020-06-30 08:51:52 +02:00
|
|
|
ask = ask_reinstall
|
2020-06-29 16:07:16 +02:00
|
|
|
end
|
2020-06-25 12:37:01 +02:00
|
|
|
|
2020-06-29 16:07:16 +02:00
|
|
|
for _, lang in ipairs(languages) do
|
2020-06-30 08:51:52 +02:00
|
|
|
install_lang(lang, ask, cache_folder, package_path, with_sync)
|
2020-04-30 22:11:44 +02:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-06-30 08:51:52 +02:00
|
|
|
M.ensure_installed = install(false, false)
|
2020-04-30 22:11:44 +02:00
|
|
|
|
2020-04-21 23:40:23 +02:00
|
|
|
M.commands = {
|
|
|
|
|
TSInstall = {
|
2020-06-30 08:51:52 +02:00
|
|
|
run = install(false, true),
|
2020-04-21 23:40:23 +02:00
|
|
|
args = {
|
2020-05-15 17:15:20 +02:00
|
|
|
"-nargs=+",
|
2020-04-21 23:40:23 +02:00
|
|
|
"-complete=custom,v:lua.ts_installable_parsers"
|
2020-06-29 16:07:16 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
TSInstallSync = {
|
2020-06-30 08:51:52 +02:00
|
|
|
run = install(true, true),
|
2020-06-29 16:07:16 +02:00
|
|
|
args = {
|
|
|
|
|
"-nargs=+",
|
|
|
|
|
"-complete=custom,v:lua.ts_installable_parsers"
|
|
|
|
|
}
|
2020-04-21 23:40:23 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-19 14:43:55 +02:00
|
|
|
return M
|