@@ -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+
950function 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' )
1556end
1657
58+ function M .get_lock_file ()
59+ return M .get_package_path () .. ' /.org-ts-lock.json'
60+ end
61+
1762function 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 )
71116end
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 )
103155end
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