Do not compute $history in builtin set.

Most uses of set don't care about the value of $history, and it
can be expensive to compute.

See #6290
This commit is contained in:
Johannes Altmanninger 2019-11-05 16:47:01 +01:00
parent e1e82ecd40
commit 939d4674e4
3 changed files with 24 additions and 9 deletions

View file

@ -21,6 +21,7 @@
#include "env.h"
#include "expand.h"
#include "fallback.h" // IWYU pragma: keep
#include "history.h"
#include "io.h"
#include "parser.h"
#include "proc.h"
@ -463,7 +464,7 @@ static env_mode_flags_t compute_scope(set_cmd_opts_t &opts) {
}
/// Print the names of all environment variables in the scope. It will include the values unless the
/// `set --list` flag was used.
/// `set --names` flag was used.
static int builtin_set_list(const wchar_t *cmd, set_cmd_opts_t &opts, int argc, wchar_t **argv,
parser_t &parser, io_streams_t &streams) {
UNUSED(cmd);
@ -481,10 +482,17 @@ static int builtin_set_list(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
streams.out.append(e_key);
if (!names_only) {
auto var = parser.vars().get(key, compute_scope(opts));
if (!var.missing_or_empty()) {
wcstring val;
if (key == L"history") {
val = history_variable_description;
} else {
auto var = parser.vars().get(key, compute_scope(opts));
if (!var.missing_or_empty()) {
val = expand_escape_variable(*var);
}
}
if (!val.empty()) {
bool shorten = false;
wcstring val = expand_escape_variable(*var);
if (opts.shorten_ok && val.length() > 64) {
shorten = true;
val.resize(60);
@ -596,10 +604,11 @@ static int builtin_set_show(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
if (argc == 0) { // show all vars
wcstring_list_t names = parser.vars().get_names(ENV_USER);
sort(names.begin(), names.end());
for (auto it : names) {
show_scope(it.c_str(), ENV_LOCAL, streams, vars);
show_scope(it.c_str(), ENV_GLOBAL, streams, vars);
show_scope(it.c_str(), ENV_UNIVERSAL, streams, vars);
for (const auto &name : names) {
if (name == L"history") continue;
show_scope(name.c_str(), ENV_LOCAL, streams, vars);
show_scope(name.c_str(), ENV_GLOBAL, streams, vars);
show_scope(name.c_str(), ENV_UNIVERSAL, streams, vars);
streams.out.push_back(L'\n');
}
} else {

View file

@ -36,6 +36,7 @@
#include "expand.h"
#include "fallback.h" // IWYU pragma: keep
#include "function.h"
#include "history.h"
#include "iothread.h"
#include "parse_constants.h"
#include "parse_util.h"
@ -1193,7 +1194,7 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset) {
if (this->type() != COMPLETE_AUTOSUGGEST) {
// $history can be huge, don't put it in the completion description; see #6288.
if (env_name == L"history") {
desc = format_string(L"Full history of interactive commands");
desc = history_variable_description;
} else {
// Can't use this->vars here, it could be any variable.
auto var = vars.get(env_name);

View file

@ -293,4 +293,9 @@ bool all_paths_are_valid(const path_list_t &paths, const wcstring &working_direc
void start_private_mode();
/// Queries private mode status.
bool in_private_mode();
/// The description of the $history environment variable, as offered in completions and
/// the output of builtin set.
constexpr const wchar_t *history_variable_description = L"Full history of interactive commands";
#endif