diff options
author | Steve Purcell <steve@sanityinc.com> | 2020-06-20 15:24:47 +1200 |
---|---|---|
committer | Steve Purcell <steve@sanityinc.com> | 2020-06-20 15:54:57 +1200 |
commit | 8439afbe1e1fca1b64c91aac302764d465212bca (patch) | |
tree | e6110f0278d5d5355ba08270c08cc652657d8625 /parse.nix | |
parent | 49597c22188e20dc05a7dcf2cfbe6f12162a7ed1 (diff) | |
download | nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.tar nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.tar.gz nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.tar.bz2 nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.tar.lz nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.tar.xz nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.tar.zst nixlib-8439afbe1e1fca1b64c91aac302764d465212bca.zip |
Add emacsWithPackagesFromPackageRequires
This provides a mechanism for creating an Emacs closure that contains the runtime dependencies for a given Emacs package source file, by inspecting its Package-Requires header.
Diffstat (limited to 'parse.nix')
-rw-r--r-- | parse.nix | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/parse.nix b/parse.nix new file mode 100644 index 000000000000..9fbe7c747389 --- /dev/null +++ b/parse.nix @@ -0,0 +1,61 @@ +{ lib }: +let + isStrEmpty = s: (builtins.replaceStrings [ " " ] [ "" ] s) == ""; + + splitString = _sep: _s: builtins.filter + (x: builtins.typeOf x == "string") + (builtins.split _sep _s); + + parsePackagesFromPackageRequires = packageFile: + let + lines = splitString "\r?\n" packageFile; + requires = + lib.concatMapStrings + (line: + let match = builtins.match "^;;;* *[pP]ackage-[rR]equires *: *\\((.*)\\)" line; + in if match == null then "" else builtins.head match) + lines; + parseReqList = s: + let matchAndRest = builtins.match " *\\(? *([^ \"\\)]+)( +\"[^\"]+\" *\\))?(.*)" s; + in + if isStrEmpty s then + [ ] + else + if matchAndRest == null then + throw "Failed to parse package requirements list: ${s}" + else + [ (builtins.head matchAndRest) ] ++ (parseReqList (builtins.elemAt matchAndRest 2)); + in + parseReqList requires; + + stripComments = dotEmacs: + let + lines = splitString "\n" dotEmacs; + stripped = builtins.map + (l: + builtins.elemAt (splitString ";;" l) 0) + lines; + in + builtins.concatStringsSep " " stripped; + + parsePackagesFromUsePackage = dotEmacs: + let + strippedComments = stripComments dotEmacs; + tokens = builtins.filter (t: !(isStrEmpty t)) (builtins.map + (t: if builtins.typeOf t == "list" then builtins.elemAt t 0 else t) + (builtins.split "([\(\)])" strippedComments) + ); + matches = builtins.map + (t: + builtins.match "^use-package[[:space:]]+([A-Za-z0-9_-]+).*" t) + tokens; + in + builtins.map + (m: builtins.elemAt m 0) + (builtins.filter (m: m != null) matches); + +in +{ + inherit parsePackagesFromPackageRequires; + inherit parsePackagesFromUsePackage; +} |