1#!/usr/bin/env python
2
3# run with:
4# $ nix run .\#vimPluginsUpdater
5# format:
6# $ nix run nixpkgs#python3Packages.ruff -- update.py
7# type-check:
8# $ nix run nixpkgs#python3Packages.mypy -- update.py
9# linted:
10# $ nix run nixpkgs#python3Packages.flake8 -- --ignore E501,E265,E402 update.py
11
12# If you see `HTTP Error 429: too many requests` errors while running this
13# script, refer to:
14#
15# https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md#updating-plugins-in-nixpkgs-updating-plugins-in-nixpkgs
16#
17# (or the equivalent file /doc/languages-frameworks/vim.section.md
18# from Nixpkgs master tree).
19#
20
21import inspect
22import logging
23import os
24import textwrap
25from pathlib import Path
26from typing import List, Tuple
27
28log = logging.getLogger("vim-updater")
29
30# Import plugin update library from maintainers/scripts/pluginupdate.py
31ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
32import importlib
33
34import pluginupdate
35from pluginupdate import PluginDesc, run_nix_expr
36
37treesitter = importlib.import_module("nvim-treesitter.update")
38
39
40HEADER = (
41 "# GENERATED by ./pkgs/applications/editors/vim/plugins/utils/update.py. Do not edit!"
42)
43
44NIXPKGS_NVIMTREESITTER_FOLDER = "pkgs/applications/editors/vim/plugins/nvim-treesitter"
45
46
47class VimEditor(pluginupdate.Editor):
48 nvim_treesitter_updated = False
49
50 def generate_nix(
51 self, plugins: List[Tuple[PluginDesc, pluginupdate.Plugin]], outfile: str
52 ):
53 log.info("Generating nix code")
54 log.debug("Loading nvim-treesitter revision from nix...")
55 nvim_treesitter_rev = pluginupdate.run_nix_expr(
56 "(import <localpkgs> { }).vimPlugins.nvim-treesitter.src.rev",
57 self.nixpkgs,
58 timeout=10,
59 )
60
61 GET_PLUGINS_LUA = """
62 with import <localpkgs> {};
63 lib.attrNames lua51Packages"""
64 log.debug("Loading list of lua plugins...")
65 luaPlugins = run_nix_expr(GET_PLUGINS_LUA, self.nixpkgs, timeout=30)
66
67 def _isNeovimPlugin(plug: pluginupdate.Plugin) -> bool:
68 """
69 Whether it's a neovim-only plugin
70 We can check if it's available in lua packages
71 """
72 if plug.normalized_name in luaPlugins:
73 log.debug("%s is a neovim plugin", plug)
74 return True
75 return False
76
77 with open(outfile, "w+") as f:
78 log.debug("Writing to %s", outfile)
79 f.write(HEADER)
80 f.write(
81 textwrap.dedent(
82 """
83 {
84 lib,
85 buildVimPlugin,
86 buildNeovimPlugin,
87 fetchFromGitHub,
88 }:
89
90 final: prev: {
91 """
92 )
93 )
94 for pdesc, plugin in plugins:
95 content = self.plugin2nix(pdesc, plugin, _isNeovimPlugin(plugin))
96 f.write(content)
97 if (
98 plugin.name == "nvim-treesitter"
99 and plugin.commit != nvim_treesitter_rev
100 ):
101 self.nvim_treesitter_updated = True
102 f.write("}\n")
103 print(f"updated {outfile}")
104
105 def plugin2nix(
106 self, pdesc: PluginDesc, plugin: pluginupdate.Plugin, isNeovim: bool
107 ) -> str:
108 if isNeovim:
109 raise RuntimeError(f"Plugin {plugin.name} is already packaged in `luaPackages`, please use that")
110 repo = pdesc.repo
111
112 content = f" {plugin.normalized_name} = "
113 src_nix = repo.as_nix(plugin)
114 content += """{buildFn} {{
115 pname = "{plugin.name}";
116 version = "{plugin.version}";
117 src = {src_nix};
118 meta.homepage = "{repo.uri}";
119 meta.hydraPlatforms = [ ];
120 }};
121
122""".format(
123 buildFn="buildNeovimPlugin" if isNeovim else "buildVimPlugin",
124 plugin=plugin,
125 src_nix=src_nix,
126 repo=repo,
127 )
128 log.debug(content)
129 return content
130
131 def update(self, args):
132 pluginupdate.update_plugins(self, args)
133
134 # TODO this should probably be skipped when running outside a nixpkgs checkout
135 if self.nvim_treesitter_updated:
136 print("updating nvim-treesitter grammars")
137 generated = treesitter.update_grammars()
138 treesitter_generated_nix_path = os.path.join(
139 NIXPKGS_NVIMTREESITTER_FOLDER, "generated.nix"
140 )
141 open(os.path.join(args.nixpkgs, treesitter_generated_nix_path), "w").write(
142 generated
143 )
144
145 if self.nixpkgs_repo:
146 index = self.nixpkgs_repo.index
147 for diff in index.diff(None):
148 if diff.a_path == treesitter_generated_nix_path:
149 msg = "vimPlugins.nvim-treesitter: update grammars"
150 print(f"committing to nixpkgs: {msg}")
151 index.add([treesitter_generated_nix_path])
152 index.commit(msg)
153 return
154 print("no updates to nvim-treesitter grammars")
155
156
157def main():
158 global luaPlugins
159
160 log.debug(f"Loading from {ROOT}/get-plugins.nix")
161 with open(f"{ROOT}/get-plugins.nix") as f:
162 GET_PLUGINS = f.read()
163 editor = VimEditor(
164 "vim", Path("pkgs/applications/editors/vim/plugins"), GET_PLUGINS
165 )
166 editor.run()
167
168
169if __name__ == "__main__":
170 main()