Use replaceStrings primop

This commit is contained in:
Eelco Dolstra 2015-07-24 15:45:41 +02:00
parent 6f6f66ac98
commit 9cfd128a42

View File

@ -8,7 +8,7 @@ in
rec { rec {
inherit (builtins) stringLength substring head tail isString; inherit (builtins) stringLength substring head tail isString replaceStrings;
# Concatenate a list of strings. # Concatenate a list of strings.
@ -80,28 +80,25 @@ rec {
# will likely be horribly inefficient; Nix is not a general purpose # will likely be horribly inefficient; Nix is not a general purpose
# programming language. Complex string manipulations should, if # programming language. Complex string manipulations should, if
# appropriate, be done in a derivation. # appropriate, be done in a derivation.
stringToCharacters = s: let l = stringLength s; in stringToCharacters = s:
if l == 0 map (p: substring p 1 s) (lib.range 0 (stringLength s - 1));
then []
else map (p: substring p 1 s) (lib.range 0 (l - 1));
# Manipulate a string charcater by character and replace them by strings # Manipulate a string charactter by character and replace them by
# before concatenating the results. # strings before concatenating the results.
stringAsChars = f: s: stringAsChars = f: s:
concatStrings ( concatStrings (
map f (stringToCharacters s) map f (stringToCharacters s)
); );
# same as vim escape function. # Escape occurrence of the elements of list in string by
# Each character contained in list is prefixed by "\" # prefixing it with a backslash. For example, escape ["(" ")"]
escape = list : string : # "(foo)" returns the string \(foo\).
stringAsChars (c: if lib.elem c list then "\\${c}" else c) string; escape = list: replaceChars list (map (c: "\\${c}") list);
# still ugly slow. But more correct now # Escape all characters that have special meaning in the Bourne shell.
# [] for zsh
escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]"); escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]");
@ -109,7 +106,8 @@ rec {
# the `tr' command except that one character can be replace by multiple # the `tr' command except that one character can be replace by multiple
# ones. e.g., # ones. e.g.,
# replaceChars ["<" ">"] ["&lt;" "&gt;"] "<foo>" returns "&lt;foo&gt;". # replaceChars ["<" ">"] ["&lt;" "&gt;"] "<foo>" returns "&lt;foo&gt;".
replaceChars = del: new: s: replaceChars = builtins.replaceStrings or (
del: new: s:
let let
substList = lib.zipLists del new; substList = lib.zipLists del new;
subst = c: subst = c:
@ -119,20 +117,22 @@ rec {
else else
found.snd; found.snd;
in in
stringAsChars subst s; stringAsChars subst s);
# Case conversion utilities # Case conversion utilities.
lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz"; lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz";
upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
toLower = replaceChars upperChars lowerChars; toLower = replaceChars upperChars lowerChars;
toUpper = replaceChars lowerChars upperChars; toUpper = replaceChars lowerChars upperChars;
# Appends string context from another string
# Appends string context from another string.
addContextFrom = a: b: substring 0 0 a + b; addContextFrom = a: b: substring 0 0 a + b;
# Compares strings not requiring context equality # Compares strings not requiring context equality
# Obviously, a workaround but works on all Nix versions # Obviously, a workaround but works on all Nix versions.
eqStrings = a: b: addContextFrom b a == addContextFrom a b; eqStrings = a: b: addContextFrom b a == addContextFrom a b;