Skip to content

Commit fb636d9

Browse files
staticoclaude
andcommitted
Install tree-sitter parsers via sync script instead of at nvim startup
tree-sitter-manager's ensure_installed kicks off async builds that don't finish before nvim exits, so slow parsers re-clone every launch. Move installs into parsers.sh which uses headless nvim + vim.wait() to block until each .dylib lands in the parser dir. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 5366699 commit fb636d9

3 files changed

Lines changed: 87 additions & 8 deletions

File tree

.config/nvim/init.lua

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,11 @@ require('lazy').setup({
5555
},
5656

5757
-- Syntax highlighting (parsers; highlighting itself is built-in on nvim 0.12+)
58+
-- Parsers are installed by ./parsers.sh, not at startup, so we don't pay for
59+
-- async installs on every launch (they couldn't finish before nvim exited).
5860
{
5961
'romus204/tree-sitter-manager.nvim',
60-
opts = {
61-
ensure_installed = {
62-
'lua', 'vim', 'vimdoc', 'query',
63-
'javascript', 'typescript', 'tsx', 'html', 'css', 'json',
64-
'markdown', 'markdown_inline', 'python', 'bash', 'yaml', 'ruby',
65-
'xml', 'glsl', 'scss', 'mermaid',
66-
},
67-
},
62+
opts = {},
6863
},
6964
{
7065
'windwp/nvim-ts-autotag',

.config/nvim/parsers.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env zsh
2+
# Install tree-sitter parsers synchronously via headless nvim.
3+
#
4+
# tree-sitter-manager.nvim installs parsers asynchronously, which means slow
5+
# builds don't finish before nvim exits and they get re-attempted every
6+
# startup. Running them here with vim.wait() blocks until each .dylib lands
7+
# in ~/.local/share/nvim/site/parser/ — after which the plugin sees them and
8+
# stops trying to reinstall.
9+
10+
set -e
11+
12+
if ! command -v nvim &>/dev/null; then
13+
echo "Error: nvim not found in PATH" >&2
14+
exit 1
15+
fi
16+
17+
if ! command -v tree-sitter &>/dev/null; then
18+
echo "Error: tree-sitter CLI not found in PATH" >&2
19+
exit 1
20+
fi
21+
22+
echo "◉ Installing tree-sitter parsers..."
23+
24+
nvim --headless -c "lua << EOF
25+
local langs = {
26+
'lua', 'vim', 'vimdoc', 'query',
27+
'javascript', 'typescript', 'tsx', 'html', 'css', 'json',
28+
'markdown', 'markdown_inline', 'python', 'bash', 'yaml', 'ruby',
29+
'xml', 'glsl', 'scss', 'mermaid',
30+
}
31+
32+
local ok, installer = pcall(require, 'tree-sitter-manager.installer')
33+
if not ok then
34+
io.stderr:write('tree-sitter-manager.installer not available — run lazy install first\n')
35+
vim.cmd('cq')
36+
end
37+
local util = require('tree-sitter-manager.util')
38+
local config = require('tree-sitter-manager.config')
39+
40+
vim.fn.mkdir(config.cfg.parser_dir, 'p')
41+
vim.fn.mkdir(config.cfg.query_dir, 'p')
42+
43+
local pending = 0
44+
local failed = {}
45+
46+
for _, lang in ipairs(langs) do
47+
local already
48+
if installer.is_only_query(lang) then
49+
already = vim.uv.fs_stat(util.qpath(lang)) ~= nil
50+
else
51+
already = vim.uv.fs_stat(util.ppath(lang)) ~= nil
52+
end
53+
if not already then
54+
pending = pending + 1
55+
installer.install(lang, function(success)
56+
if not success then table.insert(failed, lang) end
57+
pending = pending - 1
58+
end)
59+
end
60+
end
61+
62+
if pending == 0 then
63+
print('all parsers already installed')
64+
else
65+
print('waiting on ' .. pending .. ' parser install(s)...')
66+
local done = vim.wait(600000, function() return pending == 0 end, 200)
67+
if not done then
68+
io.stderr:write('timeout: ' .. pending .. ' install(s) still pending\n')
69+
vim.cmd('cq')
70+
end
71+
end
72+
73+
if #failed > 0 then
74+
io.stderr:write('failed: ' .. table.concat(failed, ', ') .. '\n')
75+
vim.cmd('cq')
76+
end
77+
EOF" -c qa
78+
79+
echo "╰─ Parser install complete"

.config/nvim/update.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,8 @@ else
7070
fi
7171

7272
echo "╰─ Plugin update complete"
73+
74+
# Install/refresh tree-sitter parsers synchronously so they actually land
75+
# in ~/.local/share/nvim/site/parser/ instead of being re-attempted at every
76+
# nvim startup.
77+
"$(dirname "$0")/parsers.sh"

0 commit comments

Comments
 (0)