search.cc: improve UX for nix search

As proposed in #1634 the `nix search` command could use some
improvements. Initially 0413aeb35d added
some basic sorting behavior using `std::map`, a next step would be an
improvement of the output.

This patch includes the following changes:

* Use `$PAGER` for outputs with `RunPager` from `shared.hh`:
  The same behavior is defined for `nix-env --query`, furthermore it
  makes searching huge results way easier.

* Simplified result blocks:
  The new output is heavily inspired by the output from `nox`, the first
  line shows the attribute path and the derivaiton name
  (`attribute path (derivation name)`) and the description in the second
  line.
This commit is contained in:
Maximilian Bosch 2018-05-12 20:00:59 +02:00
parent a91c4ca01f
commit 6b74fdac27
No known key found for this signature in database
GPG key ID: 091DBF4D1FC46B8E

View file

@ -7,19 +7,25 @@
#include "common-args.hh" #include "common-args.hh"
#include "json.hh" #include "json.hh"
#include "json-to-value.hh" #include "json-to-value.hh"
#include "shared.hh"
#include <regex> #include <regex>
#include <fstream> #include <fstream>
using namespace nix; using namespace nix;
std::string hilite(const std::string & s, const std::smatch & m) 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 return
m.empty() m.empty()
? s ? s
: std::string(m.prefix()) : std::string(m.prefix())
+ ANSI_RED + std::string(m.str()) + ANSI_NORMAL + ANSI_RED + std::string(m.str()) + postfix
+ std::string(m.suffix()); + std::string(m.suffix());
} }
@ -75,6 +81,10 @@ struct CmdSearch : SourceExprCommand, MixJSON
"To search for git and frontend or gui:", "To search for git and frontend or gui:",
"nix search git 'frontend|gui'" "nix search git 'frontend|gui'"
}, },
Example{
"To display the description of the found packages:",
"nix search git --verbose"
}
}; };
} }
@ -164,14 +174,10 @@ struct CmdSearch : SourceExprCommand, MixJSON
} else { } else {
results[attrPath] = fmt( results[attrPath] = fmt(
"Attribute name: %s\n" "* %s (%s)\n %s\n",
"Package name: %s\n" wrap("\e[0;1m", hilite(attrPath, attrPathMatch, "\e[0;1m")),
"Version: %s\n" wrap("\e[0;2m", hilite(parsed.fullName, nameMatch, "\e[0;2m")),
"Description: %s\n", hilite(description, descriptionMatch, ANSI_NORMAL));
hilite(attrPath, attrPathMatch),
hilite(name, nameMatch),
parsed.version,
hilite(description, descriptionMatch));
} }
} }
@ -263,6 +269,10 @@ struct CmdSearch : SourceExprCommand, MixJSON
throw SysError("cannot rename '%s' to '%s'", tmpFile, jsonCacheFileName); throw SysError("cannot rename '%s' to '%s'", tmpFile, jsonCacheFileName);
} }
if (results.size() == 0)
throw Error("no results for the given search term(s)!");
RunPager pager;
for (auto el : results) std::cout << el.second << "\n"; for (auto el : results) std::cout << el.second << "\n";
} }