From 95fe6f0d734143182bf2fb54cf1cf9250dfcacf5 Mon Sep 17 00:00:00 2001 From: Timothy Stack Date: Thu, 24 Nov 2016 23:27:54 -0800 Subject: [PATCH] [hotkey] the n/N keys will now move to the next cluster of search hits, up to a screenful Defect Number: Reviewed By: Testing Done: --- NEWS | 3 +++ src/hotkeys.cc | 8 ++++++-- src/lnav.cc | 30 ++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index a34d2edb..e6f9659d 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,9 @@ lnav v0.8.2: , the view will move to the matched line. The previous behavior was to stay on the current line, which tended to be a surprise to new users. + * Pressing 'n'/'N' to move through the next/previous search hit will now + skip adjacent lines, up to the vertical size of the view. This should + make scanning through clusters of hits much faster. Breaking Changes: * The captured timestamp text in log files must fully match a known format diff --git a/src/hotkeys.cc b/src/hotkeys.cc index 5d0a35a0..d2e173fd 100644 --- a/src/hotkeys.cc +++ b/src/hotkeys.cc @@ -330,7 +330,9 @@ void handle_paging_key(int ch) break; case 'n': - tc->set_top(bm[&textview_curses::BM_SEARCH].next(tc->get_top())); + moveto_cluster(&bookmark_vector::next, + &textview_curses::BM_SEARCH, + tc->get_top()); lnav_data.ld_bottom_source.grep_error(""); lnav_data.ld_rl_view->set_alt_value( "Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<") @@ -338,7 +340,9 @@ void handle_paging_key(int ch) break; case 'N': - tc->set_top(bm[&textview_curses::BM_SEARCH].prev(tc->get_top())); + moveto_cluster(&bookmark_vector::prev, + &textview_curses::BM_SEARCH, + tc->get_top()); lnav_data.ld_bottom_source.grep_error(""); lnav_data.ld_rl_view->set_alt_value( "Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<") diff --git a/src/lnav.cc b/src/lnav.cc index 2cea752e..429718d8 100644 --- a/src/lnav.cc +++ b/src/lnav.cc @@ -852,30 +852,40 @@ bool ensure_view(textview_curses *expected_tc) vis_line_t next_cluster( vis_line_t(bookmark_vector::*f) (vis_line_t), bookmark_type_t *bt, - vis_line_t top) + const vis_line_t top) { textview_curses *tc = lnav_data.ld_view_stack.top(); vis_bookmarks &bm = tc->get_bookmarks(); bookmark_vector &bv = bm[bt]; bool top_is_marked = binary_search(bv.begin(), bv.end(), top); - vis_line_t last_top(top); + vis_line_t last_top(top), new_top(top), tc_height; + unsigned long tc_width; + int hit_count = 0; - while ((top = (bv.*f)(top)) != -1) { - int diff = top - last_top; + tc->get_dimensions(tc_height, tc_width); + while ((new_top = (bv.*f)(new_top)) != -1) { + int diff = new_top - last_top; + + hit_count += 1; if (!top_is_marked || diff > 1) { - return top; + return new_top; + } + else if (hit_count > 1 && std::abs(new_top - top) >= tc_height) { + return vis_line_t(new_top - diff); } else if (diff < -1) { - last_top = top; - while ((top = (bv.*f)(top)) != -1) { - if (std::abs(last_top - top) > 1) + last_top = new_top; + while ((new_top = (bv.*f)(new_top)) != -1) { + if ((std::abs(last_top - new_top) > 1) || + (hit_count > 1 && (std::abs(top - new_top) >= tc_height))) { break; - last_top = top; + } + last_top = new_top; } return last_top; } - last_top = top; + last_top = new_top; } return vis_line_t(-1);