Skip to content

Commit 54aeadb

Browse files
feat(treesitter): track installed tree-sitter parser version
1 parent 62366c7 commit 54aeadb

File tree

3 files changed

+66
-16
lines changed

3 files changed

+66
-16
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ luac.out
4242

4343
# Auto-generated vim helptags
4444
doc/tags
45+
46+
# Lock file
47+
.org-ts-lock.json

lua/orgmode/config/init.lua

+3-9
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,11 @@ function Config:__index(key)
3030
end
3131

3232
function Config:install_grammar()
33-
local ok, result, err = pcall(vim.treesitter.language.add, 'org')
34-
if not ok or (not result and err ~= nil) then
35-
require('orgmode.utils.treesitter.install').run()
36-
return true
37-
end
38-
return false
33+
return require('orgmode.utils.treesitter.install').install()
3934
end
4035

41-
---@param url? string
42-
function Config:reinstall_grammar(url)
43-
return require('orgmode.utils.treesitter.install').run(url)
36+
function Config:reinstall_grammar()
37+
return require('orgmode.utils.treesitter.install').reinstall()
4438
end
4539

4640
---@param opts table

lua/orgmode/utils/treesitter/install.lua

+60-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,47 @@ local M = {
66
compilers = { vim.fn.getenv('CC'), 'cc', 'gcc', 'clang', 'cl', 'zig' },
77
}
88

9+
local required_version = '1.3.4'
10+
11+
function M.install()
12+
if M.not_installed() then
13+
M.run('install')
14+
return true
15+
end
16+
17+
if M.outdated() then
18+
M.run('update')
19+
return true
20+
end
21+
22+
return false
23+
end
24+
25+
function M.reinstall()
26+
return M.run('reinstall')
27+
end
28+
29+
function M.outdated()
30+
local installed_version = M.get_installed_version()
31+
return vim.version.lt(installed_version, required_version)
32+
end
33+
34+
function M.not_installed()
35+
local ok, result, err = pcall(vim.treesitter.language.add, 'org')
36+
return not ok or (not result and err ~= nil)
37+
end
38+
39+
function M.get_installed_version()
40+
local lock_file = M.get_lock_file()
41+
-- No lock file, assume that version is 1.3.4 (when lock file was introduced)
42+
if not vim.uv.fs_stat(lock_file) then
43+
utils.writefile(lock_file, vim.json.encode({ version = '1.3.4' })):wait()
44+
return '1.3.4'
45+
end
46+
local file_content = vim.json.decode(utils.readfile(lock_file, { raw = true }):wait())
47+
return file_content.version
48+
end
49+
950
function M.get_package_path()
1051
-- Path to this source file, removing the leading '@'
1152
local source = string.sub(debug.getinfo(1, 'S').source, 2)
@@ -14,6 +55,10 @@ function M.get_package_path()
1455
return vim.fn.fnamemodify(source, ':p:h:h:h:h:h')
1556
end
1657

58+
function M.get_lock_file()
59+
return M.get_package_path() .. '/.org-ts-lock.json'
60+
end
61+
1762
function M.select_compiler_args(compiler)
1863
if string.match(compiler, 'cl$') or string.match(compiler, 'cl.exe$') then
1964
return {
@@ -70,20 +115,27 @@ function M.exe(cmd, opts)
70115
end)
71116
end
72117

73-
function M.get_path(url)
118+
function M.get_path(url, type)
74119
local local_path = vim.fn.expand(url)
75120
local is_local_path = vim.fn.isdirectory(local_path) == 1
76121

77122
if is_local_path then
123+
utils.echo_info('Using local version of tree-sitter grammar...')
78124
return Promise.resolve(local_path)
79125
end
80126

81127
local path = ('%s/tree-sitter-org'):format(vim.fn.stdpath('cache'))
82128
vim.fn.delete(path, 'rf')
83129

84-
utils.echo_info('Installing tree-sitter grammar...')
130+
local msg = {
131+
install = 'Installing',
132+
update = 'Updating',
133+
reinstall = 'Reinstalling',
134+
}
135+
136+
utils.echo_info(('%s tree-sitter grammar...'):format(msg[type]))
85137
return M.exe('git', {
86-
args = { 'clone', '--filter=blob:none', url, path },
138+
args = { 'clone', '--filter=blob:none', '--depth=1', '--branch=' .. required_version, url, path },
87139
})
88140
:next(function(code)
89141
if code ~= 0 then
@@ -102,9 +154,9 @@ function M.get_path(url)
102154
end)
103155
end
104156

105-
---@param url? string
106-
function M.run(url)
107-
url = url or 'https://github.com/nvim-orgmode/tree-sitter-org'
157+
---@param type? 'install' | 'update' | 'reinstall''
158+
function M.run(type)
159+
local url = 'https://github.com/nvim-orgmode/tree-sitter-org'
108160
local compiler = vim.tbl_filter(function(exe)
109161
return exe ~= vim.NIL and vim.fn.executable(exe) == 1
110162
end, M.compilers)[1]
@@ -117,7 +169,7 @@ function M.run(url)
117169
local package_path = M.get_package_path()
118170
local path = nil
119171

120-
return M.get_path(url)
172+
return M.get_path(url, type)
121173
:next(function(directory)
122174
path = directory
123175
return M.exe(compiler, {
@@ -133,6 +185,7 @@ function M.run(url)
133185
if renamed ~= 0 then
134186
error('[orgmode] Failed to move generated tree-sitter parser to runtime folder', 0)
135187
end
188+
utils.writefile(M.get_lock_file(), vim.json.encode({ version = required_version })):wait()
136189
utils.echo_info('Done!')
137190
return true
138191
end))

0 commit comments

Comments
 (0)