diff options
author | talyz <kim.lindberger@gmail.com> | 2020-07-17 22:28:07 +0200 |
---|---|---|
committer | talyz <kim.lindberger@gmail.com> | 2020-07-18 01:32:47 +0200 |
commit | 8bdbed0579f0f537970129c4e8f267c44c2a6bc7 (patch) | |
tree | d1845ed6f853cce30638c4f2737177871b02a516 /parse.nix | |
parent | 419d8e4636f1314951aeebf33252843058dc2328 (diff) | |
download | nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.tar nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.tar.gz nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.tar.bz2 nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.tar.lz nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.tar.xz nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.tar.zst nixlib-8bdbed0579f0f537970129c4e8f267c44c2a6bc7.zip |
Make parsePackagesFromUsePackage consider :ensure and :disabled
Use `fromElisp` (https://github.com/talyz/fromElisp), imported using `niv` (https://github.com/nmattia/niv), to properly parse the emacs configuration. This lets us take `:ensure` and `:disabled` into account when listing packages to install: - only declarations with an `:ensure` value of true or an alternate package name will be included; if an alternate package name is supplied, it will be used - declarations with a `:disabled` value of true will be excluded
Diffstat (limited to 'parse.nix')
-rw-r--r-- | parse.nix | 112 |
1 files changed, 90 insertions, 22 deletions
diff --git a/parse.nix b/parse.nix index b79411127411..afdd377a376a 100644 --- a/parse.nix +++ b/parse.nix @@ -1,5 +1,9 @@ { lib }: + let + nixDeps = import ./nix/sources.nix; + inherit (import nixDeps.fromElisp {}) fromElisp; + isStrEmpty = s: (builtins.replaceStrings [ " " ] [ "" ] s) == ""; splitString = _sep: _s: builtins.filter @@ -41,31 +45,95 @@ let in parseReqList requires; - stripComments = dotEmacs: + # Get a list of packages declared wanted with `use-package` in the + # input string `config`. The goal is to only list packages that + # would be installed by `use-package` on evaluation; thus we look at + # the `:ensure` and `:disabled` keyword values to attempt to figure + # out which and whether the package should be installed. + # + # Example input: + # + # '' + # (use-package org + # :commands org-mode + # :bind (("C-c a" . org-agenda) + # :map org-mode-map + # ([C-right] . org-demote-subtree) + # ([C-left] . org-promote-subtree))) + # + # (use-package direnv + # :ensure t + # :config (direnv-mode)) + # + # (use-package paredit-mode + # :ensure paredit + # :hook (emacs-lisp-mode lisp-mode lisp-interaction-mode)) + # '' + # => [ "direnv" "paredit" ] + parsePackagesFromUsePackage = config: let - lines = splitString "\n" dotEmacs; - stripped = builtins.map - (l: - builtins.elemAt (splitString ";;" l) 0) - lines; - in - builtins.concatStringsSep " " stripped; + find = item: list: + if list == [] then [] else + if builtins.head list == item then + list + else + find item (builtins.tail list); - 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; + getKeywordValue = keyword: list: + let + keywordList = find keyword list; + in + if keywordList != [] then + let + keywordValue = builtins.tail keywordList; + in + if keywordValue != [] then + builtins.head keywordValue + else + true + else + null; + + isDisabled = item: + let + disabledValue = getKeywordValue ":disabled" item; + in + if disabledValue == [] then + false + else if builtins.isBool disabledValue then + disabledValue + else if builtins.isString disabledValue then + true + else + false; + + getName = item: + let + ensureValue = getKeywordValue ":ensure" item; + in + if ensureValue == [] then + [] + else if builtins.isString ensureValue && !(lib.hasPrefix ":" ensureValue) then + ensureValue + else + builtins.head (builtins.tail item); + + recurse = item: + if builtins.isList item && item != [] then + if (builtins.head item) == "use-package" then + if !(isDisabled item) then + if builtins.elem ":ensure" item then + [ (getName item) ] ++ map recurse item + else + map recurse item + else + [] + else + map recurse item + else + []; in - builtins.map - (m: builtins.elemAt m 0) - (builtins.filter (m: m != null) matches); + lib.flatten (map recurse (fromElisp config)); in { |