aboutsummaryrefslogtreecommitdiff
path: root/src/nix/search.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix/search.cc')
-rw-r--r--src/nix/search.cc51
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));
}
}
}