mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-01-20 03:42:44 +08:00
Allow specifying a limit on number of expansion in operation_context
If the user types something like `/**`, prior to this change we would attempt to expand it in the background for both highlighting and autosuggestions. This could thrash your disk and also consume a lot of memory. Add a a field to operation_context_t to allow specifying a limit, and add a "default background" limit of 512 items.
This commit is contained in:
parent
0f2d73e4a3
commit
a8080e8e6f
|
@ -451,7 +451,7 @@ class completer_t {
|
|||
|
||||
public:
|
||||
completer_t(const operation_context_t &ctx, completion_request_flags_t f)
|
||||
: ctx(ctx), flags(f) {}
|
||||
: ctx(ctx), flags(f), completions(ctx.expansion_limit) {}
|
||||
|
||||
void perform_for_commandline(wcstring cmdline);
|
||||
|
||||
|
|
|
@ -124,14 +124,11 @@ using completion_list_t = std::vector<completion_t>;
|
|||
/// some conveniences.
|
||||
class completion_receiver_t {
|
||||
public:
|
||||
/// The default maximum number of items that something may expand to.
|
||||
static constexpr size_t k_default_expansion_limit = 512 * 1024;
|
||||
|
||||
/// Construct as empty, with a limit.
|
||||
explicit completion_receiver_t(size_t limit = k_default_expansion_limit) : limit_(limit) {}
|
||||
explicit completion_receiver_t(size_t limit) : limit_(limit) {}
|
||||
|
||||
/// Acquire an existing list, with a limit.
|
||||
explicit completion_receiver_t(completion_list_t &&v, size_t limit = k_default_expansion_limit)
|
||||
explicit completion_receiver_t(completion_list_t &&v, size_t limit)
|
||||
: completions_(std::move(v)), limit_(limit) {}
|
||||
|
||||
/// Add a completion.
|
||||
|
|
|
@ -1146,7 +1146,7 @@ expand_result_t expander_t::expand_string(wcstring input, completion_receiver_t
|
|||
expand_result_t expand_string(wcstring input, completion_list_t *out_completions,
|
||||
expand_flags_t flags, const operation_context_t &ctx,
|
||||
parse_error_list_t *errors) {
|
||||
completion_receiver_t recv(std::move(*out_completions));
|
||||
completion_receiver_t recv(std::move(*out_completions), ctx.expansion_limit);
|
||||
auto res = expand_string(std::move(input), &recv, flags, ctx, errors);
|
||||
*out_completions = recv.take();
|
||||
return res;
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
bool no_cancel() { return false; }
|
||||
|
||||
operation_context_t::operation_context_t(std::shared_ptr<parser_t> parser,
|
||||
const environment_t &vars, cancel_checker_t cancel_checker)
|
||||
: parser(std::move(parser)), vars(vars), cancel_checker(std::move(cancel_checker)) {}
|
||||
const environment_t &vars, cancel_checker_t cancel_checker,
|
||||
size_t expansion_limit)
|
||||
: parser(std::move(parser)),
|
||||
vars(vars),
|
||||
expansion_limit(expansion_limit),
|
||||
cancel_checker(std::move(cancel_checker)) {}
|
||||
|
||||
operation_context_t operation_context_t::empty() {
|
||||
static const null_environment_t nullenv{};
|
||||
|
|
|
@ -12,14 +12,17 @@ class job_group_t;
|
|||
/// A common helper which always returns false.
|
||||
bool no_cancel();
|
||||
|
||||
/// Default limits for expansion.
|
||||
enum expansion_limit_t : size_t {
|
||||
/// The default maximum number of items from expansion.
|
||||
kExpansionLimitDefault = 512 * 1024,
|
||||
|
||||
/// A smaller limit for background operations like syntax highlighting.
|
||||
kExpansionLimitBackground = 512,
|
||||
};
|
||||
|
||||
/// A operation_context_t is a simple property bag which wraps up data needed for highlighting,
|
||||
/// expansion, completion, and more.
|
||||
/// It contains the following triple:
|
||||
/// 1. A parser. This is often null. If not null, it may be used to execute fish script. If null,
|
||||
/// then this is a background operation and fish script must not be executed.
|
||||
/// 2. A variable set. This is never null. This may differ from the variables in the parser.
|
||||
/// 3. A cancellation checker. This is a function which you may call to detect that the operation
|
||||
/// is no longer necessary and should be cancelled.
|
||||
class operation_context_t {
|
||||
public:
|
||||
// The parser, if this is a foreground operation. If this is a background operation, this may be
|
||||
|
@ -30,6 +33,9 @@ class operation_context_t {
|
|||
// context itself.
|
||||
const environment_t &vars;
|
||||
|
||||
// The limit in the number of expansions which should be produced.
|
||||
const size_t expansion_limit;
|
||||
|
||||
/// The job group of the parental job.
|
||||
/// This is used only when expanding command substitutions. If this is set, any jobs created by
|
||||
/// the command substitions should use this tree.
|
||||
|
@ -48,9 +54,10 @@ class operation_context_t {
|
|||
// cancels.
|
||||
static operation_context_t globals();
|
||||
|
||||
/// Construct from the full triple of a parser, vars, and cancel checker.
|
||||
/// Construct from a full set of properties.
|
||||
operation_context_t(std::shared_ptr<parser_t> parser, const environment_t &vars,
|
||||
cancel_checker_t cancel_checker);
|
||||
cancel_checker_t cancel_checker,
|
||||
size_t expansion_limit = kExpansionLimitDefault);
|
||||
|
||||
/// Construct from vars alone.
|
||||
explicit operation_context_t(const environment_t &vars)
|
||||
|
|
|
@ -138,7 +138,7 @@ static operation_context_t get_bg_context(const std::shared_ptr<environment_t> &
|
|||
// Cancel if the generation count changed.
|
||||
return generation_count != read_generation_count();
|
||||
};
|
||||
return operation_context_t{nullptr, *env, std::move(cancel_checker)};
|
||||
return operation_context_t{nullptr, *env, std::move(cancel_checker), kExpansionLimitBackground};
|
||||
}
|
||||
|
||||
/// We try to ensure that syntax highlighting completes appropriately before executing what the user
|
||||
|
|
Loading…
Reference in New Issue
Block a user