diff --git a/src/input_handler.cc b/src/input_handler.cc index 9fab9ccdb..6cf175c23 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -752,7 +752,7 @@ public: m_empty_text{std::move(emptystr)}, m_line_editor{context().faces()}, m_flags(flags), m_history{RegisterManager::instance()[history_register]}, - m_current_history{m_history.get(context()).size()}, + m_current_history{-1}, m_auto_complete{context().options()["autocomplete"].get() & AutoComplete::Prompt}, m_idle_timer{TimePoint::max(), context().flags() & Context::Flags::Draft ? Timer::Callback{} : [this](Timer&) { @@ -861,48 +861,28 @@ public: } else if (key == Key::Up or key == ctrl('p')) { - if (m_current_history != 0) + auto history = m_history.get(context()); + m_current_history = std::min(static_cast(history.size()) - 1, m_current_history); + if (m_current_history == -1) + m_prefix = line; + auto next = find_if(history.subrange(m_current_history + 1), [this](StringView s) { return prefix_match(s, m_prefix); }); + if (next != history.end()) { - auto history = m_history.get(context()); - // The history register might have been mutated in the mean time - m_current_history = std::min(history.size(), m_current_history); - if (m_current_history == history.size()) - m_prefix = line; - auto index = m_current_history; - // search for the previous history entry matching typed prefix - do - { - --index; - if (prefix_match(history[index], m_prefix)) - { - m_current_history = index; - m_line_editor.reset(history[index], m_empty_text); - break; - } - } while (index != 0); - - clear_completions(); - m_refresh_completion_pending = true; + m_current_history = next - history.begin(); + m_line_editor.reset(*next, m_empty_text); } + clear_completions(); + m_refresh_completion_pending = true; } else if (key == Key::Down or key == ctrl('n')) // next { auto history = m_history.get(context()); - // The history register might have been mutated in the mean time - m_current_history = std::min(history.size(), m_current_history); - if (m_current_history < history.size()) + m_current_history = std::min(static_cast(history.size()) - 1, m_current_history); + if (m_current_history >= 0) { - // search for the next history entry matching typed prefix - ++m_current_history; - while (m_current_history != history.size() and - not prefix_match(history[m_current_history], m_prefix)) - ++m_current_history; - - if (m_current_history != history.size()) - m_line_editor.reset(history[m_current_history], m_empty_text); - else - m_line_editor.reset(m_prefix, m_empty_text); - + auto next = find_if(history.subrange(0, m_current_history) | reverse(), [this](StringView s) { return prefix_match(s, m_prefix); }); + m_current_history = history.rend() - next - 1; + m_line_editor.reset(next != history.rend() ? *next : m_prefix, m_empty_text); clear_completions(); m_refresh_completion_pending = true; } @@ -1162,7 +1142,7 @@ private: bool m_line_changed = false; PromptFlags m_flags; Register& m_history; - size_t m_current_history; + int m_current_history; bool m_auto_complete; bool m_refresh_completion_pending = true; Timer m_idle_timer; diff --git a/src/normal.cc b/src/normal.cc index c891d5418..17fd48331 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -941,7 +941,7 @@ template void search_next(Context& context, NormalParams params) { const char reg = to_lower(params.reg ? params.reg : '/'); - StringView str = RegisterManager::instance()[reg].get(context).back(); + StringView str = RegisterManager::instance()[reg].get(context).front(); if (not str.empty()) { Regex regex{str, direction_flags(regex_mode)}; diff --git a/src/register_manager.cc b/src/register_manager.cc index 6dc92006c..f5a6269bc 100644 --- a/src/register_manager.cc +++ b/src/register_manager.cc @@ -40,16 +40,14 @@ void HistoryRegister::set(Context& context, ConstArrayView values, bool return; } - for (auto& entry : values) + for (auto&& entry : values | reverse()) { - m_content.erase(std::remove(m_content.begin(), m_content.end(), entry), - m_content.end()); - m_content.push_back(entry); + m_content.erase(std::remove(m_content.begin(), m_content.end(), entry), m_content.end()); + m_content.insert(m_content.begin(), entry); } - const size_t current_size = m_content.size(); - if (current_size > size_limit) - m_content.erase(m_content.begin(), m_content.begin() + (current_size - size_limit)); + if (m_content.size() > size_limit) + m_content.erase(m_content.end() - (m_content.size() - size_limit), m_content.end()); if (not m_disable_modified_hook) context.hooks().run_hook(Hook::RegisterModified, m_name, context); @@ -57,7 +55,7 @@ void HistoryRegister::set(Context& context, ConstArrayView values, bool const String& HistoryRegister::get_main(const Context&, size_t) { - return m_content.empty() ? String::ms_empty : m_content.back(); + return m_content.empty() ? String::ms_empty : m_content.front(); } static const HashMap reg_names = {