mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-31 12:21:19 -03:00
Remove EXPAND prefix from expand_flags and lowercase them
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
44
src/expand.h
44
src/expand.h
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user