diff options
| author | kiyan42 <yazdani.kiyan@protonmail.com> | 2020-04-19 16:00:26 +0200 |
|---|---|---|
| committer | kiyan42 <yazdani.kiyan@protonmail.com> | 2020-04-20 20:57:11 +0200 |
| commit | ec9daa1f8a61d1226d755dacdfd34fc955bea4bc (patch) | |
| tree | ffa7be77d2400e03e6f6eecb4a25559346642f22 /lua | |
| parent | add parser installer (diff) | |
| download | nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.tar nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.tar.gz nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.tar.bz2 nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.tar.lz nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.tar.xz nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.tar.zst nvim-treesitter-ec9daa1f8a61d1226d755dacdfd34fc955bea4bc.zip | |
feat/refacto: improve installer
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/nvim-treesitter/install.lua | 140 |
1 files changed, 102 insertions, 38 deletions
diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua index 2f40db11c..8e39be5e7 100644 --- a/lua/nvim-treesitter/install.lua +++ b/lua/nvim-treesitter/install.lua @@ -1,74 +1,138 @@ local api = vim.api local fn = vim.fn +local luv = vim.loop local M = {} -local package_path = nil local repositories = { javascript = { url = "https://github.com/tree-sitter/tree-sitter-javascript", - files = "src/parser.c src/scanner.c", + files = { "src/parser.c", "src/scanner.c" }, }, c = { url = "https://github.com/tree-sitter/tree-sitter-c", - files = "src/parser.c" + files = { "src/parser.c" } + }, + rust = { + url = "https://github.com/tree-sitter/tree-sitter-rust", + files = { "src/parser.c", "src/scanner.c" }, } } --- TODO(kyazdani): there might be a better way to get the plugin path -for _, path in pairs(api.nvim_list_runtime_paths()) do - if string.match(path, '.*/nvim%-treesitter') then - package_path = path - break +local function get_package_path() + for _, path in pairs(api.nvim_list_runtime_paths()) do + if string.match(path, '.*/nvim%-treesitter') then + return path + end end + + return nil, 'Plugin runtime path not found.' end -local function create_compile_command(ft, path, files) - -- TODO(kyazdani): should download the parser in $XDG_CACHE_HOME instead of /tmp - return "cd /tmp/tree-sitter-"..ft..[[ && \ - gcc -o parser.so -shared ]]..files..[[ -Os -I./src && \ - mv parser.so ]]..path.."/parsers/"..ft..[[.so && \ - rm -rf /tmp/tree-sitter-]]..ft +local function get_cache_dir() + local home = fn.get(fn.environ(), 'HOME') + local xdg_cache = fn.get(fn.environ(), 'XDG_CACHE_HOME') + + if xdg_cache == 0 then + xdg_cache = home .. '/.cache' + end + + if luv.fs_access(xdg_cache, 'RW') then + return xdg_cache + elseif luv.fs_access('/tmp', 'RW') then + return '/tmp' + end + + return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write' end -local function create_download_command(url) - return "cd /tmp && git clone "..url +local function iter_cmd(cmd_list, i, ft) + if i == #cmd_list then return print('Treesitter parser for '..ft..' has been installed') end + local attr = cmd_list[i + 1] + print(attr.info) + handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code) + handle:close() + if code ~= 0 then return api.nvim_err_writeln(attr.err) end + iter_cmd(cmd_list, i + 1, ft) + end)) end -function M.install_parser(lang) +local function run_install(cache_folder, package_path, ft, files, url) + local project_repo = cache_folder..'/tree-sitter-'..ft + local parser_lib_name = package_path.."/parser/"..ft..".so" + local command_list = { + { + cmd = 'rm', + opts = { + args = { '-rf', project_repo }, + } + }, + { + cmd = 'git', + info = 'Downloading...', + err = 'Error during download, please verify your internet connection', + opts = { + args = { 'clone', url }, + cwd = cache_folder, + }, + }, + { + cmd = 'cc', + info = 'Compiling...', + err = 'Error during compilation', + opts = { + args = { '-o', 'parser.so', '-shared', '-lstdc++', unpack(files), '-Os', '-I./src' }, + cwd = project_repo + } + }, + { + cmd = 'mv', + opts = { + args = { project_repo..'/parser.so', parser_lib_name } + } + }, + { + cmd = 'rm', + opts = { + args = { '-rf', project_repo } + } + } + } + + iter_cmd(command_list, 0, ft) +end + +-- TODO(kyazdani): this should work on windows too +function M.install_parser(ft) if fn.has('win32') == 1 then - -- TODO(kyazdani): this should work on windows too - api.nvim_err_writeln('This command is not available on windows at the moment.') - return + return api.nvim_err_writeln('This command is not available on windows at the moment.') end - if not lang then - api.nvim_err_writeln("usage: install_parser('language')") - return + if not ft then + return api.nvim_err_writeln("Usage: install_parser('language')") end - local repository = repositories[lang] - if not repository then - api.nvim_err_writeln('Parser not available for language '..lang) - return + if #api.nvim_get_runtime_file('parser/'..ft..'.so', false) > 0 then + local yesno = fn.input('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 - if not package_path then - api.nvim_err_writeln('Plugin runtime path not found.') - return + local repository = repositories[ft] + if not repository then + return api.nvim_err_writeln('Parser not available for language '..ft) end - if not fn.executable('git') == 1 then - api.nvim_err_writeln('Please install `git` to download parsers.') - return + if fn.executable('git') == 0 then + return api.nvim_err_writeln('Git is required on your system to run this command') end - print("Downloading parser...") - fn.system(create_download_command(repository.url)) + local package_path, err = get_package_path() + if err then return api.nvim_err_writeln(err) end - print("Compiling parser...") - fn.system(create_compile_command(lang, package_path, repository.files)) + local cache_folder, err = get_cache_dir() + if err then return api.nvim_err_writeln(err) end - print("Install for the " ..lang.." parser was successfull") + run_install(cache_folder, package_path, ft, repository.files, repository.url) end return M |
