diff options
Diffstat (limited to 'src/nix/search.cc')
-rw-r--r-- | src/nix/search.cc | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/src/nix/search.cc b/src/nix/search.cc index 0d8fdd5c2..e9307342c 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -9,6 +9,7 @@ #include "shared.hh" #include "eval-cache.hh" #include "attr-path.hh" +#include "fmt.hh" #include <regex> #include <fstream> @@ -20,16 +21,6 @@ std::string wrap(std::string prefix, std::string s) return prefix + s + ANSI_NORMAL; } -std::string hilite(const std::string & s, const std::smatch & m, std::string postfix) -{ - return - m.empty() - ? s - : std::string(m.prefix()) - + ANSI_GREEN + std::string(m.str()) + postfix - + std::string(m.suffix()); -} - struct CmdSearch : InstallableCommand, MixJSON { std::vector<std::string> res; @@ -100,8 +91,6 @@ struct CmdSearch : InstallableCommand, MixJSON }; if (cursor.isDerivation()) { - size_t found = 0; - DrvName name(cursor.getAttr("name")->getString()); auto aMeta = cursor.maybeGetAttr("meta"); @@ -110,21 +99,31 @@ struct CmdSearch : InstallableCommand, MixJSON std::replace(description.begin(), description.end(), '\n', ' '); auto attrPath2 = concatStringsSep(".", attrPath); - std::smatch attrPathMatch; - std::smatch descriptionMatch; - std::smatch nameMatch; + std::vector<std::smatch> attrPathMatches; + std::vector<std::smatch> descriptionMatches; + std::vector<std::smatch> nameMatches; + bool found = false; for (auto & regex : regexes) { - std::regex_search(attrPath2, attrPathMatch, regex); - std::regex_search(name.name, nameMatch, regex); - std::regex_search(description, descriptionMatch, regex); - if (!attrPathMatch.empty() - || !nameMatch.empty() - || !descriptionMatch.empty()) - found++; + found = false; + auto addAll = [&found](std::sregex_iterator it, std::vector<std::smatch> & vec) { + const auto end = std::sregex_iterator(); + while (it != end) { + vec.push_back(*it++); + found = true; + } + }; + + addAll(std::sregex_iterator(attrPath2.begin(), attrPath2.end(), regex), attrPathMatches); + addAll(std::sregex_iterator(name.name.begin(), name.name.end(), regex), nameMatches); + addAll(std::sregex_iterator(description.begin(), description.end(), regex), descriptionMatches); + + if (!found) + break; } - if (found == res.size()) { + if (found) + { results++; if (json) { auto jsonElem = jsonOut->object(attrPath2); @@ -132,15 +131,15 @@ struct CmdSearch : InstallableCommand, MixJSON jsonElem.attr("version", name.version); jsonElem.attr("description", description); } else { - auto name2 = hilite(name.name, nameMatch, "\e[0;2m"); + auto name2 = hiliteMatches(name.name, std::move(nameMatches), ANSI_GREEN, "\e[0;2m"); if (results > 1) logger->cout(""); logger->cout( "* %s%s", - wrap("\e[0;1m", hilite(attrPath2, attrPathMatch, "\e[0;1m")), + wrap("\e[0;1m", hiliteMatches(attrPath2, std::move(attrPathMatches), ANSI_GREEN, "\e[0;1m")), name.version != "" ? " (" + name.version + ")" : ""); if (description != "") logger->cout( - " %s", hilite(description, descriptionMatch, ANSI_NORMAL)); + " %s", hiliteMatches(description, std::move(descriptionMatches), ANSI_GREEN, ANSI_NORMAL)); } } } |