Do not expand filenames when doing insert filename completion

Fixes #855
This commit is contained in:
Maxime Coste 2016-10-13 19:46:09 +01:00
parent ee5c246861
commit 1f3e424047
3 changed files with 27 additions and 12 deletions

View File

@ -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&)
{

View File

@ -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)

View File

@ -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);