summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-10-13 19:46:09 +0100
committerMaxime Coste <frrrwww@gmail.com>2016-10-13 19:46:09 +0100
commit1f3e424047176da8ab48dca800f80fbe147e5f1f (patch)
treedfd2ab3f8ccdedb0834ede3382edcef07ead750b /src
parentee5c24686158a94d8be590b695028da2310fb115 (diff)
Do not expand filenames when doing insert filename completion
Fixes #855
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc9
-rw-r--r--src/file.cc17
-rw-r--r--src/file.hh13
3 files changed, 27 insertions, 12 deletions
diff --git a/src/commands.cc b/src/commands.cc
index 0cc27662..cae54822 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -111,7 +111,7 @@ auto filename_completer = make_completer(
{ return Completions{ 0_byte, cursor_pos,
complete_filename(prefix,
context.options()["ignored_files"].get<Regex>(),
- cursor_pos) }; });
+ cursor_pos, FilenameFlags::Expand) }; });
static Completions complete_buffer_name(const Context& context, CompletionFlags flags,
StringView prefix, ByteCount cursor_pos)
@@ -873,7 +873,7 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
auto& ignored_files = context.options()["ignored_files"].get<Regex>();
return Completions{ 0_byte, pos_in_token,
complete_filename(prefix, ignored_files,
- pos_in_token) };
+ pos_in_token, FilenameFlags::Expand) };
};
}
else if (parser.get_switch("client-completion"))
@@ -1678,7 +1678,8 @@ const CommandDesc prompt_cmd = {
StringView prefix, ByteCount cursor_pos) -> Completions {
auto& ignored_files = context.options()["ignored_files"].get<Regex>();
return { 0_byte, cursor_pos,
- complete_filename(prefix, ignored_files, cursor_pos) };
+ complete_filename(prefix, ignored_files, cursor_pos,
+ FilenameFlags::Expand) };
};
else if (parser.get_switch("client-completion"))
completer = [](const Context& context, CompletionFlags,
@@ -1968,7 +1969,7 @@ const CommandDesc change_working_directory_cmd = {
return { 0_byte, cursor_pos,
complete_filename(prefix,
context.options()["ignored_files"].get<Regex>(),
- cursor_pos, true) };
+ cursor_pos, FilenameFlags::OnlyDirectories) };
}),
[](const ParametersParser& parser, Context&, const ShellContext&)
{
diff --git a/src/file.cc b/src/file.cc
index a4ea99b0..16b3cf04 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -392,24 +392,26 @@ static CandidateList candidates(ConstArrayView<RankedMatch> matches, StringView
}
CandidateList complete_filename(StringView prefix, const Regex& ignored_regex,
- ByteCount cursor_pos, bool only_dir)
+ ByteCount cursor_pos, FilenameFlags flags)
{
- String real_prefix = parse_filename(prefix.substr(0, cursor_pos));
+ prefix = prefix.substr(0, cursor_pos);
StringView dirname, fileprefix;
- std::tie(dirname, fileprefix) = split_path(real_prefix);
+ std::tie(dirname, fileprefix) = split_path(prefix);
+ auto parsed_dirname = parse_filename(dirname);
const bool check_ignored_regex = not ignored_regex.empty() and
not regex_match(fileprefix.begin(), fileprefix.end(), ignored_regex);
const bool include_hidden = fileprefix.substr(0_byte, 1_byte) == ".";
+ const bool only_dirs = (flags & FilenameFlags::OnlyDirectories);
- auto filter = [&ignored_regex, check_ignored_regex, include_hidden, only_dir](const dirent& entry, struct stat& st)
+ auto filter = [&ignored_regex, check_ignored_regex, include_hidden, only_dirs](const dirent& entry, struct stat& st)
{
StringView name{entry.d_name};
return (include_hidden or name.substr(0_byte, 1_byte) != ".") and
(not check_ignored_regex or not regex_match(name.begin(), name.end(), ignored_regex)) and
- (not only_dir or S_ISDIR(st.st_mode));
+ (not only_dirs or S_ISDIR(st.st_mode));
};
- auto files = list_files(dirname, filter);
+ auto files = list_files(parsed_dirname, filter);
Vector<RankedMatch> matches;
for (auto& file : files)
{
@@ -417,7 +419,8 @@ CandidateList complete_filename(StringView prefix, const Regex& ignored_regex,
matches.push_back(match);
}
std::sort(matches.begin(), matches.end());
- return candidates(matches, dirname);
+ const bool expand = (flags & FilenameFlags::Expand);
+ return candidates(matches, expand ? parsed_dirname : dirname);
}
Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
diff --git a/src/file.hh b/src/file.hh
index 2dde1abb..2c73ed7b 100644
--- a/src/file.hh
+++ b/src/file.hh
@@ -5,6 +5,7 @@
#include "completion.hh"
#include "exception.hh"
#include "regex.hh"
+#include "flags.hh"
#include <sys/types.h>
#include <sys/stat.h>
@@ -83,8 +84,18 @@ constexpr bool operator!=(const timespec& lhs, const timespec& rhs)
return not (lhs == rhs);
}
+enum class FilenameFlags
+{
+ None = 0,
+ OnlyDirectories = 1 << 0,
+ Expand = 1 << 1
+};
+
+template<> struct WithBitOps<FilenameFlags> : std::true_type {};
+
CandidateList complete_filename(StringView prefix, const Regex& ignore_regex,
- ByteCount cursor_pos = -1, bool only_dir = false);
+ ByteCount cursor_pos = -1,
+ FilenameFlags flags = FilenameFlags::None);
CandidateList complete_command(StringView prefix, ByteCount cursor_pos = -1);