From 911a32a992fb96a23e66eba478c00655703cfed0 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 22 Aug 2016 20:31:08 +0100 Subject: [PATCH] Only drop blank prefixed history entries in command/shell prompts For regex prompts we actually want to save them, as a leading space is significant Fixes #767 --- src/commands.cc | 7 ++++--- src/input_handler.cc | 19 +++++++++++-------- src/input_handler.hh | 11 ++++++++++- src/normal.cc | 19 +++++++++++++------ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 1c1ce310..9bcd9c3a 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1627,11 +1627,12 @@ const CommandDesc prompt_cmd = { context, flags, prefix, cursor_pos); }; - const bool password = (bool)parser.get_switch("password"); + const auto flags = parser.get_switch("password") ? + PromptFlags::Password : PromptFlags::None; context.input_handler().prompt( parser[0], initstr.str(), get_face("Prompt"), - password, std::move(completer), + flags, std::move(completer), [=](StringView str, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) @@ -1642,7 +1643,7 @@ const CommandDesc prompt_cmd = { CommandManager::instance().execute(command, context, shell_context); - if (password) + if (flags & PromptFlags::Password) { const String& str = RegisterManager::instance()[reg].values(context)[0]; memset(const_cast(str).data(), 0, (int)str.length()); diff --git a/src/input_handler.cc b/src/input_handler.cc index d6850a51..1fb68f86 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -621,10 +621,10 @@ class Prompt : public InputMode { public: Prompt(InputHandler& input_handler, StringView prompt, - String initstr, Face face, bool password, + String initstr, Face face, PromptFlags flags, Completer completer, PromptCallback callback) : InputMode(input_handler), m_prompt(prompt.str()), m_prompt_face(face), - m_password(password), m_completer(completer), m_callback(callback), + m_flags(flags), m_completer(completer), m_callback(callback), m_autoshowcompl{context().options()["autoshowcompl"].get()} { m_history_it = ms_history[m_prompt].end(); @@ -853,7 +853,7 @@ private: auto width = context().client().dimensions().column - m_prompt.char_length(); DisplayLine display_line; - if (not m_password) + if (not (m_flags & PromptFlags::Password)) display_line = m_line_editor.build_display_line(width); display_line.insert(display_line.begin(), { m_prompt, m_prompt_face }); context().print_status(display_line); @@ -872,15 +872,18 @@ private: String m_prefix; LineEditor m_line_editor; bool m_autoshowcompl; - bool m_password; + PromptFlags m_flags; + bool m_history_drop_blank_prefix; using History = Vector; static UnorderedMap ms_history; History::iterator m_history_it; - static void history_push(History& history, StringView entry) + void history_push(History& history, StringView entry) { - if(entry.empty() or is_horizontal_blank(entry[0_byte])) + if(entry.empty() or + (m_flags & PromptFlags::DropHistoryEntriesWithBlankPrefix and + is_horizontal_blank(entry[0_byte]))) return; history.erase(std::remove(history.begin(), history.end(), entry), @@ -1293,11 +1296,11 @@ void InputHandler::repeat_last_insert() } void InputHandler::prompt(StringView prompt, String initstr, - Face prompt_face, bool password, + Face prompt_face, PromptFlags flags, Completer completer, PromptCallback callback) { push_mode(new InputModes::Prompt(*this, prompt, initstr, prompt_face, - password, completer, callback)); + flags, completer, callback)); } void InputHandler::set_prompt_face(Face prompt_face) diff --git a/src/input_handler.hh b/src/input_handler.hh index c4fcb1a3..a26bbbd4 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -29,6 +29,15 @@ enum class PromptEvent Validate }; using PromptCallback = std::function; +enum class PromptFlags +{ + None = 0, + Password = 1 << 0, + DropHistoryEntriesWithBlankPrefix = 1 << 1 +}; +template<> struct WithBitOps : std::true_type {}; + + using KeyCallback = std::function; class InputMode; @@ -53,7 +62,7 @@ public: // returns to normal mode after validation if callback does // not change the mode itself void prompt(StringView prompt, String initstr, - Face prompt_face, bool password, + Face prompt_face, PromptFlags flags, Completer completer, PromptCallback callback); void set_prompt_face(Face prompt_face); diff --git a/src/normal.cc b/src/normal.cc index 0600144e..49aab27f 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -338,7 +338,7 @@ void command(Context& context, NormalParams params) CommandManager::instance().clear_last_complete_command(); context.input_handler().prompt( - ":", "", get_face("Prompt"), false, + ":", "", get_face("Prompt"), PromptFlags::DropHistoryEntriesWithBlankPrefix, [](const Context& context, CompletionFlags flags, StringView cmd_line, ByteCount pos) { return CommandManager::instance().complete(context, flags, cmd_line, pos); @@ -375,7 +375,9 @@ template void pipe(Context& context, NormalParams) { const char* prompt = replace ? "pipe:" : "pipe-to:"; - context.input_handler().prompt(prompt, "", get_face("Prompt"), false, shell_complete, + context.input_handler().prompt( + prompt, "", get_face("Prompt"), + PromptFlags::DropHistoryEntriesWithBlankPrefix, shell_complete, [](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) @@ -429,7 +431,9 @@ template void insert_output(Context& context, NormalParams) { const char* prompt = mode == InsertMode::Insert ? "insert-output:" : "append-output:"; - context.input_handler().prompt(prompt, "", get_face("Prompt"), false, shell_complete, + context.input_handler().prompt( + prompt, "", get_face("Prompt"), + PromptFlags::DropHistoryEntriesWithBlankPrefix, shell_complete, [](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) @@ -590,7 +594,8 @@ void regex_prompt(Context& context, const String prompt, T func) { CharCoord position = context.has_window() ? context.window().position() : CharCoord{}; SelectionList selections = context.selections(); - context.input_handler().prompt(prompt, "", get_face("Prompt"), false, complete_nothing, + context.input_handler().prompt( + prompt, "", get_face("Prompt"), PromptFlags::None, complete_nothing, [=](StringView str, PromptEvent event, Context& context) mutable { try { @@ -817,7 +822,8 @@ void keep(Context& context, NormalParams) void keep_pipe(Context& context, NormalParams) { context.input_handler().prompt( - "keep pipe:", "", get_face("Prompt"), false, shell_complete, + "keep pipe:", "", get_face("Prompt"), + PromptFlags::DropHistoryEntriesWithBlankPrefix, shell_complete, [](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) return; @@ -959,7 +965,8 @@ void select_object(Context& context, NormalParams params) AutoInfo::Command, context); context.input_handler().prompt( - "object desc:", "", get_face("Prompt"), false, complete_nothing, + "object desc:", "", get_face("Prompt"), + PromptFlags::None, complete_nothing, [level,info](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Change) hide_auto_info_ifn(context, info);