1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#!/usr/bin/env nix-shell
#!nix-shell update-shell.nix -i python
import json
import logging
import os
import subprocess
import sys
from concurrent.futures import ThreadPoolExecutor
log = logging.getLogger("vim-updater")
def generate_grammar(lang, rev, cfg):
"""Generate grammar for a language"""
info = cfg["install_info"]
url = info["url"]
generated = f""" {lang} = buildGrammar {{
language = "{lang}";
version = "0.0.0+rev={rev[:7]}";
src = """
generated += subprocess.check_output(["nurl", url, rev, "--indent=4"], text=True)
generated += ";"
location = info.get("location")
if location:
generated += f"""
location = "{location}";"""
if info.get("requires_generate_from_grammar"):
generated += """
generate = true;"""
generated += f"""
meta.homepage = "{url}";
}};
"""
return generated
def update_grammars(nvim_treesitter_dir: str):
"""
The lockfile contains just revisions so we start neovim to dump the
grammar information in a better format
"""
# the lockfile
cmd = [
"nvim",
"--headless",
"-u",
"NONE",
"--cmd",
f"set rtp^={nvim_treesitter_dir}",
"+lua io.write(vim.json.encode(require('nvim-treesitter.parsers').get_parser_configs()))",
"+quit!",
]
log.debug("Running command: %s", ' '.join(cmd))
configs = json.loads(subprocess.check_output(cmd))
generated_file = """# generated by pkgs/applications/editors/vim/plugins/utils/nvim-treesitter/update.py
{
buildGrammar,
"""
# Get the output and format it properly
nurl_output = subprocess.check_output(["nurl", "-Ls", ","], text=True).strip()
# Add proper indentation (2 spaces) to the comma-separated list
indented_output = nurl_output.replace(",", ",\n ")
generated_file += indented_output
generated_file += """,
}:
{
"""
lockfile_path = os.path.join(nvim_treesitter_dir, "lockfile.json")
log.debug("Opening %s", lockfile_path)
with open(lockfile_path) as lockfile_fd:
lockfile = json.load(lockfile_fd)
def _generate_grammar(item):
lang, lock = item
cfg = configs.get(lang)
if not cfg:
return ""
return generate_grammar(lang, lock["revision"], cfg)
for generated in ThreadPoolExecutor(max_workers=5).map(
_generate_grammar, lockfile.items()
):
generated_file += generated
generated_file += "}\n"
return generated_file
if __name__ == "__main__":
generated = update_grammars(sys.argv[1])
output_path = os.path.join(
os.path.dirname(__file__),
"../../nvim-treesitter/generated.nix"
)
open(output_path, "w").write(generated)
|