completions: Offer ../ and ./ again (#9477)

Inadvertently broken in a2d816710f,
this made `cd .` no longer offer `cd ../` (same for general file completions
like `ls .`, which only offers dotfiles)
This commit is contained in:
Fabian Boehm 2023-01-16 10:05:01 +01:00 committed by GitHub
parent 256713b670
commit 6df09b3753
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 7 deletions

View File

@ -679,7 +679,7 @@ class wildcard_expander_t {
}
// Helper to resolve using our prefix.
dir_iter_t open_dir(const wcstring &base_dir) const {
dir_iter_t open_dir(const wcstring &base_dir, bool dotdot = false) const {
wcstring path = this->working_directory;
append_path_component(path, base_dir);
if (flags & expand_flag::special_for_cd) {
@ -687,7 +687,7 @@ class wildcard_expander_t {
// for example, cd ../<tab> should complete "without resolving symlinks".
path = normalize_path(path);
}
return dir_iter_t(path);
return dir_iter_t(path, dotdot);
}
public:
@ -952,7 +952,8 @@ void wildcard_expander_t::expand(const wcstring &base_dir, const wchar_t *wc,
}
}
dir_iter_t dir = open_dir(base_dir);
// return "." and ".." entries if we're doing completions
dir_iter_t dir = open_dir(base_dir, /* return . and .. */ flags & expand_flag::for_completions);
if (dir.valid()) {
if (is_last_segment) {
// Last wildcard segment, nonempty wildcard.

View File

@ -172,12 +172,13 @@ void dir_iter_t::entry_t::do_stat() const {
}
}
dir_iter_t::dir_iter_t(const wcstring &path) {
dir_iter_t::dir_iter_t(const wcstring &path, bool withdot) {
dir_.reset(wopendir(path));
if (!dir_) {
error_ = errno;
return;
}
withdot_ = withdot;
entry_.dirfd_ = dirfd(&*dir_);
}
@ -211,8 +212,9 @@ const dir_iter_t::entry_t *dir_iter_t::next() {
error_ = errno;
return nullptr;
}
// Skip . and ..
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
// Skip . and ..,
// unless we've been told not to.
if (!withdot_ && (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))) {
return next();
}
entry_.reset();

View File

@ -171,12 +171,15 @@ enum class dir_entry_type_t : uint8_t {
/// symlink, or if the caller asks for the stat buffer.
/// Symlinks are followed.
class dir_iter_t : noncopyable_t {
private:
/// Whether this dir_iter considers the "." and ".." filesystem entries.
bool withdot_{false};
public:
struct entry_t;
/// Open a directory at a given path. On failure, \p error() will return the error code.
/// Note opendir is guaranteed to set close-on-exec by POSIX (hooray).
explicit dir_iter_t(const wcstring &path);
explicit dir_iter_t(const wcstring &path, bool withdot = false);
/// Advance this iterator.
/// \return a pointer to the entry, or nullptr if the entry is finished, or an error occurred.

View File

@ -267,3 +267,7 @@ begin
# CHECK: $PWD is absolute
cd ../../..
end
complete -C'cd .'
# CHECK: ../
# CHECK: ./