Remove EXPAND prefix from expand_flags and lowercase them

This commit is contained in:
ridiculousfish
2019-04-25 11:34:49 -07:00
parent d8ab6290e8
commit 496529b20a
8 changed files with 113 additions and 122 deletions

View File

@@ -360,10 +360,10 @@ class completer_t {
// Never do command substitution in autosuggestions. Sadly, we also can't yet do job
// expansion because it's not thread safe.
expand_flags_t result{};
if (this->type() == COMPLETE_AUTOSUGGEST) result |= expand_flag::EXPAND_SKIP_CMDSUBST;
if (this->type() == COMPLETE_AUTOSUGGEST) result |= expand_flag::skip_cmdsubst;
// Allow fuzzy matching.
if (this->fuzzy()) result |= expand_flag::EXPAND_FUZZY_MATCH;
if (this->fuzzy()) result |= expand_flag::fuzzy_match;
return result;
}
@@ -546,8 +546,7 @@ void completer_t::complete_strings(const wcstring &wc_escaped, const description
complete_flags_t flags) {
wcstring tmp = wc_escaped;
if (!expand_one(tmp,
this->expand_flags() | expand_flag::EXPAND_SKIP_CMDSUBST |
expand_flag::EXPAND_SKIP_WILDCARDS,
this->expand_flags() | expand_flag::skip_cmdsubst | expand_flag::skip_wildcards,
vars))
return;
@@ -670,8 +669,8 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
// Append all possible executables
expand_result_t result =
expand_string(str_cmd, &this->completions,
this->expand_flags() | expand_flag::EXPAND_SPECIAL_FOR_COMMAND |
expand_flag::EXPAND_FOR_COMPLETIONS | expand_flag::EXECUTABLES_ONLY,
this->expand_flags() | expand_flag::special_for_command |
expand_flag::for_completions | expand_flag::executables_only,
vars, NULL);
if (result != expand_result_t::error && this->wants_descriptions()) {
this->complete_cmd_desc(str_cmd);
@@ -683,10 +682,10 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
// updated with choices for the user.
expand_result_t ignore =
// Append all matching directories
expand_string(str_cmd, &this->completions,
this->expand_flags() | expand_flag::EXPAND_FOR_COMPLETIONS |
expand_flag::DIRECTORIES_ONLY,
vars, NULL);
expand_string(
str_cmd, &this->completions,
this->expand_flags() | expand_flag::for_completions | expand_flag::directories_only,
vars, NULL);
UNUSED(ignore);
}
@@ -754,8 +753,8 @@ void completer_t::complete_from_args(const wcstring &str, const wcstring &args,
expand_flags_t eflags{};
if (is_autosuggest) {
eflags |= expand_flag::EXPAND_NO_DESCRIPTIONS;
eflags |= expand_flag::EXPAND_SKIP_CMDSUBST;
eflags |= expand_flag::no_descriptions;
eflags |= expand_flag::skip_cmdsubst;
}
std::vector<completion_t> possible_comp;
@@ -1067,22 +1066,21 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt,
/// Perform generic (not command-specific) expansions on the specified string.
void completer_t::complete_param_expand(const wcstring &str, bool do_file,
bool handle_as_special_cd) {
expand_flags_t flags = this->expand_flags() | expand_flag::EXPAND_SKIP_CMDSUBST |
expand_flag::EXPAND_FOR_COMPLETIONS;
expand_flags_t flags =
this->expand_flags() | expand_flag::skip_cmdsubst | expand_flag::for_completions;
if (!do_file) flags |= expand_flag::EXPAND_SKIP_WILDCARDS;
if (!do_file) flags |= expand_flag::skip_wildcards;
if (handle_as_special_cd && do_file) {
if (this->type() == COMPLETE_AUTOSUGGEST) {
flags |= expand_flag::EXPAND_SPECIAL_FOR_CD_AUTOSUGGEST;
flags |= expand_flag::special_for_cd_autosuggestion;
}
flags |= expand_flags_t{expand_flag::DIRECTORIES_ONLY, expand_flag::EXPAND_SPECIAL_FOR_CD,
expand_flag::EXPAND_NO_DESCRIPTIONS};
flags |= expand_flags_t{expand_flag::directories_only, expand_flag::special_for_cd,
expand_flag::no_descriptions};
}
// Squelch file descriptions per issue #254.
if (this->type() == COMPLETE_AUTOSUGGEST || do_file)
flags |= expand_flag::EXPAND_NO_DESCRIPTIONS;
if (this->type() == COMPLETE_AUTOSUGGEST || do_file) flags |= expand_flag::no_descriptions;
// We have the following cases:
//
@@ -1119,7 +1117,7 @@ void completer_t::complete_param_expand(const wcstring &str, bool do_file,
if (complete_from_start) {
// Don't do fuzzy matching for files if the string begins with a dash (issue #568). We could
// consider relaxing this if there was a preceding double-dash argument.
if (string_prefixes_string(L"-", str)) flags.clear(expand_flag::EXPAND_FUZZY_MATCH);
if (string_prefixes_string(L"-", str)) flags.clear(expand_flag::fuzzy_match);
if (expand_string(str, &this->completions, flags, vars, NULL) == expand_result_t::error) {
debug(3, L"Error while expanding string '%ls'", str.c_str());

View File

@@ -511,7 +511,7 @@ static expand_result_t expand_braces(const wcstring &instr, expand_flags_t flags
}
if (brace_count > 0) {
if (!(flags & expand_flag::EXPAND_FOR_COMPLETIONS)) {
if (!(flags & expand_flag::for_completions)) {
syntax_error = true;
} else {
// The user hasn't typed an end brace yet; make one up and append it, then expand
@@ -527,7 +527,7 @@ static expand_result_t expand_braces(const wcstring &instr, expand_flags_t flags
}
// Note: this code looks very fishy, apparently it has never worked.
return expand_braces(mod, expand_flag::EXPAND_SKIP_CMDSUBST, out, errors);
return expand_braces(mod, expand_flag::skip_cmdsubst, out, errors);
}
}
@@ -838,7 +838,7 @@ wcstring replace_home_directory_with_tilde(const wcstring &str, const environmen
}
/// Remove any internal separators. Also optionally convert wildcard characters to regular
/// equivalents. This is done to support EXPAND_SKIP_WILDCARDS.
/// equivalents. This is done to support skip_wildcards.
static void remove_internal_separator(wcstring *str, bool conv) {
// Remove all instances of INTERNAL_SEPARATOR.
str->erase(std::remove(str->begin(), str->end(), (wchar_t)INTERNAL_SEPARATOR), str->end());
@@ -898,7 +898,7 @@ class expander_t {
};
expand_result_t expander_t::stage_cmdsubst(wcstring input, std::vector<completion_t> *out) {
if (flags & expand_flag::EXPAND_SKIP_CMDSUBST) {
if (flags & expand_flag::skip_cmdsubst) {
size_t cur = 0, start = 0, end;
switch (parse_util_locate_cmdsubst_range(input, &cur, nullptr, &start, &end, true)) {
case 0:
@@ -924,7 +924,7 @@ expand_result_t expander_t::stage_variables(wcstring input, std::vector<completi
wcstring next;
unescape_string(input, &next, UNESCAPE_SPECIAL | UNESCAPE_INCOMPLETE);
if (flags & expand_flag::EXPAND_SKIP_VARIABLES) {
if (flags & expand_flag::skip_variables) {
for (size_t i = 0; i < next.size(); i++) {
if (next.at(i) == VARIABLE_EXPAND) {
next[i] = L'$';
@@ -946,7 +946,7 @@ expand_result_t expander_t::stage_braces(wcstring input, std::vector<completion_
}
expand_result_t expander_t::stage_home_and_self(wcstring input, std::vector<completion_t> *out) {
if (!(flags & expand_flag::EXPAND_SKIP_HOME_DIRECTORIES)) {
if (!(flags & expand_flag::skip_home_directories)) {
expand_home_directory(input, vars);
}
expand_percent_self(input);
@@ -958,30 +958,30 @@ expand_result_t expander_t::stage_wildcards(wcstring path_to_expand,
std::vector<completion_t> *out) {
expand_result_t result = expand_result_t::ok;
remove_internal_separator(&path_to_expand, flags & expand_flag::EXPAND_SKIP_WILDCARDS);
remove_internal_separator(&path_to_expand, flags & expand_flag::skip_wildcards);
const bool has_wildcard = wildcard_has(path_to_expand, true /* internal, i.e. ANY_STRING */);
const bool for_completions = flags & expand_flag::EXPAND_FOR_COMPLETIONS;
const bool skip_wildcards = flags & expand_flag::EXPAND_SKIP_WILDCARDS;
const bool for_completions = flags & expand_flag::for_completions;
const bool skip_wildcards = flags & expand_flag::skip_wildcards;
if (has_wildcard && (flags & expand_flag::EXECUTABLES_ONLY)) {
if (has_wildcard && (flags & expand_flag::executables_only)) {
; // don't do wildcard expansion for executables, see issue #785
} else if ((for_completions && !skip_wildcards) || has_wildcard) {
// We either have a wildcard, or we don't have a wildcard but we're doing completion
// expansion (so we want to get the completion of a file path). Note that if
// EXPAND_SKIP_WILDCARDS is set, we stomped wildcards in remove_internal_separator above, so
// skip_wildcards is set, we stomped wildcards in remove_internal_separator above, so
// there actually aren't any.
//
// So we're going to treat this input as a file path. Compute the "working directories",
// which may be CDPATH if the special flag is set.
const wcstring working_dir = vars.get_pwd_slash();
wcstring_list_t effective_working_dirs;
bool for_cd = flags & expand_flag::EXPAND_SPECIAL_FOR_CD;
bool for_command = flags & expand_flag::EXPAND_SPECIAL_FOR_COMMAND;
bool for_cd = flags & expand_flag::special_for_cd;
bool for_command = flags & expand_flag::special_for_command;
if (!for_cd && !for_command) {
// Common case.
effective_working_dirs.push_back(working_dir);
} else {
// Either EXPAND_SPECIAL_FOR_COMMAND or EXPAND_SPECIAL_FOR_CD. We can handle these
// Either special_for_command or special_for_cd. We can handle these
// mostly the same. There's the following differences:
//
// 1. An empty CDPATH should be treated as '.', but an empty PATH should be left empty
@@ -1039,7 +1039,7 @@ expand_result_t expander_t::stage_wildcards(wcstring path_to_expand,
// Can't fully justify this check. I think it's that SKIP_WILDCARDS is used when completing
// to mean don't do file expansions, so if we're not doing file expansions, just drop this
// completion on the floor.
if (!(flags & expand_flag::EXPAND_FOR_COMPLETIONS)) {
if (!(flags & expand_flag::for_completions)) {
append_completion(out, std::move(path_to_expand));
}
}
@@ -1051,7 +1051,7 @@ expand_result_t expander_t::expand_string(wcstring input,
expand_flags_t flags, const environment_t &vars,
parse_error_list_t *errors) {
// Early out. If we're not completing, and there's no magic in the input, we're done.
if (!(flags & expand_flag::EXPAND_FOR_COMPLETIONS) && expand_is_clean(input)) {
if (!(flags & expand_flag::for_completions) && expand_is_clean(input)) {
append_completion(out_completions, std::move(input));
return expand_result_t::ok;
}
@@ -1093,7 +1093,7 @@ expand_result_t expander_t::expand_string(wcstring input,
if (total_result != expand_result_t::error) {
// Hack to un-expand tildes (see #647).
if (!(flags & expand_flag::EXPAND_SKIP_HOME_DIRECTORIES)) {
if (!(flags & expand_flag::skip_home_directories)) {
unexpand_tildes(input, vars, &completions);
}
out_completions->insert(out_completions->end(),
@@ -1114,12 +1114,12 @@ bool expand_one(wcstring &string, expand_flags_t flags, const environment_t &var
parse_error_list_t *errors) {
std::vector<completion_t> completions;
if (!flags.get(expand_flag::EXPAND_FOR_COMPLETIONS) && expand_is_clean(string)) {
if (!flags.get(expand_flag::for_completions) && expand_is_clean(string)) {
return true;
}
if (expand_string(string, &completions, flags | expand_flag::EXPAND_NO_DESCRIPTIONS, vars,
errors) != expand_result_t::error &&
if (expand_string(string, &completions, flags | expand_flag::no_descriptions, vars, errors) !=
expand_result_t::error &&
completions.size() == 1) {
string = std::move(completions.at(0).completion);
return true;
@@ -1138,11 +1138,10 @@ expand_result_t expand_to_command_and_args(const wcstring &instr, const environm
}
std::vector<completion_t> completions;
expand_result_t expand_err =
expand_string(instr, &completions,
{expand_flag::EXPAND_SKIP_CMDSUBST, expand_flag::EXPAND_NO_DESCRIPTIONS,
expand_flag::EXPAND_SKIP_JOBS},
vars, errors);
expand_result_t expand_err = expand_string(
instr, &completions,
{expand_flag::skip_cmdsubst, expand_flag::no_descriptions, expand_flag::skip_jobs}, vars,
errors);
if (expand_err == expand_result_t::ok || expand_err == expand_result_t::wildcard_match) {
// The first completion is the command, any remaning are arguments.
bool first = true;

View File

@@ -22,41 +22,41 @@ class environment_t;
class env_var_t;
class environment_t;
/// Set of flags controlling expansions.
enum class expand_flag {
/// Flag specifying that cmdsubst expansion should be skipped.
EXPAND_SKIP_CMDSUBST,
/// Flag specifying that variable expansion should be skipped.
EXPAND_SKIP_VARIABLES,
/// Flag specifying that wildcard expansion should be skipped.
EXPAND_SKIP_WILDCARDS,
/// Skip command substitutions.
skip_cmdsubst,
/// Skip variable expansion.
skip_variables,
/// Skip wildcard expansion.
skip_wildcards,
/// The expansion is being done for tab or auto completions. Returned completions may have the
/// wildcard as a prefix instead of a match.
EXPAND_FOR_COMPLETIONS,
for_completions,
/// Only match files that are executable by the current user.
EXECUTABLES_ONLY,
executables_only,
/// Only match directories.
DIRECTORIES_ONLY,
directories_only,
/// Don't generate descriptions.
EXPAND_NO_DESCRIPTIONS,
/// Don't expand jobs (but you can still expand processes). This is because
/// job expansion is not thread safe.
EXPAND_SKIP_JOBS,
no_descriptions,
/// Don't expand jobs (but still expand processes).
skip_jobs,
/// Don't expand home directories.
EXPAND_SKIP_HOME_DIRECTORIES,
skip_home_directories,
/// Allow fuzzy matching.
EXPAND_FUZZY_MATCH,
fuzzy_match,
/// Disallow directory abbreviations like /u/l/b for /usr/local/bin. Only applicable if
/// EXPAND_FUZZY_MATCH is set.
EXPAND_NO_FUZZY_DIRECTORIES,
/// fuzzy_match is set.
no_fuzzy_directories,
/// Do expansions specifically to support cd. This means using CDPATH as a list of potential
/// working directories, and to use logical instead of physical paths.
EXPAND_SPECIAL_FOR_CD,
special_for_cd,
/// Do expansions specifically for cd autosuggestion. This is to differentiate between cd
/// completions and cd autosuggestions.
EXPAND_SPECIAL_FOR_CD_AUTOSUGGEST,
special_for_cd_autosuggestion,
/// Do expansions specifically to support external command completions. This means using PATH as
/// a list of potential working directories.
EXPAND_SPECIAL_FOR_COMMAND,
special_for_command,
COUNT,
};
@@ -123,7 +123,7 @@ enum class expand_result_t {
/// \param input The parameter to expand
/// \param output The list to which the result will be appended.
/// \param flags Specifies if any expansion pass should be skipped. Legal values are any combination
/// of EXPAND_SKIP_CMDSUBST EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
/// of skip_cmdsubst skip_variables and skip_wildcards
/// \param vars variables used during expansion.
/// \param errors Resulting errors, or NULL to ignore
///
@@ -139,7 +139,7 @@ __warn_unused expand_result_t expand_string(wcstring input, std::vector<completi
///
/// \param inout_str The parameter to expand in-place
/// \param flags Specifies if any expansion pass should be skipped. Legal values are any combination
/// of EXPAND_SKIP_CMDSUBST EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
/// of skip_cmdsubst skip_variables and skip_wildcards
/// \param errors Resulting errors, or NULL to ignore
///
/// \return Whether expansion succeded

View File

@@ -1669,11 +1669,10 @@ static void test_expand() {
expand_test(L"foo", noflags, L"foo", 0, L"Strings do not expand to themselves");
expand_test(L"a{b,c,d}e", noflags, L"abe", L"ace", L"ade", 0, L"Bracket expansion is broken");
expand_test(L"a*", expand_flag::EXPAND_SKIP_WILDCARDS, L"a*", 0,
L"Cannot skip wildcard expansion");
expand_test(L"/bin/l\\0", expand_flag::EXPAND_FOR_COMPLETIONS, 0,
expand_test(L"a*", expand_flag::skip_wildcards, L"a*", 0, L"Cannot skip wildcard expansion");
expand_test(L"/bin/l\\0", expand_flag::for_completions, 0,
L"Failed to handle null escape in expansion");
expand_test(L"foo\\$bar", expand_flag::EXPAND_SKIP_VARIABLES, L"foo$bar", 0,
expand_test(L"foo\\$bar", expand_flag::skip_variables, L"foo$bar", 0,
L"Failed to handle dollar sign in variable-skipping expansion");
// bb
@@ -1747,27 +1746,25 @@ static void test_expand() {
expand_test(L"test/fish_expand_test/**/q", noflags, L"test/fish_expand_test/lol/nub/q", wnull,
L"Glob did the wrong thing 7");
expand_test(L"test/fish_expand_test/BA", expand_flag::EXPAND_FOR_COMPLETIONS,
expand_test(L"test/fish_expand_test/BA", expand_flag::for_completions,
L"test/fish_expand_test/bar", L"test/fish_expand_test/bax/",
L"test/fish_expand_test/baz/", wnull, L"Case insensitive test did the wrong thing");
expand_test(L"test/fish_expand_test/BA", expand_flag::EXPAND_FOR_COMPLETIONS,
expand_test(L"test/fish_expand_test/BA", expand_flag::for_completions,
L"test/fish_expand_test/bar", L"test/fish_expand_test/bax/",
L"test/fish_expand_test/baz/", wnull, L"Case insensitive test did the wrong thing");
expand_test(L"test/fish_expand_test/bb/yyy", expand_flag::EXPAND_FOR_COMPLETIONS,
expand_test(L"test/fish_expand_test/bb/yyy", expand_flag::for_completions,
/* nothing! */ wnull, L"Wrong fuzzy matching 1");
expand_test(
L"test/fish_expand_test/bb/x",
expand_flags_t{expand_flag::EXPAND_FOR_COMPLETIONS, expand_flag::EXPAND_FUZZY_MATCH}, L"",
wnull, // we just expect the empty string since this is an exact match
L"Wrong fuzzy matching 2");
expand_test(L"test/fish_expand_test/bb/x",
expand_flags_t{expand_flag::for_completions, expand_flag::fuzzy_match}, L"",
wnull, // we just expect the empty string since this is an exact match
L"Wrong fuzzy matching 2");
// Some vswprintfs refuse to append ANY_STRING in a format specifiers, so don't use
// format_string here.
const expand_flags_t fuzzy_comp{expand_flag::EXPAND_FOR_COMPLETIONS,
expand_flag::EXPAND_FUZZY_MATCH};
const expand_flags_t fuzzy_comp{expand_flag::for_completions, expand_flag::fuzzy_match};
const wcstring any_str_str(1, ANY_STRING);
expand_test(L"test/fish_expand_test/b/xx*", fuzzy_comp,
(L"test/fish_expand_test/bax/xx" + any_str_str).c_str(),

View File

@@ -432,7 +432,7 @@ bool autosuggest_validate_from_history(const history_item_t &item,
if (parsed_command == L"cd" && !cd_dir.empty()) {
// We can possibly handle this specially.
if (expand_one(cd_dir, expand_flag::EXPAND_SKIP_CMDSUBST, vars)) {
if (expand_one(cd_dir, expand_flag::skip_cmdsubst, vars)) {
handled = true;
bool is_help =
string_prefixes_string(cd_dir, L"--help") || string_prefixes_string(cd_dir, L"-h");
@@ -926,7 +926,7 @@ void highlighter_t::color_arguments(const std::vector<tnode_t<g::argument>> &arg
if (cmd_is_cd) {
// Mark this as an error if it's not 'help' and not a valid cd path.
wcstring param = arg.get_source(this->buff);
if (expand_one(param, expand_flag::EXPAND_SKIP_CMDSUBST, vars)) {
if (expand_one(param, expand_flag::skip_cmdsubst, vars)) {
bool is_help = string_prefixes_string(param, L"--help") ||
string_prefixes_string(param, L"-h");
if (!is_help && this->io_ok &&
@@ -969,7 +969,7 @@ void highlighter_t::color_redirection(tnode_t<g::redirection> redirection_node)
// I/O is disallowed, so we don't have much hope of catching anything but gross
// errors. Assume it's valid.
target_is_valid = true;
} else if (!expand_one(target, expand_flag::EXPAND_SKIP_CMDSUBST, vars)) {
} else if (!expand_one(target, expand_flag::skip_cmdsubst, vars)) {
// Could not be expanded.
target_is_valid = false;
} else {

View File

@@ -128,8 +128,7 @@ tnode_t<g::plain_statement> parse_execution_context_t::infinite_recursive_statem
if (plain_statement) {
maybe_t<wcstring> cmd = command_for_plain_statement(plain_statement, pstree->src);
if (cmd &&
expand_one(*cmd,
{expand_flag::EXPAND_SKIP_CMDSUBST, expand_flag::EXPAND_SKIP_VARIABLES},
expand_one(*cmd, {expand_flag::skip_cmdsubst, expand_flag::skip_variables},
nullenv) &&
cmd == forbidden_function_name) {
// This is it.
@@ -453,7 +452,7 @@ parse_execution_result_t parse_execution_context_t::run_switch_statement(
std::vector<completion_t> switch_values_expanded;
parse_error_list_t errors;
auto expand_ret = expand_string(switch_value, &switch_values_expanded,
expand_flag::EXPAND_NO_DESCRIPTIONS, parser->vars(), &errors);
expand_flag::no_descriptions, parser->vars(), &errors);
parse_error_offset_source_start(&errors, switch_value_n.source_range()->start);
switch (expand_ret) {
@@ -909,7 +908,7 @@ parse_execution_result_t parse_execution_context_t::expand_arguments_from_nodes(
// Expand this string.
parse_error_list_t errors;
arg_expanded.clear();
auto expand_ret = expand_string(arg_str, &arg_expanded, expand_flag::EXPAND_NO_DESCRIPTIONS,
auto expand_ret = expand_string(arg_str, &arg_expanded, expand_flag::no_descriptions,
parser->vars(), &errors);
parse_error_offset_source_start(&errors, arg_node.source_range()->start);
switch (expand_ret) {
@@ -957,10 +956,9 @@ bool parse_execution_context_t::determine_io_chain(tnode_t<g::arguments_or_redir
wcstring target; // file path or target fd
auto redirect_type = redirection_type(redirect_node, pstree->src, &source_fd, &target);
// PCA: I can't justify this EXPAND_SKIP_VARIABLES flag. It was like this when I got here.
bool target_expanded =
expand_one(target, no_exec ? expand_flag::EXPAND_SKIP_VARIABLES : expand_flags_t{},
parser->vars());
// PCA: I can't justify this skip_variables flag. It was like this when I got here.
bool target_expanded = expand_one(
target, no_exec ? expand_flag::skip_variables : expand_flags_t{}, parser->vars());
if (!target_expanded || target.empty()) {
// TODO: Improve this error message.
errored =

View File

@@ -167,7 +167,7 @@ static wcstring resolve_description(const wcstring &full_completion, wcstring *c
completion->resize(complete_sep_loc);
return description;
}
if (expand_flags & expand_flag::EXPAND_NO_DESCRIPTIONS) return {};
if (expand_flags & expand_flag::no_descriptions) return {};
return desc_func ? desc_func(full_completion) : wcstring{};
}
@@ -219,7 +219,7 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc,
// If we're allowing fuzzy match, any match is OK. Otherwise we require a prefix match.
bool match_acceptable;
if (params.expand_flags & expand_flag::EXPAND_FUZZY_MATCH) {
if (params.expand_flags & expand_flag::fuzzy_match) {
match_acceptable = match.type != fuzzy_match_none;
} else {
match_acceptable = match_type_shares_prefix(match.type);
@@ -381,8 +381,8 @@ static const wchar_t *file_get_desc(const wcstring &filename, int lstat_res, con
return COMPLETE_FILE_DESC;
}
/// Test if the given file is an executable (if EXECUTABLES_ONLY) or directory (if
/// DIRECTORIES_ONLY). If it matches, call wildcard_complete() with some description that we make
/// Test if the given file is an executable (if executables_only) or directory (if
/// directories_only). If it matches, call wildcard_complete() with some description that we make
/// up. Note that the filename came from a readdir() call, so we know it exists.
static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wcstring &filename,
const wchar_t *wc, expand_flags_t expand_flags,
@@ -415,12 +415,12 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc
const bool is_directory = stat_res == 0 && S_ISDIR(stat_buf.st_mode);
const bool is_executable = stat_res == 0 && S_ISREG(stat_buf.st_mode);
const bool need_directory = expand_flags & expand_flag::DIRECTORIES_ONLY;
const bool need_directory = expand_flags & expand_flag::directories_only;
if (need_directory && !is_directory) {
return false;
}
const bool executables_only = expand_flags & expand_flag::EXECUTABLES_ONLY;
const bool executables_only = expand_flags & expand_flag::executables_only;
if (executables_only && (!is_executable || waccess(filepath, X_OK) != 0)) {
return false;
}
@@ -432,7 +432,7 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc
// Compute the description.
wcstring desc;
if (!(expand_flags & expand_flag::EXPAND_NO_DESCRIPTIONS)) {
if (!(expand_flags & expand_flag::no_descriptions)) {
desc = file_get_desc(filepath, lstat_res, lstat_buf, stat_res, stat_buf, stat_errno);
if (file_size >= 0) {
@@ -507,7 +507,7 @@ class wildcard_expander_t {
void add_expansion_result(const wcstring &result) {
// This function is only for the non-completions case.
assert(!(this->flags & expand_flag::EXPAND_FOR_COMPLETIONS));
assert(!(this->flags & expand_flag::for_completions));
if (this->completion_set.insert(result).second) {
append_completion(this->resolved_completions, result);
this->did_add = true;
@@ -568,13 +568,13 @@ class wildcard_expander_t {
void try_add_completion_result(const wcstring &filepath, const wcstring &filename,
const wcstring &wildcard, const wcstring &prefix) {
// This function is only for the completions case.
assert(this->flags & expand_flag::EXPAND_FOR_COMPLETIONS);
assert(this->flags & expand_flag::for_completions);
wcstring abs_path = this->working_directory;
append_path_component(abs_path, filepath);
// We must normalize the path to allow 'cd ..' to operate on logical paths.
if (flags & expand_flag::EXPAND_SPECIAL_FOR_CD) abs_path = normalize_path(abs_path);
if (flags & expand_flag::special_for_cd) abs_path = normalize_path(abs_path);
size_t before = this->resolved_completions->size();
if (wildcard_test_flags_then_complete(abs_path, filename, wildcard.c_str(), this->flags,
@@ -592,11 +592,11 @@ class wildcard_expander_t {
c->prepend_token_prefix(prefix);
}
// Implement EXPAND_SPECIAL_FOR_CD_AUTOSUGGEST by descending the deepest unique
// Implement special_for_cd_autosuggestion by descending the deepest unique
// hierarchy we can, and then appending any components to each new result.
// Only descend deepest unique for cd autosuggest and not for cd tab completion
// (issue #4402).
if (flags & expand_flag::EXPAND_SPECIAL_FOR_CD_AUTOSUGGEST) {
if (flags & expand_flag::special_for_cd_autosuggestion) {
wcstring unique_hierarchy = this->descend_unique_hierarchy(abs_path);
if (!unique_hierarchy.empty()) {
for (size_t i = before; i < after; i++) {
@@ -614,7 +614,7 @@ class wildcard_expander_t {
DIR *open_dir(const wcstring &base_dir) const {
wcstring path = this->working_directory;
append_path_component(path, base_dir);
if (flags & expand_flag::EXPAND_SPECIAL_FOR_CD) {
if (flags & expand_flag::special_for_cd) {
// cd operates on logical paths.
// for example, cd ../<tab> should complete "without resolving symlinks".
path = normalize_path(path);
@@ -660,7 +660,7 @@ void wildcard_expander_t::expand_trailing_slash(const wcstring &base_dir, const
return;
}
if (!(flags & expand_flag::EXPAND_FOR_COMPLETIONS)) {
if (!(flags & expand_flag::for_completions)) {
// Trailing slash and not accepting incomplete, e.g. `echo /xyz/`. Insert this file if it
// exists.
if (waccess(base_dir, F_OK) == 0) {
@@ -783,7 +783,7 @@ void wildcard_expander_t::expand_last_segment(const wcstring &base_dir, DIR *bas
const wcstring &wc, const wcstring &prefix) {
wcstring name_str;
while (wreaddir(base_dir_fp, name_str)) {
if (flags & expand_flag::EXPAND_FOR_COMPLETIONS) {
if (flags & expand_flag::for_completions) {
this->try_add_completion_result(base_dir + name_str, name_str, wc, prefix);
} else {
// Normal wildcard expansion, not for completions.
@@ -810,7 +810,7 @@ void wildcard_expander_t::expand_last_segment(const wcstring &base_dir, DIR *bas
/// prefix: the string that should be prepended for completions that replace their token.
// This is usually the same thing as the original wildcard, but for fuzzy matching, we
// expand intermediate segments. effective_prefix is always either empty, or ends with a slash
// Note: this is only used when doing completions (EXPAND_FOR_COMPLETIONS is true), not
// Note: this is only used when doing completions (for_completions is true), not
// expansions
void wildcard_expander_t::expand(const wcstring &base_dir, const wchar_t *wc,
const wcstring &effective_prefix) {
@@ -854,11 +854,11 @@ void wildcard_expander_t::expand(const wcstring &base_dir, const wchar_t *wc,
// Maybe try a fuzzy match (#94) if nothing was found with the literal match. Respect
// EXPAND_NO_DIRECTORY_ABBREVIATIONS (issue #2413).
// Don't do fuzzy matches if the literal segment was valid (#3211)
bool allow_fuzzy = this->flags.get(expand_flag::EXPAND_FUZZY_MATCH) &&
!this->flags.get(expand_flag::EXPAND_NO_FUZZY_DIRECTORIES);
bool allow_fuzzy = this->flags.get(expand_flag::fuzzy_match) &&
!this->flags.get(expand_flag::no_fuzzy_directories);
if (allow_fuzzy && this->resolved_completions->size() == before &&
waccess(intermediate_dirpath, F_OK) != 0) {
assert(this->flags & expand_flag::EXPAND_FOR_COMPLETIONS);
assert(this->flags & expand_flag::for_completions);
DIR *base_dir_fd = open_dir(base_dir);
if (base_dir_fd != NULL) {
this->expand_literal_intermediate_segment_with_fuzz(
@@ -904,15 +904,14 @@ int wildcard_expand_string(const wcstring &wc, const wcstring &working_directory
expand_flags_t flags, std::vector<completion_t> *output) {
assert(output != NULL);
// Fuzzy matching only if we're doing completions.
assert(flags.get(expand_flag::EXPAND_FOR_COMPLETIONS) ||
!flags.get(expand_flag::EXPAND_FUZZY_MATCH));
assert(flags.get(expand_flag::for_completions) || !flags.get(expand_flag::fuzzy_match));
// expand_flag::EXPAND_SPECIAL_FOR_CD requires expand_flag::DIRECTORIES_ONLY and
// expand_flag::EXPAND_FOR_COMPLETIONS and expand_flag::EXPAND_NO_DESCRIPTIONS.
assert(!(flags.get(expand_flag::EXPAND_SPECIAL_FOR_CD)) ||
((flags.get(expand_flag::DIRECTORIES_ONLY)) &&
(flags.get(expand_flag::EXPAND_FOR_COMPLETIONS)) &&
(flags.get(expand_flag::EXPAND_NO_DESCRIPTIONS))));
// expand_flag::special_for_cd requires expand_flag::directories_only and
// expand_flag::for_completions and expand_flag::no_descriptions.
assert(!(flags.get(expand_flag::special_for_cd)) ||
((flags.get(expand_flag::directories_only)) &&
(flags.get(expand_flag::for_completions)) &&
(flags.get(expand_flag::no_descriptions))));
// Hackish fix for issue #1631. We are about to call c_str(), which will produce a string
// truncated at any embedded nulls. We could fix this by passing around the size, etc. However

View File

@@ -37,8 +37,8 @@ enum {
///
/// \param wc The wildcard string
/// \param working_directory The working directory
/// \param flags flags for the search. Can be any combination of EXPAND_FOR_COMPLETIONS and
/// EXECUTABLES_ONLY
/// \param flags flags for the search. Can be any combination of for_completions and
/// executables_only
/// \param out The list in which to put the output
///
/// \return 1 if matches where found, 0 otherwise. Return -1 on abort (I.e. ^C was pressed).