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,
unsigned from_line) {
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());
}
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.
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_;
while (++index < max_index) {
while ((index += increment) != invalid_index) {
history_item_t item = history_->item_at_index(index);
// 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) {
history_search_t searcher = history_search_t(hist, search_string, search_type,
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())) {
break;
}

View file

@ -129,6 +129,8 @@ using history_item_list_t = std::deque<history_item_t>;
struct history_impl_t;
enum class history_search_direction_t { forward, backward };
class history_t : noncopyable_t, nonmovable_t {
friend class history_tests_t;
struct impl_wrapper_t;
@ -269,8 +271,8 @@ class history_search_t {
/// Gets the original search term.
const wcstring &original_term() const { return orig_term_; }
/// Finds the previous search result (backwards in time). Returns true if one was found.
bool go_backwards();
// Finds the next search result. Returns true if one was found.
bool go_to_next_match(history_search_direction_t direction);
/// Returns the current search result item. asserts if there is no current item.
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.
#define KILL_PREPEND 1
enum class history_search_direction_t { forward, backward };
enum class jump_direction_t { forward, backward };
enum class jump_precision_t { till, to };
@ -445,7 +443,7 @@ class reader_history_search_t {
}
// 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()) {
match_index_++;
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;
history_search_t search{history, search_string, history_search_type_t::contains,
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();
completions.push_back(completion_t{
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.
history_search_t searcher(history.get(), search_string, history_search_type_t::prefix,
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();
// Skip items with newlines because they make terrible autosuggestions.