From 25bf605940c5d8df0777f627677e68861586167f Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Sat, 21 Nov 2020 18:49:19 +0100 Subject: [PATCH] Only update outdated_parsers on TSUpdate --- lua/nvim-treesitter/install.lua | 75 +++++++++++++++++++++++++-------- lua/nvim-treesitter/utils.lua | 11 +++-- parser-info/.gitignore | 2 + 3 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 parser-info/.gitignore diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua index 2a91c07c8..4011a0807 100644 --- a/lua/nvim-treesitter/install.lua +++ b/lua/nvim-treesitter/install.lua @@ -28,7 +28,7 @@ end local function get_job_status() return "[nvim-treesitter] ["..finished_commands.."/"..started_commands - ..(failed_commands > 0 and ", failed: "..failed_commands or "").."]" + ..(failed_commands > 0 and ", failed: "..failed_commands or "").."]" end local function get_revision(lang) @@ -38,6 +38,24 @@ local function get_revision(lang) return (lockfile[lang] and lockfile[lang].revision) end +local function get_installed_revision(lang) + local lang_file = utils.join_path(utils.get_parser_info_dir(), lang..'.revision') + if vim.fn.filereadable(lang_file) == 1 then + return vim.fn.readfile(lang_file)[1] + end +end + +local function needs_update(lang) + return not get_revision(lang) or get_revision(lang) ~= get_installed_revision(lang) +end + +local function outdated_parsers() + return vim.tbl_filter(function(lang) + return needs_update(lang) + end, + info.installed_parsers()) +end + function M.iter_cmd(cmd_list, i, lang, success_message) if i == 1 then started_commands = started_commands + 1 @@ -50,17 +68,28 @@ function M.iter_cmd(cmd_list, i, lang, success_message) local attr = cmd_list[i] if attr.info then print(get_job_status().." "..attr.info) end - local handle - - handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code) - handle:close() - if code ~= 0 then + if type(attr.cmd) == 'function' then + local ok, err = pcall(attr.cmd) + if ok then + M.iter_cmd(cmd_list, i + 1, lang, success_message) + else failed_commands = failed_commands + 1 finished_commands = finished_commands + 1 - return api.nvim_err_writeln(attr.err or ("Failed to execute the following command:\n"..vim.inspect(attr))) + return api.nvim_err_writeln((attr.err or ("Failed to execute the following command:\n"..vim.inspect(attr))) + ..'\n'..vim.inspect(err)) end - M.iter_cmd(cmd_list, i + 1, lang, success_message) - end)) + else + local handle + handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code) + handle:close() + if code ~= 0 then + failed_commands = failed_commands + 1 + finished_commands = finished_commands + 1 + return api.nvim_err_writeln(attr.err or ("Failed to execute the following command:\n"..vim.inspect(attr))) + end + M.iter_cmd(cmd_list, i + 1, lang, success_message) + end)) + end end local function get_command(cmd) @@ -87,13 +116,17 @@ local function iter_cmd_sync(cmd_list) print(cmd.info) end - local ret = vim.fn.system(get_command(cmd)) - if vim.v.shell_error ~= 0 then - print(ret) - api.nvim_err_writeln((cmd.err and cmd.err..'\n' or '') - .."Failed to execute the following command:\n" - ..vim.inspect(cmd)) - return false + if type(cmd.cmd) == 'function' then + cmd.cmd() + else + local ret = vim.fn.system(get_command(cmd)) + if vim.v.shell_error ~= 0 then + print(ret) + api.nvim_err_writeln((cmd.err and cmd.err..'\n' or '') + .."Failed to execute the following command:\n" + ..vim.inspect(cmd)) + return false + end end end @@ -164,6 +197,11 @@ local function run_install(cache_folder, install_folder, lang, repo, with_sync, } }, shell.select_mv_cmd('parser.so', parser_lib_name, compile_location), + { + cmd = function() + vim.fn.writefile({revision or ''}, utils.join_path(utils.get_parser_info_dir(), lang..'.revision')) + end + } }) if not from_local_path then vim.list_extend(command_list, {shell.select_install_rm_cmd(cache_folder, project_name)}) @@ -239,11 +277,14 @@ local function install(with_sync, ask_reinstall, generate_from_grammar) end function M.update(lang) + M.lockfile = {} reset_progress_counter() if lang and lang ~= 'all' then install(false, 'force')(lang) else - local installed = info.installed_parsers() + local installed = configs.get_update_strategy() == 'lockfile' + and outdated_parsers() + or info.installed_parsers() for _, lang in pairs(installed) do install(false, 'force')(lang) end diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index 17e7ff95e..de579bd6d 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -68,9 +68,10 @@ end -- "site" dir from "runtimepath". "site" dir will be created if it doesn't -- exist. Using only the package dir won't work when the plugin is installed -- with Nix, since the "/nix/store" is read-only. -function M.get_parser_install_dir() +function M.get_parser_install_dir(folder_name) + folder_name = folder_name or "parser" local package_path = M.get_package_path() - local package_path_parser_dir = M.join_path(package_path, "parser") + local package_path_parser_dir = M.join_path(package_path, folder_name) -- If package_path is read/write, use that if luv.fs_access(package_path_parser_dir, 'RW') then @@ -79,7 +80,7 @@ function M.get_parser_install_dir() local site_dir = M.get_site_dir() local path_sep = M.get_path_sep() - local parser_dir = M.join_path(site_dir, path_sep, 'parser') + local parser_dir = M.join_path(site_dir, path_sep, folder_name) -- Try creating and using parser_dir if it doesn't exist if not luv.fs_stat(parser_dir) then @@ -101,6 +102,10 @@ function M.get_parser_install_dir() return nil, join_space('Invalid cache rights,', package_path, 'or', parser_dir, 'should be read/write') end +function M.get_parser_info_dir() + return M.get_parser_install_dir('parser-info') +end + -- Gets a property at path -- @param tbl the table to access -- @param path the '.' separated path diff --git a/parser-info/.gitignore b/parser-info/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/parser-info/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore