mirror of
https://github.com/NixOS/nix.git
synced 2025-11-11 21:16:02 +01:00
Merge remote-tracking branch 'upstream/master' into fix-url-format
This commit is contained in:
commit
3c220442ff
26 changed files with 387 additions and 151 deletions
|
|
@ -127,11 +127,11 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
|||
if (flag.handler.arity == ArityAny) break;
|
||||
throw UsageError("flag '%s' requires %d argument(s)", name, flag.handler.arity);
|
||||
}
|
||||
if (flag.completer)
|
||||
if (auto prefix = needsCompletion(*pos)) {
|
||||
anyCompleted = true;
|
||||
if (auto prefix = needsCompletion(*pos)) {
|
||||
anyCompleted = true;
|
||||
if (flag.completer)
|
||||
flag.completer(n, *prefix);
|
||||
}
|
||||
}
|
||||
args.push_back(*pos++);
|
||||
}
|
||||
if (!anyCompleted)
|
||||
|
|
@ -146,6 +146,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
|||
&& hasPrefix(name, std::string(*prefix, 2)))
|
||||
completions->add("--" + name, flag->description);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
auto i = longFlags.find(std::string(*pos, 2));
|
||||
if (i == longFlags.end()) return false;
|
||||
|
|
@ -187,10 +188,12 @@ bool Args::processArgs(const Strings & args, bool finish)
|
|||
{
|
||||
std::vector<std::string> ss;
|
||||
for (const auto &[n, s] : enumerate(args)) {
|
||||
ss.push_back(s);
|
||||
if (exp.completer)
|
||||
if (auto prefix = needsCompletion(s))
|
||||
if (auto prefix = needsCompletion(s)) {
|
||||
ss.push_back(*prefix);
|
||||
if (exp.completer)
|
||||
exp.completer(n, *prefix);
|
||||
} else
|
||||
ss.push_back(s);
|
||||
}
|
||||
exp.handler.fun(ss);
|
||||
expectedArgs.pop_front();
|
||||
|
|
@ -279,21 +282,22 @@ static void _completePath(std::string_view prefix, bool onlyDirs)
|
|||
{
|
||||
completionType = ctFilenames;
|
||||
glob_t globbuf;
|
||||
int flags = GLOB_NOESCAPE | GLOB_TILDE;
|
||||
int flags = GLOB_NOESCAPE;
|
||||
#ifdef GLOB_ONLYDIR
|
||||
if (onlyDirs)
|
||||
flags |= GLOB_ONLYDIR;
|
||||
#endif
|
||||
if (glob((std::string(prefix) + "*").c_str(), flags, nullptr, &globbuf) == 0) {
|
||||
// using expandTilde here instead of GLOB_TILDE(_CHECK) so that ~<Tab> expands to /home/user/
|
||||
if (glob((expandTilde(prefix) + "*").c_str(), flags, nullptr, &globbuf) == 0) {
|
||||
for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
if (onlyDirs) {
|
||||
auto st = lstat(globbuf.gl_pathv[i]);
|
||||
auto st = stat(globbuf.gl_pathv[i]);
|
||||
if (!S_ISDIR(st.st_mode)) continue;
|
||||
}
|
||||
completions->add(globbuf.gl_pathv[i]);
|
||||
}
|
||||
globfree(&globbuf);
|
||||
}
|
||||
globfree(&globbuf);
|
||||
}
|
||||
|
||||
void completePath(size_t, std::string_view prefix)
|
||||
|
|
@ -322,11 +326,6 @@ MultiCommand::MultiCommand(const Commands & commands_)
|
|||
.optional = true,
|
||||
.handler = {[=](std::string s) {
|
||||
assert(!command);
|
||||
if (auto prefix = needsCompletion(s)) {
|
||||
for (auto & [name, command] : commands)
|
||||
if (hasPrefix(name, *prefix))
|
||||
completions->add(name);
|
||||
}
|
||||
auto i = commands.find(s);
|
||||
if (i == commands.end()) {
|
||||
std::set<std::string> commandNames;
|
||||
|
|
@ -337,6 +336,11 @@ MultiCommand::MultiCommand(const Commands & commands_)
|
|||
}
|
||||
command = {s, i->second()};
|
||||
command->second->parent = this;
|
||||
}},
|
||||
.completer = {[&](size_t, std::string_view prefix) {
|
||||
for (auto & [name, command] : commands)
|
||||
if (hasPrefix(name, prefix))
|
||||
completions->add(name);
|
||||
}}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,17 @@ std::string_view baseNameOf(std::string_view path)
|
|||
}
|
||||
|
||||
|
||||
std::string expandTilde(std::string_view path)
|
||||
{
|
||||
// TODO: expand ~user ?
|
||||
auto tilde = path.substr(0, 2);
|
||||
if (tilde == "~/" || tilde == "~")
|
||||
return getHome() + std::string(path.substr(1));
|
||||
else
|
||||
return std::string(path);
|
||||
}
|
||||
|
||||
|
||||
bool isInDir(std::string_view path, std::string_view dir)
|
||||
{
|
||||
return path.substr(0, 1) == "/"
|
||||
|
|
@ -213,6 +224,15 @@ bool isDirOrInDir(std::string_view path, std::string_view dir)
|
|||
}
|
||||
|
||||
|
||||
struct stat stat(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st))
|
||||
throw SysError("getting status of '%1%'", path);
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
struct stat lstat(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ Path dirOf(const PathView path);
|
|||
following the final `/' (trailing slashes are removed). */
|
||||
std::string_view baseNameOf(std::string_view path);
|
||||
|
||||
/* Perform tilde expansion on a path. */
|
||||
std::string expandTilde(std::string_view path);
|
||||
|
||||
/* Check whether 'path' is a descendant of 'dir'. Both paths must be
|
||||
canonicalized. */
|
||||
bool isInDir(std::string_view path, std::string_view dir);
|
||||
|
|
@ -77,6 +80,7 @@ bool isInDir(std::string_view path, std::string_view dir);
|
|||
bool isDirOrInDir(std::string_view path, std::string_view dir);
|
||||
|
||||
/* Get status of `path'. */
|
||||
struct stat stat(const Path & path);
|
||||
struct stat lstat(const Path & path);
|
||||
|
||||
/* Return true iff the given path exists. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue