aboutsummaryrefslogtreecommitdiff
path: root/src/nix
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-06-07 19:01:36 +0200
committerGitHub <noreply@github.com>2022-06-07 19:01:36 +0200
commitb2dea231cf61d8d10cef89991571f57976b77f06 (patch)
treeb3cb47145e5aa2ac858966f3468b099a35833059 /src/nix
parent8977cdee6aac8ef3238b28543199572150929bab (diff)
parent9ae22b1fdeaf6cc7541a66d981ecf7b6038739cc (diff)
Merge pull request #6618 from afishhh/search-exclude
Add `-e`/`--exclude` flag to `nix search`
Diffstat (limited to 'src/nix')
-rw-r--r--src/nix/search.cc29
-rw-r--r--src/nix/search.md13
2 files changed, 37 insertions, 5 deletions
diff --git a/src/nix/search.cc b/src/nix/search.cc
index 87dc1c0de..f1f5f9641 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -18,16 +18,24 @@ using namespace nix;
std::string wrap(std::string prefix, std::string s)
{
- return prefix + s + ANSI_NORMAL;
+ return concatStrings(prefix, s, ANSI_NORMAL);
}
struct CmdSearch : InstallableCommand, MixJSON
{
std::vector<std::string> res;
+ std::vector<std::string> excludeRes;
CmdSearch()
{
expectArgs("regex", &res);
+ addFlag(Flag {
+ .longName = "exclude",
+ .shortName = 'e',
+ .description = "Hide packages whose attribute path, name or description contain *regex*.",
+ .labels = {"regex"},
+ .handler = Handler(&excludeRes),
+ });
}
std::string description() override
@@ -62,11 +70,16 @@ struct CmdSearch : InstallableCommand, MixJSON
res.push_back("^");
std::vector<std::regex> regexes;
+ std::vector<std::regex> excludeRegexes;
regexes.reserve(res.size());
+ excludeRegexes.reserve(excludeRes.size());
for (auto & re : res)
regexes.push_back(std::regex(re, std::regex::extended | std::regex::icase));
+ for (auto & re : excludeRes)
+ excludeRegexes.emplace_back(re, std::regex::extended | std::regex::icase);
+
auto state = getEvalState();
auto jsonOut = json ? std::make_unique<JSONObject>(std::cout) : nullptr;
@@ -106,6 +119,14 @@ struct CmdSearch : InstallableCommand, MixJSON
std::vector<std::smatch> nameMatches;
bool found = false;
+ for (auto & regex : excludeRegexes) {
+ if (
+ std::regex_search(attrPath2, regex)
+ || std::regex_search(name.name, regex)
+ || std::regex_search(description, regex))
+ return;
+ }
+
for (auto & regex : regexes) {
found = false;
auto addAll = [&found](std::sregex_iterator it, std::vector<std::smatch> & vec) {
@@ -133,15 +154,15 @@ struct CmdSearch : InstallableCommand, MixJSON
jsonElem.attr("version", name.version);
jsonElem.attr("description", description);
} else {
- auto name2 = hiliteMatches(name.name, std::move(nameMatches), ANSI_GREEN, "\e[0;2m");
+ auto name2 = hiliteMatches(name.name, nameMatches, ANSI_GREEN, "\e[0;2m");
if (results > 1) logger->cout("");
logger->cout(
"* %s%s",
- wrap("\e[0;1m", hiliteMatches(attrPath2, std::move(attrPathMatches), ANSI_GREEN, "\e[0;1m")),
+ wrap("\e[0;1m", hiliteMatches(attrPath2, attrPathMatches, ANSI_GREEN, "\e[0;1m")),
name.version != "" ? " (" + name.version + ")" : "");
if (description != "")
logger->cout(
- " %s", hiliteMatches(description, std::move(descriptionMatches), ANSI_GREEN, ANSI_NORMAL));
+ " %s", hiliteMatches(description, descriptionMatches, ANSI_GREEN, ANSI_NORMAL));
}
}
}
diff --git a/src/nix/search.md b/src/nix/search.md
index d182788a6..5a5b5ae05 100644
--- a/src/nix/search.md
+++ b/src/nix/search.md
@@ -43,12 +43,23 @@ R""(
# nix search nixpkgs 'firefox|chromium'
```
-* Search for packages containing `git'`and either `frontend` or `gui`:
+* Search for packages containing `git` and either `frontend` or `gui`:
```console
# nix search nixpkgs git 'frontend|gui'
```
+* Search for packages containing `neovim` but hide ones containing either `gui` or `python`:
+
+ ```console
+ # nix search nixpkgs neovim -e 'python|gui'
+ ```
+ or
+
+ ```console
+ # nix search nixpkgs neovim -e 'python' -e 'gui'
+ ```
+
# Description
`nix search` searches *installable* (which must be evaluatable, e.g. a