diff options
| author | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-08-12 23:33:13 +0530 |
|---|---|---|
| committer | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-08-29 03:50:26 +0530 |
| commit | 8ab2eadd2c079b0e0b648b48d08d4d6b7d1ba2ab (patch) | |
| tree | 2af0ddd01a0534043c460d65db3d3d65cea559b9 /modules | |
| parent | c3c72a81f90191c32a122ad5e065b1212912e9ab (diff) | |
| download | home-manager-config-8ab2eadd2c079b0e0b648b48d08d4d6b7d1ba2ab.tar.gz home-manager-config-8ab2eadd2c079b0e0b648b48d08d4d6b7d1ba2ab.zip | |
feat: added vimium to chromium for keyboard navigation
- added git tag based latest version from github for vimium
- added vimium extension and loading it unpacked
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/web/chromium/default.nix | 1 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/default.nix | 1 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/lib.nix | 184 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/vimium.nix | 33 |
4 files changed, 182 insertions, 37 deletions
diff --git a/modules/web/chromium/default.nix b/modules/web/chromium/default.nix index 7f3d31f..19038e5 100644 --- a/modules/web/chromium/default.nix +++ b/modules/web/chromium/default.nix @@ -92,6 +92,7 @@ config.web.chromium.extensions.browserpass.id config.web.chromium.extensions.darkreader.id config.web.chromium.extensions.ublockOrigin.id + config.web.chromium.extensions.vimium.id ]; ui = { developer_mode = true; diff --git a/modules/web/chromium/extensions/default.nix b/modules/web/chromium/extensions/default.nix index 704d0c4..cfb3c54 100644 --- a/modules/web/chromium/extensions/default.nix +++ b/modules/web/chromium/extensions/default.nix @@ -59,5 +59,6 @@ in searxngHome = mkExtension ./searxng-home.nix; theme = mkExtension ./theme.nix; ublockOrigin = mkExtension ./ublock-origin.nix; + vimium = mkExtension ./vimium.nix; }; } diff --git a/modules/web/chromium/extensions/lib.nix b/modules/web/chromium/extensions/lib.nix index 79007bd..1197868 100644 --- a/modules/web/chromium/extensions/lib.nix +++ b/modules/web/chromium/extensions/lib.nix @@ -5,7 +5,7 @@ checkForUpdates ? true, }: rec { - # Fetch the latest release tag from the GitHub releases API + # Fetch using the Releases API (Finds the latest official GitHub Release) fetchLatestGithubReleaseTag = { owner, repo }: let @@ -17,45 +17,135 @@ rec { in json.tag_name; - # Abort if the pinned version is older than the latest upstream release + # Fetch using the Tags API (Finds the newest tag matching a prefix/regex) + fetchLatestGithubTag = + { + owner, + repo, + tagPrefix ? "", + tagRegex ? null, + }: + let + raw = builtins.fetchurl { + url = "https://api.github.com/repos/${owner}/${repo}/tags"; + name = "${repo}-tags.json"; + }; + tags = builtins.fromJSON (builtins.readFile raw); + + isValidTag = + t: + let + matchesPrefix = tagPrefix == "" || lib.hasPrefix tagPrefix t.name; + matchesRegex = tagRegex == null || builtins.match tagRegex t.name != null; + in + matchesPrefix && matchesRegex; + + matchingTags = builtins.filter isValidTag tags; + in + if builtins.length matchingTags > 0 then + (builtins.head matchingTags).name + else + throw "No tags found for ${owner}/${repo} matching prefix '${tagPrefix}' and regex '${toString tagRegex}'"; + + # Internal helper to handle the version comparison and error message + _verifyAndThrow = + { + pname, + version, + latestTag, + tagPrefix, + urlTemplate, + updateType, + }: + let + latestVersion = + if lib.hasPrefix tagPrefix latestTag then lib.removePrefix tagPrefix latestTag else latestTag; + in + if latestVersion != version then + throw '' + [${pname}] A newer ${updateType} is available upstream — refusing to build a stale extension. + + pinned version : ${version} + latest version : ${latestVersion} (tag: ${latestTag}) + + To upgrade, edit extensions/${pname}.nix: + 1. Set version = "${latestVersion}"; + 2. Point the url at the new release asset: + ${urlTemplate} + 3. Set hash = lib.fakeHash; + then re-run your switch — it'll fail with a hash mismatch showing + the real sha256. Paste that in as the final hash. + 4. Re-run once more. This check passes once pinned == latest. + + To skip this check for now (e.g. offline / pure eval), set: + web.chromium.checkForUpdates = false; + '' + else + version; + checkExtensionVersion = { pname, owner, repo, version, - urlTemplate, # human-readable template shown in the error message - tagPrefix ? "", # e.g. "v" if tags look like "v1.2.3" + urlTemplate, + tagPrefix ? "", }: if !checkForUpdates then version else let latestTag = fetchLatestGithubReleaseTag { inherit owner repo; }; - latestVersion = - if lib.hasPrefix tagPrefix latestTag then lib.removePrefix tagPrefix latestTag else latestTag; in - if latestVersion != version then - throw '' - [${pname}] A newer release is available upstream — refusing to build a stale extension. - - pinned version : ${version} - latest version : ${latestVersion} (tag: ${latestTag}) - - To upgrade, edit extensions/${pname}.nix: - 1. Set version = "${latestVersion}"; - 2. Point the url at the new release asset: - ${urlTemplate} - 3. Set hash = lib.fakeHash; - then re-run your switch — it'll fail with a hash mismatch showing - the real sha256. Paste that in as the final hash. - 4. Re-run once more. This check passes once pinned == latest. - - To skip this check for now (e.g. offline / pure eval), set: - web.chromium.checkForUpdates = false; - '' - else - version; + _verifyAndThrow { + inherit + pname + version + latestTag + tagPrefix + urlTemplate + ; + updateType = "release"; + }; + + checkExtensionVersionByTag = + { + pname, + owner, + repo, + version, + urlTemplate, + tagPrefix ? "", + tagRegex ? null, + }: + if !checkForUpdates then + version + else + let + latestTag = fetchLatestGithubTag { + inherit + owner + repo + tagPrefix + tagRegex + ; + }; + in + _verifyAndThrow { + inherit + pname + version + latestTag + tagPrefix + urlTemplate + ; + updateType = "tag"; + }; + + # ========================================== + # 3. EXTENSION BUILDERS + # ========================================== # Download and unpack a zip or crx file into an unpacked extension directory fetchUnpackedExtension = @@ -65,7 +155,7 @@ rec { url, hash, isCrx ? false, - extensionKey ? null, # Accept an optional public key + extensionKey ? null, }: pkgs.stdenv.mkDerivation { inherit pname version; @@ -73,7 +163,7 @@ rec { nativeBuildInputs = [ config.file-management.ouch.package - pkgs.jq # Required for safely editing manifest.json + pkgs.python3 ]; dontUnpack = true; @@ -111,20 +201,40 @@ rec { # Inject the public key into manifest.json if provided ${lib.optionalString (extensionKey != null) '' - if [ -f "$out/manifest.json" ]; then - echo "Injecting extension key into manifest.json to lock the extension ID..." - jq '.key = "${extensionKey}"' "$out/manifest.json" > "$out/manifest.tmp.json" - mv "$out/manifest.tmp.json" "$out/manifest.json" - else - echo "Warning: No manifest.json found in $out to inject the key!" >&2 - fi + if [ -f "$out/manifest.json" ]; then + echo "Injecting extension key into manifest.json to lock the extension ID..." + python3 -c ' + import json, sys, re + + manifest_path = sys.argv[1] + ext_key = sys.argv[2] + + with open(manifest_path, "r", encoding="utf-8", errors="ignore") as f: + content = f.read() + + # 1. Strip JS comments without corrupting URLs inside strings + pattern = r"(\"[^\"]*?\")|//.*?$|/\*.*?\*/" + clean = re.sub(pattern, lambda m: m.group(1) if m.group(1) else "", content, flags=re.DOTALL | re.MULTILINE) + + # 2. Strip trailing commas in JSON objects/arrays + clean = re.sub(r",\s*([\]}])", r"\1", clean) + + data = json.loads(clean) + data["key"] = ext_key + + with open(manifest_path, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2) + ' "$out/manifest.json" "${extensionKey}" + else + echo "Warning: No manifest.json found in $out to inject the key!" >&2 + fi ''} runHook postBuild ''; installPhase = "true"; - }; # Package a local directory as an unpacked extension + }; mkLocalExtension = { diff --git a/modules/web/chromium/extensions/vimium.nix b/modules/web/chromium/extensions/vimium.nix new file mode 100644 index 0000000..4175ae7 --- /dev/null +++ b/modules/web/chromium/extensions/vimium.nix @@ -0,0 +1,33 @@ +{ + extLib, + lib, + ... +}: +let + pname = "vimium"; + owner = "philc"; + repo = "vimium"; + version = "2.4.2"; + checkedVersion = extLib.checkExtensionVersionByTag { + inherit + pname + owner + repo + version + ; + tagPrefix = "v"; + urlTemplate = "https://github.com/${owner}/${repo}/archive/refs/tags/v<version>.zip"; + }; +in +{ + inherit pname; + version = checkedVersion; + id = "ckajgijcljfkdbocbbdmambggjlecpia"; + drv = extLib.fetchUnpackedExtension { + inherit pname; + version = checkedVersion; + url = "https://github.com/${owner}/${repo}/archive/refs/tags/v${checkedVersion}.zip"; + hash = "sha256-Q+Tus7nl7TiuVJ4hn8vYg9L2cC4NhqWSOr5WKD0RSq0="; + extensionKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUw4MXlUYAqIQqJ1Gb/RH7RdgVjekKed1aoJS1OPM5C9EFfvVlj0/eIf8dVbCMKc7ThRYYJkZPqFNN38T0LtnBJbvdiJztL/nGueJT7GupXisIzJ9s17X+HpogODouDY7qHldQRw/7qnrBe0NeNxWVeUOH9PmHi8nBTZ3JRygS9svZ1BvY0ZkPZyNDTEsXCbb+fkSOOkjqDNqtt98eFJhPGZ0W+cn3KgTdr+rC0rqfacwfu41dpmQPEirOFtshs8DywoI+L66UtqVfwhBNdb3+JN7oeDs4HNFjCPbqOTSKKCng+nNndpIen2CKYUuYztvmrrRdQeEv5i3l7/MFrRXQIDAQAB"; + }; +} |
