mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Migrate expansion stages to a new type expander_t
This avoids having to pass around so many parameters during expansion.
This commit is contained in:
parent
ae11bf4dcb
commit
b54c44f2f6
1 changed files with 61 additions and 37 deletions
|
@ -865,19 +865,39 @@ static void remove_internal_separator(wcstring *str, bool conv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A stage in string expansion is represented as a function that takes an input and returns a list
|
namespace {
|
||||||
/// of output (by reference). We get flags, vars and errors. It may return an error; if so expansion
|
/// A type that knows how to perform expansions.
|
||||||
/// halts.
|
class expander_t {
|
||||||
typedef expand_error_t (*expand_stage_t)(wcstring input, //!OCLINT(unused param)
|
/// Variables to use in expansion.
|
||||||
std::vector<completion_t> *out, //!OCLINT(unused param)
|
const environment_t &vars;
|
||||||
expand_flags_t flags, //!OCLINT(unused param)
|
|
||||||
const environment_t &vars, //!OCLINT(unused param)
|
|
||||||
parse_error_list_t *errors); //!OCLINT(unused param)
|
|
||||||
|
|
||||||
static expand_error_t expand_stage_cmdsubst(wcstring input, std::vector<completion_t> *out,
|
/// Flags to use during expansion.
|
||||||
expand_flags_t flags, const environment_t &vars,
|
const expand_flags_t flags;
|
||||||
parse_error_list_t *errors) {
|
|
||||||
UNUSED(vars);
|
/// List to receive any errors generated during expansion, or null to ignore errors.
|
||||||
|
parse_error_list_t *const errors;
|
||||||
|
|
||||||
|
/// An expansion stage is a member function pointer.
|
||||||
|
/// It accepts the input string (transferring ownership) and returns the list of output
|
||||||
|
/// completions by reference. It may return an error, which halts expansion.
|
||||||
|
using stage_t = expand_error_t (expander_t::*)(wcstring, std::vector<completion_t> *);
|
||||||
|
|
||||||
|
expand_error_t stage_cmdsubst(wcstring input, std::vector<completion_t> *out);
|
||||||
|
expand_error_t stage_variables(wcstring input, std::vector<completion_t> *out);
|
||||||
|
expand_error_t stage_braces(wcstring input, std::vector<completion_t> *out);
|
||||||
|
expand_error_t stage_home_and_self(wcstring input, std::vector<completion_t> *out);
|
||||||
|
expand_error_t stage_wildcards(wcstring path_to_expand, std::vector<completion_t> *out);
|
||||||
|
|
||||||
|
expander_t(const environment_t &vars, expand_flags_t flags, parse_error_list_t *errors)
|
||||||
|
: vars(vars), flags(flags), errors(errors) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static expand_error_t expand_string(wcstring input, std::vector<completion_t> *out_completions,
|
||||||
|
expand_flags_t flags, const environment_t &vars,
|
||||||
|
parse_error_list_t *errors);
|
||||||
|
};
|
||||||
|
|
||||||
|
expand_error_t expander_t::stage_cmdsubst(wcstring input, std::vector<completion_t> *out) {
|
||||||
if (EXPAND_SKIP_CMDSUBST & flags) {
|
if (EXPAND_SKIP_CMDSUBST & flags) {
|
||||||
size_t cur = 0, start = 0, end;
|
size_t cur = 0, start = 0, end;
|
||||||
switch (parse_util_locate_cmdsubst_range(input, &cur, nullptr, &start, &end, true)) {
|
switch (parse_util_locate_cmdsubst_range(input, &cur, nullptr, &start, &end, true)) {
|
||||||
|
@ -898,9 +918,7 @@ static expand_error_t expand_stage_cmdsubst(wcstring input, std::vector<completi
|
||||||
return EXPAND_OK;
|
return EXPAND_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static expand_error_t expand_stage_variables(wcstring input, std::vector<completion_t> *out,
|
expand_error_t expander_t::stage_variables(wcstring input, std::vector<completion_t> *out) {
|
||||||
expand_flags_t flags, const environment_t &vars,
|
|
||||||
parse_error_list_t *errors) {
|
|
||||||
// We accept incomplete strings here, since complete uses expand_string to expand incomplete
|
// We accept incomplete strings here, since complete uses expand_string to expand incomplete
|
||||||
// strings from the commandline.
|
// strings from the commandline.
|
||||||
wcstring next;
|
wcstring next;
|
||||||
|
@ -922,17 +940,12 @@ static expand_error_t expand_stage_variables(wcstring input, std::vector<complet
|
||||||
return EXPAND_OK;
|
return EXPAND_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static expand_error_t expand_stage_braces(wcstring input, std::vector<completion_t> *out,
|
expand_error_t expander_t::stage_braces(wcstring input, std::vector<completion_t> *out) {
|
||||||
expand_flags_t flags, const environment_t &vars,
|
|
||||||
parse_error_list_t *errors) {
|
|
||||||
UNUSED(vars);
|
UNUSED(vars);
|
||||||
return expand_braces(input, flags, out, errors);
|
return expand_braces(input, flags, out, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static expand_error_t expand_stage_home_and_self(wcstring input, std::vector<completion_t> *out,
|
expand_error_t expander_t::stage_home_and_self(wcstring input, std::vector<completion_t> *out) {
|
||||||
expand_flags_t flags, const environment_t &vars,
|
|
||||||
parse_error_list_t *errors) {
|
|
||||||
(void)errors;
|
|
||||||
if (!(EXPAND_SKIP_HOME_DIRECTORIES & flags)) {
|
if (!(EXPAND_SKIP_HOME_DIRECTORIES & flags)) {
|
||||||
expand_home_directory(input, vars);
|
expand_home_directory(input, vars);
|
||||||
}
|
}
|
||||||
|
@ -941,10 +954,8 @@ static expand_error_t expand_stage_home_and_self(wcstring input, std::vector<com
|
||||||
return EXPAND_OK;
|
return EXPAND_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static expand_error_t expand_stage_wildcards(wcstring path_to_expand, std::vector<completion_t> *out,
|
expand_error_t expander_t::stage_wildcards(wcstring path_to_expand,
|
||||||
expand_flags_t flags, const environment_t &vars,
|
std::vector<completion_t> *out) {
|
||||||
parse_error_list_t *errors) {
|
|
||||||
UNUSED(errors);
|
|
||||||
expand_error_t result = EXPAND_OK;
|
expand_error_t result = EXPAND_OK;
|
||||||
|
|
||||||
remove_internal_separator(&path_to_expand, flags & EXPAND_SKIP_WILDCARDS);
|
remove_internal_separator(&path_to_expand, flags & EXPAND_SKIP_WILDCARDS);
|
||||||
|
@ -1034,42 +1045,48 @@ static expand_error_t expand_stage_wildcards(wcstring path_to_expand, std::vecto
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
expand_error_t expand_string(wcstring input, std::vector<completion_t> *out_completions,
|
expand_error_t expander_t::expand_string(wcstring input, std::vector<completion_t> *out_completions,
|
||||||
expand_flags_t flags, const environment_t &vars,
|
expand_flags_t flags, const environment_t &vars,
|
||||||
parse_error_list_t *errors) {
|
parse_error_list_t *errors) {
|
||||||
// Early out. If we're not completing, and there's no magic in the input, we're done.
|
// Early out. If we're not completing, and there's no magic in the input, we're done.
|
||||||
if (!(flags & EXPAND_FOR_COMPLETIONS) && expand_is_clean(input)) {
|
if (!(flags & EXPAND_FOR_COMPLETIONS) && expand_is_clean(input)) {
|
||||||
append_completion(out_completions, std::move(input));
|
append_completion(out_completions, std::move(input));
|
||||||
return EXPAND_OK;
|
return EXPAND_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expander_t expand(vars, flags, errors);
|
||||||
|
|
||||||
// Our expansion stages.
|
// Our expansion stages.
|
||||||
const expand_stage_t stages[] = {expand_stage_cmdsubst, expand_stage_variables,
|
const stage_t stages[] = {&expander_t::stage_cmdsubst, &expander_t::stage_variables,
|
||||||
expand_stage_braces, expand_stage_home_and_self,
|
&expander_t::stage_braces, &expander_t::stage_home_and_self,
|
||||||
expand_stage_wildcards};
|
&expander_t::stage_wildcards};
|
||||||
|
|
||||||
// Load up our single initial completion.
|
// Load up our single initial completion.
|
||||||
std::vector<completion_t> completions, output_storage;
|
std::vector<completion_t> completions, output_storage;
|
||||||
append_completion(&completions, input);
|
append_completion(&completions, input);
|
||||||
|
|
||||||
expand_error_t total_result = EXPAND_OK;
|
expand_error_t total_result = EXPAND_OK;
|
||||||
for (size_t stage_idx = 0;
|
for (stage_t stage : stages) {
|
||||||
total_result != EXPAND_ERROR && stage_idx < sizeof stages / sizeof *stages; stage_idx++) {
|
for (completion_t &comp : completions) {
|
||||||
for (size_t i = 0; total_result != EXPAND_ERROR && i < completions.size(); i++) {
|
|
||||||
wcstring &next = completions.at(i).completion;
|
|
||||||
expand_error_t this_result =
|
expand_error_t this_result =
|
||||||
stages[stage_idx](std::move(next), &output_storage, flags, vars, errors);
|
(expand.*stage)(std::move(comp.completion), &output_storage);
|
||||||
// If this_result was no match, but total_result is that we have a match, then don't
|
// If this_result was no match, but total_result is that we have a match, then don't
|
||||||
// change it.
|
// change it.
|
||||||
if (!(this_result == EXPAND_WILDCARD_NO_MATCH &&
|
if (!(this_result == EXPAND_WILDCARD_NO_MATCH &&
|
||||||
total_result == EXPAND_WILDCARD_MATCH)) {
|
total_result == EXPAND_WILDCARD_MATCH)) {
|
||||||
total_result = this_result;
|
total_result = this_result;
|
||||||
}
|
}
|
||||||
|
if (total_result == EXPAND_ERROR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output becomes our next stage's input.
|
// Output becomes our next stage's input.
|
||||||
completions.swap(output_storage);
|
completions.swap(output_storage);
|
||||||
output_storage.clear();
|
output_storage.clear();
|
||||||
|
if (total_result == EXPAND_ERROR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_result != EXPAND_ERROR) {
|
if (total_result != EXPAND_ERROR) {
|
||||||
|
@ -1083,6 +1100,13 @@ expand_error_t expand_string(wcstring input, std::vector<completion_t> *out_comp
|
||||||
}
|
}
|
||||||
return total_result;
|
return total_result;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
expand_error_t expand_string(wcstring input, std::vector<completion_t> *out_completions,
|
||||||
|
expand_flags_t flags, const environment_t &vars,
|
||||||
|
parse_error_list_t *errors) {
|
||||||
|
return expander_t::expand_string(std::move(input), out_completions, flags, vars, errors);
|
||||||
|
}
|
||||||
|
|
||||||
bool expand_one(wcstring &string, expand_flags_t flags, const environment_t &vars,
|
bool expand_one(wcstring &string, expand_flags_t flags, const environment_t &vars,
|
||||||
parse_error_list_t *errors) {
|
parse_error_list_t *errors) {
|
||||||
|
|
Loading…
Reference in a new issue