Perform tilde expansion when completing flake fragments
Allows completing `nix build ~/flake#<Tab>`. We can implement expansion for `~user` later if needed. Not using wordexp(3) since that expands way too much.
This commit is contained in:
parent
5461ff532d
commit
55c6906701
5 changed files with 21 additions and 6 deletions
|
@ -15,7 +15,7 @@ function _complete_nix {
|
||||||
else
|
else
|
||||||
COMPREPLY+=("$completion")
|
COMPREPLY+=("$completion")
|
||||||
fi
|
fi
|
||||||
done < <(NIX_GET_COMPLETIONS=$cword "${words[@]/#\~/$HOME}" 2>/dev/null)
|
done < <(NIX_GET_COMPLETIONS=$cword "${words[@]}" 2>/dev/null)
|
||||||
__ltrim_colon_completions "$cur"
|
__ltrim_colon_completions "$cur"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "installables.hh"
|
#include "installables.hh"
|
||||||
|
#include "util.hh"
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
#include "attr-path.hh"
|
#include "attr-path.hh"
|
||||||
#include "common-eval-args.hh"
|
#include "common-eval-args.hh"
|
||||||
|
@ -256,8 +257,7 @@ void completeFlakeRefWithFragment(
|
||||||
|
|
||||||
auto fragment = prefix.substr(hash + 1);
|
auto fragment = prefix.substr(hash + 1);
|
||||||
auto flakeRefS = std::string(prefix.substr(0, hash));
|
auto flakeRefS = std::string(prefix.substr(0, hash));
|
||||||
// FIXME: do tilde expansion.
|
auto flakeRef = parseFlakeRef(expandTilde(flakeRefS), absPath("."));
|
||||||
auto flakeRef = parseFlakeRef(flakeRefS, absPath("."));
|
|
||||||
|
|
||||||
auto evalCache = openEvalCache(*evalState,
|
auto evalCache = openEvalCache(*evalState,
|
||||||
std::make_shared<flake::LockedFlake>(lockFlake(*evalState, flakeRef, lockFlags)));
|
std::make_shared<flake::LockedFlake>(lockFlake(*evalState, flakeRef, lockFlags)));
|
||||||
|
|
|
@ -282,12 +282,13 @@ static void _completePath(std::string_view prefix, bool onlyDirs)
|
||||||
{
|
{
|
||||||
completionType = ctFilenames;
|
completionType = ctFilenames;
|
||||||
glob_t globbuf;
|
glob_t globbuf;
|
||||||
int flags = GLOB_NOESCAPE | GLOB_TILDE;
|
int flags = GLOB_NOESCAPE;
|
||||||
#ifdef GLOB_ONLYDIR
|
#ifdef GLOB_ONLYDIR
|
||||||
if (onlyDirs)
|
if (onlyDirs)
|
||||||
flags |= GLOB_ONLYDIR;
|
flags |= GLOB_ONLYDIR;
|
||||||
#endif
|
#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) {
|
for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||||
if (onlyDirs) {
|
if (onlyDirs) {
|
||||||
auto st = stat(globbuf.gl_pathv[i]);
|
auto st = stat(globbuf.gl_pathv[i]);
|
||||||
|
@ -295,8 +296,8 @@ static void _completePath(std::string_view prefix, bool onlyDirs)
|
||||||
}
|
}
|
||||||
completions->add(globbuf.gl_pathv[i]);
|
completions->add(globbuf.gl_pathv[i]);
|
||||||
}
|
}
|
||||||
globfree(&globbuf);
|
|
||||||
}
|
}
|
||||||
|
globfree(&globbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void completePath(size_t, std::string_view prefix)
|
void completePath(size_t, std::string_view prefix)
|
||||||
|
|
|
@ -200,6 +200,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)
|
bool isInDir(std::string_view path, std::string_view dir)
|
||||||
{
|
{
|
||||||
return path.substr(0, 1) == "/"
|
return path.substr(0, 1) == "/"
|
||||||
|
|
|
@ -68,6 +68,9 @@ Path dirOf(const PathView path);
|
||||||
following the final `/' (trailing slashes are removed). */
|
following the final `/' (trailing slashes are removed). */
|
||||||
std::string_view baseNameOf(std::string_view path);
|
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
|
/* Check whether 'path' is a descendant of 'dir'. Both paths must be
|
||||||
canonicalized. */
|
canonicalized. */
|
||||||
bool isInDir(std::string_view path, std::string_view dir);
|
bool isInDir(std::string_view path, std::string_view dir);
|
||||||
|
|
Loading…
Reference in a new issue