mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-16 06:54:03 +00:00
Put lots of things in anonymous namespaces
This is an attempt to help prevent ODR violations by making stuff local to a file, instead of emitting weak symbols.
This commit is contained in:
parent
accba09709
commit
89c02cfe81
10 changed files with 100 additions and 91 deletions
|
@ -16,6 +16,7 @@
|
||||||
static const int kAutoloadStalenessInterval = 15;
|
static const int kAutoloadStalenessInterval = 15;
|
||||||
|
|
||||||
/// Represents a file that we might want to autoload.
|
/// Represents a file that we might want to autoload.
|
||||||
|
namespace {
|
||||||
struct autoloadable_file_t {
|
struct autoloadable_file_t {
|
||||||
/// The path to the file.
|
/// The path to the file.
|
||||||
wcstring path;
|
wcstring path;
|
||||||
|
@ -23,6 +24,7 @@ struct autoloadable_file_t {
|
||||||
/// The metadata for the file.
|
/// The metadata for the file.
|
||||||
file_id_t file_id;
|
file_id_t file_id;
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/// Class representing a cache of files that may be autoloaded.
|
/// Class representing a cache of files that may be autoloaded.
|
||||||
/// This is responsible for performing cached accesses to a set of paths.
|
/// This is responsible for performing cached accesses to a set of paths.
|
||||||
|
|
|
@ -31,6 +31,7 @@ static const wcstring var_name_prefix = L"_flag_";
|
||||||
|
|
||||||
#define BUILTIN_ERR_INVALID_OPT_SPEC _(L"%ls: Invalid option spec '%ls' at char '%lc'\n")
|
#define BUILTIN_ERR_INVALID_OPT_SPEC _(L"%ls: Invalid option spec '%ls' at char '%lc'\n")
|
||||||
|
|
||||||
|
namespace {
|
||||||
struct option_spec_t {
|
struct option_spec_t {
|
||||||
wchar_t short_flag;
|
wchar_t short_flag;
|
||||||
wcstring long_flag;
|
wcstring long_flag;
|
||||||
|
@ -58,6 +59,7 @@ struct argparse_cmd_opts_t {
|
||||||
std::unordered_map<wcstring, wchar_t> long_to_short_flag;
|
std::unordered_map<wcstring, wchar_t> long_to_short_flag;
|
||||||
std::vector<std::vector<wchar_t>> exclusive_flag_sets;
|
std::vector<std::vector<wchar_t>> exclusive_flag_sets;
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static const wchar_t *const short_options = L"+:hn:six:N:X:";
|
static const wchar_t *const short_options = L"+:hn:six:N:X:";
|
||||||
static const struct woption long_options[] = {
|
static const struct woption long_options[] = {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "wgetopt.h"
|
#include "wgetopt.h"
|
||||||
#include "wutil.h" // IWYU pragma: keep
|
#include "wutil.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
namespace {
|
||||||
struct function_cmd_opts_t {
|
struct function_cmd_opts_t {
|
||||||
bool print_help = false;
|
bool print_help = false;
|
||||||
bool shadow_scope = true;
|
bool shadow_scope = true;
|
||||||
|
@ -35,6 +36,7 @@ struct function_cmd_opts_t {
|
||||||
wcstring_list_t inherit_vars;
|
wcstring_list_t inherit_vars;
|
||||||
wcstring_list_t wrap_targets;
|
wcstring_list_t wrap_targets;
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// This command is atypical in using the "-" (RETURN_IN_ORDER) option for flag parsing.
|
// This command is atypical in using the "-" (RETURN_IN_ORDER) option for flag parsing.
|
||||||
// This is needed due to the semantics of the -a/--argument-names flag.
|
// This is needed due to the semantics of the -a/--argument-names flag.
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
|
|
||||||
class parser_t;
|
class parser_t;
|
||||||
|
|
||||||
|
namespace {
|
||||||
struct builtin_printf_state_t {
|
struct builtin_printf_state_t {
|
||||||
// Out and err streams. Note this is a captured reference!
|
// Out and err streams. Note this is a captured reference!
|
||||||
io_streams_t &streams;
|
io_streams_t &streams;
|
||||||
|
@ -100,9 +101,9 @@ struct builtin_printf_state_t {
|
||||||
void print_esc_char(wchar_t c);
|
void print_esc_char(wchar_t c);
|
||||||
|
|
||||||
void append_output(wchar_t c);
|
void append_output(wchar_t c);
|
||||||
void append_output(const wchar_t *c);
|
|
||||||
void append_format_output(const wchar_t *fmt, ...);
|
void append_format_output(const wchar_t *fmt, ...);
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static bool is_octal_digit(wchar_t c) { return iswdigit(c) && c < L'8'; }
|
static bool is_octal_digit(wchar_t c) { return iswdigit(c) && c < L'8'; }
|
||||||
|
|
||||||
|
@ -237,13 +238,6 @@ void builtin_printf_state_t::append_output(wchar_t c) {
|
||||||
streams.out.push_back(c);
|
streams.out.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void builtin_printf_state_t::append_output(const wchar_t *c) {
|
|
||||||
// Don't output if we're done.
|
|
||||||
if (early_exit) return;
|
|
||||||
|
|
||||||
streams.out.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...) {
|
void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...) {
|
||||||
// Don't output if we're done.
|
// Don't output if we're done.
|
||||||
if (early_exit) return;
|
if (early_exit) return;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "wgetopt.h"
|
#include "wgetopt.h"
|
||||||
#include "wutil.h" // IWYU pragma: keep
|
#include "wutil.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
namespace {
|
||||||
struct read_cmd_opts_t {
|
struct read_cmd_opts_t {
|
||||||
bool print_help = false;
|
bool print_help = false;
|
||||||
int place = ENV_USER;
|
int place = ENV_USER;
|
||||||
|
@ -56,6 +57,7 @@ struct read_cmd_opts_t {
|
||||||
int nchars = 0;
|
int nchars = 0;
|
||||||
bool one_line = false;
|
bool one_line = false;
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static const wchar_t *const short_options = L":ac:d:fghiLln:p:sStuxzP:UR:L";
|
static const wchar_t *const short_options = L":ac:d:fghiLln:p:sStuxzP:UR:L";
|
||||||
static const struct woption long_options[] = {{L"array", no_argument, nullptr, 'a'},
|
static const struct woption long_options[] = {{L"array", no_argument, nullptr, 'a'},
|
||||||
|
|
|
@ -295,6 +295,7 @@ static int env_set_reporting_errors(const wchar_t *cmd, const wcstring &key, int
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
/// A helper type returned by split_var_and_indexes.
|
/// A helper type returned by split_var_and_indexes.
|
||||||
struct split_var_t {
|
struct split_var_t {
|
||||||
wcstring varname; // name of the variable
|
wcstring varname; // name of the variable
|
||||||
|
@ -304,6 +305,7 @@ struct split_var_t {
|
||||||
/// \return the number of elements in our variable, or 0 if missing.
|
/// \return the number of elements in our variable, or 0 if missing.
|
||||||
long varsize() const { return var ? static_cast<long>(var->as_list().size()) : 0L; }
|
long varsize() const { return var ? static_cast<long>(var->as_list().size()) : 0L; }
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/// Extract indexes from an argument of the form `var_name[index1 index2...]`.
|
/// Extract indexes from an argument of the form `var_name[index1 index2...]`.
|
||||||
/// The argument \p arg is split into a variable name and list of indexes, which is returned by
|
/// The argument \p arg is split into a variable name and list of indexes, which is returned by
|
||||||
|
|
|
@ -95,6 +95,7 @@ static maybe_t<job_control_t> job_control_str_to_mode(const wchar_t *mode, const
|
||||||
return none();
|
return none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
struct status_cmd_opts_t {
|
struct status_cmd_opts_t {
|
||||||
int level{1};
|
int level{1};
|
||||||
maybe_t<job_control_t> new_job_control_mode{};
|
maybe_t<job_control_t> new_job_control_mode{};
|
||||||
|
@ -102,6 +103,7 @@ struct status_cmd_opts_t {
|
||||||
status_cmd_t status_cmd{STATUS_UNDEF};
|
status_cmd_t status_cmd{STATUS_UNDEF};
|
||||||
bool print_help{false};
|
bool print_help{false};
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/// Note: Do not add new flags that represent subcommands. We're encouraging people to switch to
|
/// Note: Do not add new flags that represent subcommands. We're encouraging people to switch to
|
||||||
/// the non-flag subcommand form. While these flags are deprecated they must be supported at
|
/// the non-flag subcommand form. While these flags are deprecated they must be supported at
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
// This should be about the size of a line.
|
// This should be about the size of a line.
|
||||||
#define STRING_CHUNK_SIZE 128
|
#define STRING_CHUNK_SIZE 128
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
static void string_error(io_streams_t &streams, const wchar_t *fmt, ...) {
|
static void string_error(io_streams_t &streams, const wchar_t *fmt, ...) {
|
||||||
streams.err.append(L"string ");
|
streams.err.append(L"string ");
|
||||||
va_list va;
|
va_list va;
|
||||||
|
@ -66,7 +68,6 @@ static const wchar_t *string_get_arg_argv(int *argidx, const wchar_t *const *arg
|
||||||
}
|
}
|
||||||
|
|
||||||
// A helper type for extracting arguments from either argv or stdin.
|
// A helper type for extracting arguments from either argv or stdin.
|
||||||
namespace {
|
|
||||||
class arg_iterator_t {
|
class arg_iterator_t {
|
||||||
// The list of arguments passed to the string builtin.
|
// The list of arguments passed to the string builtin.
|
||||||
const wchar_t *const *argv_;
|
const wchar_t *const *argv_;
|
||||||
|
@ -132,7 +133,6 @@ class arg_iterator_t {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// This is used by the string subcommands to communicate with the option parser which flags are
|
// This is used by the string subcommands to communicate with the option parser which flags are
|
||||||
// valid and get the result of parsing the command for flags.
|
// valid and get the result of parsing the command for flags.
|
||||||
|
@ -808,6 +808,7 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, cons
|
||||||
return nnonempty > 0 ? STATUS_CMD_OK : STATUS_CMD_ERROR;
|
return nnonempty > 0 ? STATUS_CMD_OK : STATUS_CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
class string_matcher_t {
|
class string_matcher_t {
|
||||||
protected:
|
protected:
|
||||||
const options_t opts;
|
const options_t opts;
|
||||||
|
@ -1210,6 +1211,7 @@ class pcre2_matcher_t final : public string_matcher_t {
|
||||||
|
|
||||||
bool is_valid() const override { return regex.is_valid(); }
|
bool is_valid() const override { return regex.is_valid(); }
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static int string_match(parser_t &parser, io_streams_t &streams, int argc, const wchar_t **argv) {
|
static int string_match(parser_t &parser, io_streams_t &streams, int argc, const wchar_t **argv) {
|
||||||
const wchar_t *cmd = argv[0];
|
const wchar_t *cmd = argv[0];
|
||||||
|
@ -1881,6 +1883,7 @@ static constexpr const struct string_subcommand {
|
||||||
{L"upper", &string_upper},
|
{L"upper", &string_upper},
|
||||||
};
|
};
|
||||||
ASSERT_SORTED_BY_NAME(string_subcommands);
|
ASSERT_SORTED_BY_NAME(string_subcommands);
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/// The string builtin, for manipulating strings.
|
/// The string builtin, for manipulating strings.
|
||||||
maybe_t<int> builtin_string(parser_t &parser, io_streams_t &streams, const wchar_t **argv) {
|
maybe_t<int> builtin_string(parser_t &parser, io_streams_t &streams, const wchar_t **argv) {
|
||||||
|
|
|
@ -242,7 +242,7 @@ bool is_windows_subsystem_for_linux() {
|
||||||
/// alignment must be a power of 2 and in range [1, 64].
|
/// alignment must be a power of 2 and in range [1, 64].
|
||||||
/// This is intended to return the end point of the "unaligned prefix" of a vectorized loop.
|
/// This is intended to return the end point of the "unaligned prefix" of a vectorized loop.
|
||||||
template <size_t Align>
|
template <size_t Align>
|
||||||
inline const char *align_start(const char *start, size_t len) {
|
static inline const char *align_start(const char *start, size_t len) {
|
||||||
static_assert(Align >= 1 && Align <= 64, "Alignment must be in range [1, 64]");
|
static_assert(Align >= 1 && Align <= 64, "Alignment must be in range [1, 64]");
|
||||||
static_assert((Align & (Align - 1)) == 0, "Alignment must be power of 2");
|
static_assert((Align & (Align - 1)) == 0, "Alignment must be power of 2");
|
||||||
uintptr_t startu = reinterpret_cast<uintptr_t>(start);
|
uintptr_t startu = reinterpret_cast<uintptr_t>(start);
|
||||||
|
@ -262,7 +262,7 @@ inline const char *align_start(const char *start, size_t len) {
|
||||||
/// If there is no such pointer, return \p start.
|
/// If there is no such pointer, return \p start.
|
||||||
/// This is intended to be the start point of the "unaligned suffix" of a vectorized loop.
|
/// This is intended to be the start point of the "unaligned suffix" of a vectorized loop.
|
||||||
template <size_t Align>
|
template <size_t Align>
|
||||||
inline const char *align_end(const char *start, size_t len) {
|
static inline const char *align_end(const char *start, size_t len) {
|
||||||
static_assert(Align >= 1 && Align <= 64, "Alignment must be in range [1, 64]");
|
static_assert(Align >= 1 && Align <= 64, "Alignment must be in range [1, 64]");
|
||||||
static_assert((Align & (Align - 1)) == 0, "Alignment must be power of 2");
|
static_assert((Align & (Align - 1)) == 0, "Alignment must be power of 2");
|
||||||
// How much do we have to subtract to align it? Its value, mod Align.
|
// How much do we have to subtract to align it? Its value, mod Align.
|
||||||
|
@ -617,7 +617,7 @@ static unsigned long long absolute_value(long long x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
void format_safe_impl(CharT *buff, size_t size, unsigned long long val) {
|
static void format_safe_impl(CharT *buff, size_t size, unsigned long long val) {
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
buff[idx++] = '0';
|
buff[idx++] = '0';
|
||||||
|
|
156
src/complete.cpp
156
src/complete.cpp
|
@ -88,7 +88,7 @@ static const wcstring &C_(const wcstring &s) { return s; }
|
||||||
/// If option is non-empty, it specifies a switch for the command. If \c comp is also not empty, it
|
/// If option is non-empty, it specifies a switch for the command. If \c comp is also not empty, it
|
||||||
/// contains a list of non-switch arguments that may only follow directly after the specified
|
/// contains a list of non-switch arguments that may only follow directly after the specified
|
||||||
/// switch.
|
/// switch.
|
||||||
using complete_entry_opt_t = struct complete_entry_opt {
|
struct complete_entry_opt_t {
|
||||||
// Text of the option (like 'foo').
|
// Text of the option (like 'foo').
|
||||||
wcstring option;
|
wcstring option;
|
||||||
// Type of the option: args-oly, short, single_long, or double_long.
|
// Type of the option: args-oly, short, single_long, or double_long.
|
||||||
|
@ -139,16 +139,32 @@ class completion_entry_t {
|
||||||
const unsigned int order;
|
const unsigned int order;
|
||||||
|
|
||||||
/// Getters for option list.
|
/// Getters for option list.
|
||||||
const option_list_t &get_options() const;
|
const option_list_t &get_options() const { return options; }
|
||||||
|
|
||||||
/// Adds or removes an option.
|
/// Adds or removes an option.
|
||||||
void add_option(const complete_entry_opt_t &opt);
|
void add_option(const complete_entry_opt_t &opt) { options.push_front(opt); }
|
||||||
bool remove_option(const wcstring &option, complete_option_type_t type);
|
bool remove_option(const wcstring &option, complete_option_type_t type);
|
||||||
|
|
||||||
completion_entry_t(wcstring c, bool type)
|
completion_entry_t(wcstring c, bool type)
|
||||||
: cmd(std::move(c)), cmd_is_path(type), order(++k_complete_order) {}
|
: cmd(std::move(c)), cmd_is_path(type), order(++k_complete_order) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Remove all completion options in the specified entry that match the specified short / long
|
||||||
|
/// option strings. Returns true if it is now empty and should be deleted, false if it's not empty.
|
||||||
|
/// Must be called while locked.
|
||||||
|
bool completion_entry_t::remove_option(const wcstring &option, complete_option_type_t type) {
|
||||||
|
auto iter = this->options.begin();
|
||||||
|
while (iter != this->options.end()) {
|
||||||
|
if (iter->option == option && iter->type == type) {
|
||||||
|
iter = this->options.erase(iter);
|
||||||
|
} else {
|
||||||
|
// Just go to the next one.
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this->options.empty();
|
||||||
|
}
|
||||||
|
|
||||||
/// Set of all completion entries.
|
/// Set of all completion entries.
|
||||||
namespace std {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
|
@ -164,6 +180,7 @@ struct equal_to<completion_entry_t> {
|
||||||
return c1.cmd == c2.cmd;
|
return c1.cmd == c2.cmd;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
using completion_entry_set_t = std::unordered_set<completion_entry_t>;
|
using completion_entry_set_t = std::unordered_set<completion_entry_t>;
|
||||||
static owning_lock<completion_entry_set_t> s_completion_set;
|
static owning_lock<completion_entry_set_t> s_completion_set;
|
||||||
|
@ -178,10 +195,6 @@ static bool compare_completions_by_order(const completion_entry_t &p1,
|
||||||
return p1.order < p2.order;
|
return p1.order < p2.order;
|
||||||
}
|
}
|
||||||
|
|
||||||
void completion_entry_t::add_option(const complete_entry_opt_t &opt) { options.push_front(opt); }
|
|
||||||
|
|
||||||
const option_list_t &completion_entry_t::get_options() const { return options; }
|
|
||||||
|
|
||||||
description_func_t const_desc(const wcstring &s) {
|
description_func_t const_desc(const wcstring &s) {
|
||||||
return [=](const wcstring &ignored) {
|
return [=](const wcstring &ignored) {
|
||||||
UNUSED(ignored);
|
UNUSED(ignored);
|
||||||
|
@ -343,6 +356,7 @@ void completions_sort_and_prioritize(completion_list_t *comps, completion_reques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
/// Class representing an attempt to compute completions.
|
/// Class representing an attempt to compute completions.
|
||||||
class completer_t {
|
class completer_t {
|
||||||
/// The operation context for this completion.
|
/// The operation context for this completion.
|
||||||
|
@ -461,12 +475,6 @@ class completer_t {
|
||||||
// Autoloader for completions.
|
// Autoloader for completions.
|
||||||
static owning_lock<autoload_t> completion_autoloader{autoload_t(L"fish_complete_path")};
|
static owning_lock<autoload_t> completion_autoloader{autoload_t(L"fish_complete_path")};
|
||||||
|
|
||||||
/// Create a new completion entry.
|
|
||||||
void append_completion(completion_list_t *completions, wcstring comp, wcstring desc,
|
|
||||||
complete_flags_t flags, string_fuzzy_match_t match) {
|
|
||||||
completions->emplace_back(std::move(comp), std::move(desc), match, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test if the specified script returns zero. The result is cached, so that if multiple completions
|
/// Test if the specified script returns zero. The result is cached, so that if multiple completions
|
||||||
/// use the same condition, it needs only be evaluated once. condition_cache_clear must be called
|
/// use the same condition, it needs only be evaluated once. condition_cache_clear must be called
|
||||||
/// after a completion run to make sure that there are no stale completions.
|
/// after a completion run to make sure that there are no stale completions.
|
||||||
|
@ -504,71 +512,6 @@ static completion_entry_t &complete_get_exact_entry(completion_entry_set_t &comp
|
||||||
return const_cast<completion_entry_t &>(*ins.first);
|
return const_cast<completion_entry_t &>(*ins.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
|
|
||||||
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) {
|
|
||||||
assert(cmd && "Null command");
|
|
||||||
// option should be empty iff the option type is arguments only.
|
|
||||||
assert(option.empty() == (option_type == option_type_args_only));
|
|
||||||
|
|
||||||
// Lock the lock that allows us to edit the completion entry list.
|
|
||||||
auto completion_set = s_completion_set.acquire();
|
|
||||||
completion_entry_t &c = complete_get_exact_entry(*completion_set, cmd, cmd_is_path);
|
|
||||||
|
|
||||||
// Create our new option.
|
|
||||||
complete_entry_opt_t opt;
|
|
||||||
opt.option = option;
|
|
||||||
opt.type = option_type;
|
|
||||||
opt.result_mode = result_mode;
|
|
||||||
|
|
||||||
if (comp) opt.comp = comp;
|
|
||||||
if (condition) opt.condition = condition;
|
|
||||||
if (desc) opt.desc = desc;
|
|
||||||
opt.flags = flags;
|
|
||||||
|
|
||||||
c.add_option(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove all completion options in the specified entry that match the specified short / long
|
|
||||||
/// option strings. Returns true if it is now empty and should be deleted, false if it's not empty.
|
|
||||||
/// Must be called while locked.
|
|
||||||
bool completion_entry_t::remove_option(const wcstring &option, complete_option_type_t type) {
|
|
||||||
auto iter = this->options.begin();
|
|
||||||
while (iter != this->options.end()) {
|
|
||||||
if (iter->option == option && iter->type == type) {
|
|
||||||
iter = this->options.erase(iter);
|
|
||||||
} else {
|
|
||||||
// Just go to the next one.
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this->options.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &option,
|
|
||||||
complete_option_type_t type) {
|
|
||||||
auto completion_set = s_completion_set.acquire();
|
|
||||||
|
|
||||||
completion_entry_t tmp_entry(cmd, cmd_is_path);
|
|
||||||
auto iter = completion_set->find(tmp_entry);
|
|
||||||
if (iter != completion_set->end()) {
|
|
||||||
// const_cast: See SET_ELEMENTS_ARE_IMMUTABLE.
|
|
||||||
auto &entry = const_cast<completion_entry_t &>(*iter);
|
|
||||||
|
|
||||||
bool delete_it = entry.remove_option(option, type);
|
|
||||||
if (delete_it) {
|
|
||||||
completion_set->erase(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void complete_remove_all(const wcstring &cmd, bool cmd_is_path) {
|
|
||||||
auto completion_set = s_completion_set.acquire();
|
|
||||||
completion_entry_t tmp_entry(cmd, cmd_is_path);
|
|
||||||
completion_set->erase(tmp_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find the full path and commandname from a command string 'str'.
|
/// Find the full path and commandname from a command string 'str'.
|
||||||
static void parse_cmd_string(const wcstring &str, wcstring *path, wcstring *cmd,
|
static void parse_cmd_string(const wcstring &str, wcstring *path, wcstring *cmd,
|
||||||
const environment_t &vars) {
|
const environment_t &vars) {
|
||||||
|
@ -1760,6 +1703,63 @@ void completer_t::perform_for_commandline(wcstring cmdline) {
|
||||||
mark_completions_duplicating_arguments(cmdline, current_token, tokens);
|
mark_completions_duplicating_arguments(cmdline, current_token, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/// Create a new completion entry.
|
||||||
|
void append_completion(completion_list_t *completions, wcstring comp, wcstring desc,
|
||||||
|
complete_flags_t flags, string_fuzzy_match_t match) {
|
||||||
|
completions->emplace_back(std::move(comp), std::move(desc), match, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
|
||||||
|
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) {
|
||||||
|
assert(cmd && "Null command");
|
||||||
|
// option should be empty iff the option type is arguments only.
|
||||||
|
assert(option.empty() == (option_type == option_type_args_only));
|
||||||
|
|
||||||
|
// Lock the lock that allows us to edit the completion entry list.
|
||||||
|
auto completion_set = s_completion_set.acquire();
|
||||||
|
completion_entry_t &c = complete_get_exact_entry(*completion_set, cmd, cmd_is_path);
|
||||||
|
|
||||||
|
// Create our new option.
|
||||||
|
complete_entry_opt_t opt;
|
||||||
|
opt.option = option;
|
||||||
|
opt.type = option_type;
|
||||||
|
opt.result_mode = result_mode;
|
||||||
|
|
||||||
|
if (comp) opt.comp = comp;
|
||||||
|
if (condition) opt.condition = condition;
|
||||||
|
if (desc) opt.desc = desc;
|
||||||
|
opt.flags = flags;
|
||||||
|
|
||||||
|
c.add_option(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &option,
|
||||||
|
complete_option_type_t type) {
|
||||||
|
auto completion_set = s_completion_set.acquire();
|
||||||
|
|
||||||
|
completion_entry_t tmp_entry(cmd, cmd_is_path);
|
||||||
|
auto iter = completion_set->find(tmp_entry);
|
||||||
|
if (iter != completion_set->end()) {
|
||||||
|
// const_cast: See SET_ELEMENTS_ARE_IMMUTABLE.
|
||||||
|
auto &entry = const_cast<completion_entry_t &>(*iter);
|
||||||
|
|
||||||
|
bool delete_it = entry.remove_option(option, type);
|
||||||
|
if (delete_it) {
|
||||||
|
completion_set->erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void complete_remove_all(const wcstring &cmd, bool cmd_is_path) {
|
||||||
|
auto completion_set = s_completion_set.acquire();
|
||||||
|
completion_entry_t tmp_entry(cmd, cmd_is_path);
|
||||||
|
completion_set->erase(tmp_entry);
|
||||||
|
}
|
||||||
|
|
||||||
completion_list_t complete(const wcstring &cmd_with_subcmds, completion_request_flags_t flags,
|
completion_list_t complete(const wcstring &cmd_with_subcmds, completion_request_flags_t flags,
|
||||||
const operation_context_t &ctx) {
|
const operation_context_t &ctx) {
|
||||||
// Determine the innermost subcommand.
|
// Determine the innermost subcommand.
|
||||||
|
|
Loading…
Reference in a new issue