summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc10
-rw-r--r--src/file.cc30
-rw-r--r--src/file.hh2
3 files changed, 20 insertions, 22 deletions
diff --git a/src/commands.cc b/src/commands.cc
index e0dbef07..43cfa850 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -1826,7 +1826,15 @@ const CommandDesc change_working_directory_cmd = {
single_name_param,
CommandFlags::None,
CommandHelper{},
- filename_completer,
+ PerArgumentCommandCompleter{{
+ [](const Context& context, CompletionFlags flags,
+ const String& prefix, ByteCount cursor_pos) -> Completions {
+ return { 0_byte, cursor_pos,
+ complete_filename(prefix,
+ context.options()["ignored_files"].get<Regex>(),
+ cursor_pos, true) };
+ }
+ }},
[](const ParametersParser& parser, Context&, const ShellContext&)
{
if (chdir(parse_filename(parser[0]).c_str()) != 0)
diff --git a/src/file.cc b/src/file.cc
index a558dc29..21e06836 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -348,13 +348,13 @@ Vector<String> list_files(StringView dirname, Filter filter)
while (dirent* entry = readdir(dir))
{
StringView filename = entry->d_name;
- if (filename.empty() or not filter(*entry))
+ if (filename.empty())
continue;
struct stat st;
auto fmt_str = (dirname.empty() or dirname.back() == '/') ? "{}{}" : "{}/{}";
format_to(buffer, fmt_str, dirname, filename);
- if (stat(buffer, &st) != 0)
+ if (stat(buffer, &st) != 0 or not filter(*entry, st))
continue;
if (S_ISDIR(st.st_mode))
@@ -366,7 +366,7 @@ Vector<String> list_files(StringView dirname, Filter filter)
Vector<String> list_files(StringView directory)
{
- return list_files(directory, [](const dirent& entry) {
+ return list_files(directory, [](const dirent& entry, const struct stat&) {
return StringView{entry.d_name}.substr(0_byte, 1_byte) != ".";
});
}
@@ -380,9 +380,8 @@ static CandidateList candidates(ConstArrayView<RankedMatch> matches, StringView
return res;
}
-CandidateList complete_filename(StringView prefix,
- const Regex& ignored_regex,
- ByteCount cursor_pos)
+CandidateList complete_filename(StringView prefix, const Regex& ignored_regex,
+ ByteCount cursor_pos, bool only_dir)
{
String real_prefix = parse_filename(prefix.substr(0, cursor_pos));
StringView dirname, fileprefix;
@@ -392,10 +391,11 @@ CandidateList complete_filename(StringView prefix,
not regex_match(fileprefix.begin(), fileprefix.end(), ignored_regex);
const bool include_hidden = fileprefix.substr(0_byte, 1_byte) == ".";
- auto filter = [&ignored_regex, check_ignored_regex, include_hidden](const dirent& entry)
+ auto filter = [&ignored_regex, check_ignored_regex, include_hidden, only_dir](const dirent& entry, struct stat& st)
{
return (include_hidden or StringView{entry.d_name}.substr(0_byte, 1_byte) != ".") and
- (not check_ignored_regex or not regex_match(entry.d_name, ignored_regex));
+ (not check_ignored_regex or not regex_match(entry.d_name, ignored_regex)) and
+ (not only_dir or S_ISDIR(st.st_mode));
};
auto files = list_files(dirname, filter);
Vector<RankedMatch> matches;
@@ -416,13 +416,8 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
if (not dirname.empty())
{
- auto filter = [&dirname](const dirent& entry)
+ auto filter = [&dirname](const dirent& entry, const struct stat& st)
{
- char buffer[PATH_MAX+1];
- format_to(buffer, "{}{}", dirname, entry.d_name);
- struct stat st;
- if (stat(buffer, &st) != 0)
- return false;
bool executable = (st.st_mode & S_IXUSR)
| (st.st_mode & S_IXGRP)
| (st.st_mode & S_IXOTH);
@@ -460,12 +455,7 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
auto& cache = command_cache[dirname];
if (memcmp(&cache.mtim, &st.st_mtim, sizeof(TimeSpec)) != 0)
{
- auto filter = [&dirname](const dirent& entry) {
- struct stat st;
- char buffer[PATH_MAX+1];
- format_to(buffer, "{}/{}", dirname, entry.d_name);
- if (stat(buffer, &st))
- return false;
+ auto filter = [&dirname](const dirent& entry, const struct stat& st) {
bool executable = (st.st_mode & S_IXUSR)
| (st.st_mode & S_IXGRP)
| (st.st_mode & S_IXOTH);
diff --git a/src/file.hh b/src/file.hh
index 9a17c2b1..29d979e3 100644
--- a/src/file.hh
+++ b/src/file.hh
@@ -83,7 +83,7 @@ constexpr bool operator!=(const timespec& lhs, const timespec& rhs)
}
CandidateList complete_filename(StringView prefix, const Regex& ignore_regex,
- ByteCount cursor_pos = -1);
+ ByteCount cursor_pos = -1, bool only_dir = false);
CandidateList complete_command(StringView prefix, ByteCount cursor_pos = -1);