Show the first few history entries in set | grep history

As before, but do so efficiently. See #6290
This commit is contained in:
Johannes Altmanninger 2019-12-29 17:43:05 +01:00
parent d0edd984d5
commit 3d9c0d3c69
5 changed files with 29 additions and 8 deletions

View file

@ -482,8 +482,12 @@ static int builtin_set_list(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
if (!names_only) {
wcstring val;
if (key == L"history") {
val = history_variable_description;
if (opts.shorten_ok && key == L"history") {
history_t *history = &history_t::history_with_name(history_session_id(env_stack_t::principal()));
for (size_t i = 1; i < history->size() && val.size() < 64; i++) {
if (i > 1) val += L' ';
val += expand_escape_string(history->item_at_index(i).str());
}
} else {
auto var = parser.vars().get(key, compute_scope(opts));
if (!var.missing_or_empty()) {

View file

@ -1193,9 +1193,13 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset) {
wcstring desc;
if (this->wants_descriptions()) {
if (this->type() != COMPLETE_AUTOSUGGEST) {
// $history can be huge, don't put it in the completion description; see #6288.
// $history can be huge, don't put all of it in the completion description; see #6288.
if (env_name == L"history") {
desc = history_variable_description;
history_t *history = &history_t::history_with_name(history_session_id(env_stack_t::principal()));
for (size_t i = 1; i < history->size() && desc.size() < 64; i++) {
if (i > 1) desc += L' ';
desc += expand_escape_string(history->item_at_index(i).str());
}
} else {
// Can't use this->vars here, it could be any variable.
auto var = vars.get(env_name);

View file

@ -145,6 +145,19 @@ wcstring expand_escape_variable(const env_var_t &var) {
return buff;
}
wcstring expand_escape_string(const wcstring &el) {
wcstring buff;
bool prefer_quotes = el.find(L' ') != wcstring::npos;
if (prefer_quotes && is_quotable(el)) {
buff.append(L"'");
buff.append(el);
buff.append(L"'");
} else {
buff.append(escape_string(el, 1));
}
return buff;
}
/// Parse an array slicing specification Returns 0 on success. If a parse error occurs, returns the
/// index of the bad token. Note that 0 can never be a bad index because the string always starts
/// with [.

View file

@ -164,6 +164,10 @@ expand_result_t expand_to_command_and_args(const wcstring &instr, const environm
/// Suitable for pretty-printing.
wcstring expand_escape_variable(const env_var_t &var);
/// Convert a string value to a human readable form, i.e. escape things, handle arrays, etc.
/// Suitable for pretty-printing.
wcstring expand_escape_string(const wcstring &str);
/// Perform tilde expansion and nothing else on the specified string, which is modified in place.
///
/// \param input the string to tilde expand

View file

@ -294,8 +294,4 @@ 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