mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 13:39:02 +00:00
Promote completion_mode_t to a real type
Eliminate big #defines like NO_COMMON.
This commit is contained in:
parent
d962668aa0
commit
96bc8a14ca
4 changed files with 46 additions and 43 deletions
|
@ -29,8 +29,8 @@
|
|||
/// Silly function.
|
||||
static void builtin_complete_add2(const wchar_t *cmd, bool cmd_is_path, const wchar_t *short_opt,
|
||||
const wcstring_list_t &gnu_opts, const wcstring_list_t &old_opts,
|
||||
int result_mode, const wchar_t *condition, const wchar_t *comp,
|
||||
const wchar_t *desc, int flags) {
|
||||
completion_mode_t result_mode, const wchar_t *condition,
|
||||
const wchar_t *comp, const wchar_t *desc, int flags) {
|
||||
for (const wchar_t *s = short_opt; *s; s++) {
|
||||
complete_add(cmd, cmd_is_path, wcstring{*s}, option_type_short, result_mode, condition,
|
||||
comp, desc, flags);
|
||||
|
@ -55,7 +55,7 @@ static void builtin_complete_add2(const wchar_t *cmd, bool cmd_is_path, const wc
|
|||
/// Silly function.
|
||||
static void builtin_complete_add(const wcstring_list_t &cmds, const wcstring_list_t &paths,
|
||||
const wchar_t *short_opt, wcstring_list_t &gnu_opt,
|
||||
wcstring_list_t &old_opt, int result_mode,
|
||||
wcstring_list_t &old_opt, completion_mode_t result_mode,
|
||||
const wchar_t *condition, const wchar_t *comp, const wchar_t *desc,
|
||||
int flags) {
|
||||
for (const wcstring &cmd : cmds) {
|
||||
|
@ -114,7 +114,7 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
|
||||
wchar_t *cmd = argv[0];
|
||||
int argc = builtin_count_args(argv);
|
||||
int result_mode = SHARED;
|
||||
completion_mode_t result_mode{};
|
||||
int remove = 0;
|
||||
wcstring short_opt;
|
||||
wcstring_list_t gnu_opt, old_opt;
|
||||
|
@ -152,15 +152,16 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'x': {
|
||||
result_mode |= EXCLUSIVE;
|
||||
result_mode.no_files = true;
|
||||
result_mode.requires_param = true;
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
result_mode |= NO_FILES;
|
||||
result_mode.no_files = true;
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
result_mode |= NO_COMMON;
|
||||
result_mode.requires_param = true;
|
||||
break;
|
||||
}
|
||||
case 'k': {
|
||||
|
|
|
@ -97,9 +97,8 @@ typedef struct complete_entry_opt {
|
|||
wcstring desc;
|
||||
// Condition under which to use the option.
|
||||
wcstring condition;
|
||||
// Must be one of the values SHARED, NO_FILES, NO_COMMON, EXCLUSIVE, and determines how
|
||||
// completions should be performed on the argument after the switch.
|
||||
int result_mode;
|
||||
// Determines how completions should be performed on the argument after the switch.
|
||||
completion_mode_t result_mode;
|
||||
// Completion flags.
|
||||
complete_flags_t flags;
|
||||
|
||||
|
@ -440,8 +439,9 @@ static completion_entry_t &complete_get_exact_entry(completion_entry_set_t &comp
|
|||
}
|
||||
|
||||
void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
|
||||
complete_option_type_t option_type, int result_mode, const wchar_t *condition,
|
||||
const wchar_t *comp, const wchar_t *desc, complete_flags_t flags) {
|
||||
complete_option_type_t option_type, completion_mode_t result_mode,
|
||||
const wchar_t *condition, const wchar_t *comp, const wchar_t *desc,
|
||||
complete_flags_t flags) {
|
||||
CHECK(cmd, );
|
||||
// option should be empty iff the option type is arguments only.
|
||||
assert(option.empty() == (option_type == option_type_args_only));
|
||||
|
@ -852,7 +852,7 @@ static bool short_ok(const wcstring &arg, const complete_entry_opt_t *entry,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (match == NULL || (match->result_mode & NO_COMMON)) {
|
||||
if (match == NULL || (match->result_mode.requires_param)) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
@ -946,8 +946,8 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt,
|
|||
for (const complete_entry_opt_t &o : options) {
|
||||
const wchar_t *arg = param_match2(&o, str.c_str());
|
||||
if (arg != NULL && this->condition_test(o.condition)) {
|
||||
if (o.result_mode & NO_COMMON) use_common = false;
|
||||
if (o.result_mode & NO_FILES) use_files = false;
|
||||
if (o.result_mode.requires_param) use_common = false;
|
||||
if (o.result_mode.no_files) use_files = false;
|
||||
complete_from_args(arg, o.comp, o.localized_desc(), o.flags);
|
||||
}
|
||||
}
|
||||
|
@ -962,8 +962,8 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt,
|
|||
if (o.type == option_type_single_long && param_match(&o, popt.c_str()) &&
|
||||
this->condition_test(o.condition)) {
|
||||
old_style_match = true;
|
||||
if (o.result_mode & NO_COMMON) use_common = false;
|
||||
if (o.result_mode & NO_FILES) use_files = false;
|
||||
if (o.result_mode.requires_param) use_common = false;
|
||||
if (o.result_mode.no_files) use_files = false;
|
||||
complete_from_args(str, o.comp, o.localized_desc(), o.flags);
|
||||
}
|
||||
}
|
||||
|
@ -976,12 +976,12 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt,
|
|||
// token, so that it can be differed from a regular argument.
|
||||
// Here we are testing the previous argument for a GNU-style match,
|
||||
// to see how we should complete the current argument
|
||||
if (o.type == option_type_double_long && !(o.result_mode & NO_COMMON))
|
||||
if (o.type == option_type_double_long && !o.result_mode.requires_param)
|
||||
continue;
|
||||
|
||||
if (param_match(&o, popt.c_str()) && this->condition_test(o.condition)) {
|
||||
if (o.result_mode & NO_COMMON) use_common = false;
|
||||
if (o.result_mode & NO_FILES) use_files = false;
|
||||
if (o.result_mode.requires_param) use_common = false;
|
||||
if (o.result_mode.no_files) use_files = false;
|
||||
complete_from_args(str, o.comp, o.localized_desc(), o.flags);
|
||||
}
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt,
|
|||
// If this entry is for the base command, check if any of the arguments match.
|
||||
if (!this->condition_test(o.condition)) continue;
|
||||
if (o.option.empty()) {
|
||||
use_files = use_files && ((o.result_mode & NO_FILES) == 0);
|
||||
use_files = use_files && ((o.result_mode.no_files) == 0);
|
||||
complete_from_args(str, o.comp, o.localized_desc(), o.flags);
|
||||
}
|
||||
|
||||
|
@ -1043,7 +1043,7 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt,
|
|||
}
|
||||
|
||||
has_arg = !o.comp.empty();
|
||||
req_arg = (o.result_mode & NO_COMMON);
|
||||
req_arg = o.result_mode.requires_param;
|
||||
|
||||
if (o.type == option_type_double_long && (has_arg && !req_arg)) {
|
||||
// Optional arguments to a switch can only be handled using the '=', so we add it as
|
||||
|
@ -1616,10 +1616,15 @@ wcstring complete_print() {
|
|||
for (const completion_entry_t &e : all_completions) {
|
||||
const option_list_t &options = e.get_options();
|
||||
for (const complete_entry_opt_t &o : options) {
|
||||
const wchar_t *modestr[] = {L"", L" --no-files", L" --require-parameter",
|
||||
L" --exclusive"};
|
||||
|
||||
append_format(out, L"complete%ls", modestr[o.result_mode]);
|
||||
const wchar_t *modestr = L"";
|
||||
if (o.result_mode.no_files && o.result_mode.requires_param) {
|
||||
modestr = L" --exclusive";
|
||||
} else if (o.result_mode.no_files) {
|
||||
modestr = L" --no-files";
|
||||
} else if (o.result_mode.requires_param) {
|
||||
modestr = L" --require-parameter";
|
||||
}
|
||||
append_format(out, L"complete%ls", modestr);
|
||||
|
||||
append_switch(out, e.cmd_is_path ? L"path" : L"command",
|
||||
escape_string(e.cmd, ESCAPE_ALL));
|
||||
|
|
|
@ -12,15 +12,13 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
/// Use all completions.
|
||||
#define SHARED 0
|
||||
/// Do not use file completion.
|
||||
#define NO_FILES 1
|
||||
/// Require a parameter after completion.
|
||||
#define NO_COMMON 2
|
||||
/// Only use the argument list specifies with completion after option. This is the same as (NO_FILES
|
||||
/// | NO_COMMON).
|
||||
#define EXCLUSIVE 3
|
||||
struct completion_mode_t {
|
||||
/// If set, skip file completions.
|
||||
bool no_files{false};
|
||||
|
||||
/// If set, require a parameter after completion.
|
||||
bool requires_param{false};
|
||||
};
|
||||
|
||||
/// Separator between completion and description.
|
||||
#define COMPLETE_SEP L'\004'
|
||||
|
@ -148,19 +146,16 @@ void completions_sort_and_prioritize(std::vector<completion_t> *comps,
|
|||
/// \param option The name of an option.
|
||||
/// \param option_type The type of option: can be option_type_short (-x),
|
||||
/// option_type_single_long (-foo), option_type_double_long (--bar).
|
||||
/// \param result_mode Whether to search further completions when this completion has been
|
||||
/// succesfully matched. If result_mode is SHARED, any other completions may also be used. If
|
||||
/// result_mode is NO_FILES, file completion should not be used, but other completions may be used.
|
||||
/// If result_mode is NO_COMMON, on option may follow it - only a parameter. If result_mode is
|
||||
/// EXCLUSIVE, no option may follow it, and file completion is not performed.
|
||||
/// \param result_mode Controls how to search further completions when this completion has been
|
||||
/// succesfully matched.
|
||||
/// \param comp A space separated list of completions which may contain subshells.
|
||||
/// \param desc A description of the completion.
|
||||
/// \param condition a command to be run to check it this completion should be used. If \c condition
|
||||
/// is empty, the completion is always used.
|
||||
/// \param flags A set of completion flags
|
||||
void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
|
||||
complete_option_type_t option_type, int result_mode, const wchar_t *condition,
|
||||
const wchar_t *comp, const wchar_t *desc, int flags);
|
||||
complete_option_type_t option_type, completion_mode_t result_mode,
|
||||
const wchar_t *condition, const wchar_t *comp, const wchar_t *desc, int flags);
|
||||
|
||||
/// Remove a previously defined completion.
|
||||
void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &option,
|
||||
|
|
|
@ -2579,7 +2579,9 @@ static void test_complete() {
|
|||
do_test(completions.size() == 0);
|
||||
|
||||
// Trailing spaces (#1261).
|
||||
complete_add(L"foobarbaz", false, wcstring(), option_type_args_only, NO_FILES, NULL, L"qux",
|
||||
completion_mode_t no_files{};
|
||||
no_files.no_files = true;
|
||||
complete_add(L"foobarbaz", false, wcstring(), option_type_args_only, no_files, NULL, L"qux",
|
||||
NULL, COMPLETE_AUTO_SPACE);
|
||||
completions.clear();
|
||||
complete(L"foobarbaz ", &completions, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
|
|
Loading…
Reference in a new issue