Simplify wildcard_complete prototype

Rather than accepting both a 'description' and a 'description function',
accept just the description function.
This commit is contained in:
ridiculousfish 2018-10-15 22:30:13 -07:00
parent ec2659c500
commit 161196fe53
4 changed files with 39 additions and 39 deletions

View File

@ -196,6 +196,10 @@ const option_list_t &completion_entry_t::get_options() const {
return options;
}
description_func_t const_desc(const wcstring &s) {
return [=](const wcstring &ignored) { return s; };
}
/// Clear the COMPLETE_AUTO_SPACE flag, and set COMPLETE_NO_SPACE appropriately depending on the
/// suffix of the string.
static complete_flags_t resolve_auto_space(const wcstring &comp, complete_flags_t flags) {
@ -342,9 +346,8 @@ class completer_t {
bool condition_test(const wcstring &condition);
void complete_strings(const wcstring &wc_escaped, const wchar_t *desc,
wcstring (*desc_func)(const wcstring &),
std::vector<completion_t> &possible_comp, complete_flags_t flags);
void complete_strings(const wcstring &wc_escaped, const description_func_t &desc_func,
const std::vector<completion_t> &possible_comp, complete_flags_t flags);
expand_flags_t expand_flags() const {
// Never do command substitution in autosuggestions. Sadly, we also can't yet do job
@ -520,20 +523,15 @@ static void parse_cmd_string(const wcstring &str, wcstring &path, wcstring &cmd)
/// the prefix, possibly containing wildcards. The wildcard should not have
/// been unescaped, i.e. '*' should be used for any string, not the
/// ANY_STRING character.
/// @param desc
/// the default description, used for completions with no embedded
/// description. The description _may_ contain a COMPLETE_SEP character, if
/// not, one will be prefixed to it
/// @param desc_func
/// the function that generates a description for those completions witout an
/// the function that generates a description for those completions without an
/// embedded description
/// @param possible_comp
/// the list of possible completions to iterate over
/// @param flags
/// The flags
void completer_t::complete_strings(const wcstring &wc_escaped, const wchar_t *desc,
wcstring (*desc_func)(const wcstring &),
std::vector<completion_t> &possible_comp,
void completer_t::complete_strings(const wcstring &wc_escaped, const description_func_t &desc_func,
const std::vector<completion_t> &possible_comp,
complete_flags_t flags) {
wcstring tmp = wc_escaped;
if (!expand_one(tmp, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS | this->expand_flags(), NULL))
@ -546,7 +544,7 @@ void completer_t::complete_strings(const wcstring &wc_escaped, const wchar_t *de
const wchar_t *next_str = temp.empty() ? NULL : temp.c_str();
if (next_str) {
wildcard_complete(next_str, wc.c_str(), desc, desc_func, &this->completions,
wildcard_complete(next_str, wc.c_str(), desc_func, &this->completions,
this->expand_flags(), flags);
}
}
@ -683,7 +681,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
append_completion(&possible_comp, std::move(name));
}
this->complete_strings(str_cmd, 0, &complete_function_desc, possible_comp, 0);
this->complete_strings(str_cmd, complete_function_desc, possible_comp, 0);
}
possible_comp.clear();
@ -691,7 +689,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
if (use_builtin) {
// Append all matching builtins
builtin_get_names(&possible_comp);
this->complete_strings(str_cmd, 0, &builtin_get_desc, possible_comp, 0);
this->complete_strings(str_cmd, builtin_get_desc, possible_comp, 0);
}
}
}
@ -733,7 +731,7 @@ void completer_t::complete_from_args(const wcstring &str, const wcstring &args,
proc_pop_interactive();
}
this->complete_strings(escape_string(str, ESCAPE_ALL), desc.c_str(), 0, possible_comp, flags);
this->complete_strings(escape_string(str, ESCAPE_ALL), const_desc(desc), possible_comp, flags);
}
static size_t leading_dash_count(const wchar_t *str) {

View File

@ -49,6 +49,12 @@ enum {
};
typedef int complete_flags_t;
/// std::function which accepts a completion string and returns its description.
using description_func_t = std::function<wcstring(const wcstring &)>;
/// Helper to return a description_func_t for a constant string.
description_func_t const_desc(const wcstring &s);
class completion_t {
private:
// No public default constructor.

View File

@ -158,8 +158,8 @@ static enum fuzzy_match_type_t wildcard_match_internal(const wchar_t *str, const
// This does something horrible refactored from an even more horrible function.
static wcstring resolve_description(const wchar_t *full_completion, wcstring *completion,
const wchar_t *explicit_desc,
wcstring (*desc_func)(const wcstring &)) {
expand_flags_t expand_flags,
const description_func_t &desc_func) {
size_t complete_sep_loc = completion->find(PROG_COMPLETE_SEP);
if (complete_sep_loc != wcstring::npos) {
// This completion has an embedded description, do not use the generic description.
@ -167,23 +167,17 @@ static wcstring resolve_description(const wchar_t *full_completion, wcstring *co
completion->resize(complete_sep_loc);
return description;
}
const wcstring func_result = (desc_func ? desc_func(full_completion) : wcstring());
if (!func_result.empty()) {
return func_result;
}
return explicit_desc ? explicit_desc : L"";
if (expand_flags & EXPAND_NO_DESCRIPTIONS) return {};
return desc_func ? desc_func(full_completion) : wcstring{};
}
// A transient parameter pack needed by wildcard_complete.
struct wc_complete_pack_t {
const wcstring &orig; // the original string, transient
const wchar_t *desc; // literal description
wcstring (*desc_func)(const wcstring &); // function for generating descriptions
const description_func_t &desc_func; // function for generating descriptions
expand_flags_t expand_flags;
wc_complete_pack_t(const wcstring &str, const wchar_t *des, wcstring (*df)(const wcstring &),
expand_flags_t fl)
: orig(str), desc(des), desc_func(df), expand_flags(fl) {}
wc_complete_pack_t(const wcstring &str, const description_func_t &df, expand_flags_t fl)
: orig(str), desc_func(df), expand_flags(fl) {}
};
// Weirdly specific and non-reusable helper function that makes its one call site much clearer.
@ -244,7 +238,7 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc,
assert(!full_replacement || wcslen(wc) <= wcslen(str));
wcstring out_completion = full_replacement ? params.orig : str + wcslen(wc);
wcstring out_desc =
resolve_description(str, &out_completion, params.desc, params.desc_func);
resolve_description(str, &out_completion, params.expand_flags, params.desc_func);
// Note: out_completion may be empty if the completion really is empty, e.g. tab-completing
// 'foo' when a file 'foo' exists.
@ -316,12 +310,13 @@ static bool wildcard_complete_internal(const wchar_t *str, const wchar_t *wc,
DIE("unreachable code reached");
}
bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc,
wcstring (*desc_func)(const wcstring &), std::vector<completion_t> *out,
expand_flags_t expand_flags, complete_flags_t flags) {
bool wildcard_complete(const wcstring &str, const wchar_t *wc,
const std::function<wcstring(const wcstring &)> &desc_func,
std::vector<completion_t> *out, expand_flags_t expand_flags,
complete_flags_t flags) {
// Note out may be NULL.
assert(wc != NULL);
wc_complete_pack_t params(str, desc, desc_func, expand_flags);
wc_complete_pack_t params(str, desc_func, expand_flags);
return wildcard_complete_internal(str.c_str(), wc, params, flags, out, true /* first call */);
}
@ -393,7 +388,7 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc
const wchar_t *wc, expand_flags_t expand_flags,
std::vector<completion_t> *out) {
// Check if it will match before stat().
if (!wildcard_complete(filename, wc, NULL, NULL, NULL, expand_flags, 0)) {
if (!wildcard_complete(filename, wc, {}, NULL, expand_flags, 0)) {
return false;
}
@ -448,11 +443,12 @@ static bool wildcard_test_flags_then_complete(const wcstring &filepath, const wc
// Append a / if this is a directory. Note this requirement may be the only reason we have to
// call stat() in some cases.
auto desc_func = const_desc(desc);
if (is_directory) {
return wildcard_complete(filename + L'/', wc, desc.c_str(), NULL, out, expand_flags,
return wildcard_complete(filename + L'/', wc, desc_func, out, expand_flags,
COMPLETE_NO_SPACE);
}
return wildcard_complete(filename, wc, desc.c_str(), NULL, out, expand_flags, 0);
return wildcard_complete(filename, wc, desc_func, out, expand_flags, 0);
}
class wildcard_expander_t {

View File

@ -61,8 +61,8 @@ bool wildcard_has(const wcstring &, bool internal);
bool wildcard_has(const wchar_t *, bool internal);
/// Test wildcard completion.
bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc,
wcstring (*desc_func)(const wcstring &), std::vector<completion_t> *out,
expand_flags_t expand_flags, complete_flags_t flags);
bool wildcard_complete(const wcstring &str, const wchar_t *wc, const description_func_t &desc_func,
std::vector<completion_t> *out, expand_flags_t expand_flags,
complete_flags_t flags);
#endif