Teach history search to move forward in time

Will use this for forward incremental search.

No functional change.
This commit is contained in:
Johannes Altmanninger 2020-02-09 18:39:14 +01:00
parent dcff0a2f2b
commit 24e04daa22
4 changed files with 25 additions and 13 deletions

View File

@ -3793,7 +3793,7 @@ static void test_autosuggestion_combining() {
static void test_history_matches(history_search_t &search, const wcstring_list_t &expected, static void test_history_matches(history_search_t &search, const wcstring_list_t &expected,
unsigned from_line) { unsigned from_line) {
wcstring_list_t found; wcstring_list_t found;
while (search.go_backwards()) { while (search.go_to_next_match(history_search_direction_t::backward)) {
found.push_back(search.current_string()); found.push_back(search.current_string());
} }
do_test_from(expected == found, from_line); do_test_from(expected == found, from_line);

View File

@ -627,14 +627,24 @@ void history_impl_t::load_old_if_needed() {
} }
} }
bool history_search_t::go_backwards() { bool history_search_t::go_to_next_match(history_search_direction_t direction) {
// Backwards means increasing our index. // Backwards means increasing our index.
const auto max_index = static_cast<size_t>(-1); size_t invalid_index;
ssize_t increment;
if (current_index_ == max_index) return false; if (direction == history_search_direction_t::backward) {
invalid_index = static_cast<size_t>(-1);
increment = 1;
} else {
assert(direction == history_search_direction_t::forward);
invalid_index = 0;
increment = -1;
}
if (current_index_ == invalid_index) return false;
size_t index = current_index_; size_t index = current_index_;
while (++index < max_index) { while ((index += increment) != invalid_index) {
history_item_t item = history_->item_at_index(index); history_item_t item = history_->item_at_index(index);
// We're done if it's empty or we cancelled. // We're done if it's empty or we cancelled.
@ -1460,7 +1470,7 @@ static void do_1_history_search(history_t *hist, history_search_type_t search_ty
const cancel_checker_t &cancel_check) { const cancel_checker_t &cancel_check) {
history_search_t searcher = history_search_t(hist, search_string, search_type, history_search_t searcher = history_search_t(hist, search_string, search_type,
case_sensitive ? 0 : history_search_ignore_case); case_sensitive ? 0 : history_search_ignore_case);
while (!cancel_check() && searcher.go_backwards()) { while (!cancel_check() && searcher.go_to_next_match(history_search_direction_t::backward)) {
if (!func(searcher.current_item())) { if (!func(searcher.current_item())) {
break; break;
} }

View File

@ -129,6 +129,8 @@ using history_item_list_t = std::deque<history_item_t>;
struct history_impl_t; struct history_impl_t;
enum class history_search_direction_t { forward, backward };
class history_t : noncopyable_t, nonmovable_t { class history_t : noncopyable_t, nonmovable_t {
friend class history_tests_t; friend class history_tests_t;
struct impl_wrapper_t; struct impl_wrapper_t;
@ -269,8 +271,8 @@ class history_search_t {
/// Gets the original search term. /// Gets the original search term.
const wcstring &original_term() const { return orig_term_; } const wcstring &original_term() const { return orig_term_; }
/// Finds the previous search result (backwards in time). Returns true if one was found. // Finds the next search result. Returns true if one was found.
bool go_backwards(); bool go_to_next_match(history_search_direction_t direction);
/// Returns the current search result item. asserts if there is no current item. /// Returns the current search result item. asserts if there is no current item.
const history_item_t &current_item() const; const history_item_t &current_item() const;

View File

@ -123,8 +123,6 @@ static const size_t TAB_COMPLETE_WILDCARD_MAX_EXPANSION = 256;
/// current contents of the kill buffer. /// current contents of the kill buffer.
#define KILL_PREPEND 1 #define KILL_PREPEND 1
enum class history_search_direction_t { forward, backward };
enum class jump_direction_t { forward, backward }; enum class jump_direction_t { forward, backward };
enum class jump_precision_t { till, to }; enum class jump_precision_t { till, to };
@ -445,7 +443,7 @@ class reader_history_search_t {
} }
// Add more items from our search. // Add more items from our search.
while (search_.go_backwards()) { while (search_.go_to_next_match(history_search_direction_t::backward)) {
if (append_matches_from_search()) { if (append_matches_from_search()) {
match_index_++; match_index_++;
assert(match_index_ < matches_.size() && "Should have found more matches"); assert(match_index_ < matches_.size() && "Should have found more matches");
@ -1242,7 +1240,8 @@ static history_pager_result_t history_pager_search(const std::shared_ptr<history
completion_list_t completions; completion_list_t completions;
history_search_t search{history, search_string, history_search_type_t::contains, history_search_t search{history, search_string, history_search_type_t::contains,
smartcase_flags(search_string)}; smartcase_flags(search_string)};
while (completions.size() < page_size && search.go_backwards()) { while (completions.size() < page_size &&
search.go_to_next_match(history_search_direction_t::backward)) {
const history_item_t &item = search.current_item(); const history_item_t &item = search.current_item();
completions.push_back(completion_t{ completions.push_back(completion_t{
item.str(), L"", string_fuzzy_match_t::exact_match(), item.str(), L"", string_fuzzy_match_t::exact_match(),
@ -1841,7 +1840,8 @@ static std::function<autosuggestion_t(void)> get_autosuggestion_performer(
// Search history for a matching item. // Search history for a matching item.
history_search_t searcher(history.get(), search_string, history_search_type_t::prefix, history_search_t searcher(history.get(), search_string, history_search_type_t::prefix,
history_search_flags_t{}); history_search_flags_t{});
while (!ctx.check_cancel() && searcher.go_backwards()) { while (!ctx.check_cancel() &&
searcher.go_to_next_match(history_search_direction_t::backward)) {
const history_item_t &item = searcher.current_item(); const history_item_t &item = searcher.current_item();
// Skip items with newlines because they make terrible autosuggestions. // Skip items with newlines because they make terrible autosuggestions.