[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:
pull/398/head
Timothy Stack 8 years ago
parent 95fe6f0d73
commit 02bfd5846b

@ -21,7 +21,9 @@ lnav v0.8.2:
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.
make scanning through clusters of hits much faster. Repeatedly
pressing these keys within a short time will also accelerate scanning
by moving the view at least a full page at a time.
Breaking Changes:
* The captured timestamp text in log files must fully match a known format

@ -196,7 +196,10 @@ Spatial Navigation
e/E Move to the next/previous error.
w/W Move to the next/previous warning.
n/N Move to the next/previous search hit.
n/N Move to the next/previous search hit. When pressed
repeatedly within a short time, the view will move at
least a full page at a time instead of moving to the
next hit.
f/F Move to the next/previous file. In the log view, this
moves to the next line from a different file. In the
text view, this rotates the view to the next file.

@ -332,21 +332,19 @@ void handle_paging_key(int ch)
case 'n':
moveto_cluster(&bookmark_vector<vis_line_t>::next,
&textview_curses::BM_SEARCH,
tc->get_top());
search_forward_from(tc));
lnav_data.ld_bottom_source.grep_error("");
lnav_data.ld_rl_view->set_alt_value(
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
"' to scroll horizontally to a search result");
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
"' to scroll horizontally to a search result");
break;
case 'N':
moveto_cluster(&bookmark_vector<vis_line_t>::prev,
&textview_curses::BM_SEARCH,
tc->get_top());
previous_cluster(&textview_curses::BM_SEARCH, tc);
lnav_data.ld_bottom_source.grep_error("");
lnav_data.ld_rl_view->set_alt_value(
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
"' to scroll horizontally to a search result");
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
"' to scroll horizontally to a search result");
break;
case 'y':

@ -892,8 +892,8 @@ vis_line_t next_cluster(
}
bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
bookmark_type_t *bt,
vis_line_t top)
bookmark_type_t *bt,
vis_line_t top)
{
textview_curses *tc = lnav_data.ld_view_stack.top();
vis_line_t new_top;
@ -909,6 +909,48 @@ bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
return false;
}
void previous_cluster(bookmark_type_t *bt, textview_curses *tc)
{
key_repeat_history &krh = lnav_data.ld_key_repeat_history;
vis_line_t height, new_top, initial_top = tc->get_top();
unsigned long width;
new_top = next_cluster(&bookmark_vector<vis_line_t>::prev,
bt,
initial_top);
tc->get_dimensions(height, width);
if (krh.krh_count > 1 &&
initial_top < (krh.krh_start_line - (1.5 * height)) &&
(initial_top - new_top) < height) {
bookmark_vector<vis_line_t> &bv = tc->get_bookmarks()[bt];
new_top = bv.next(std::max(vis_line_t(0), initial_top - height));
}
if (new_top != -1) {
tc->set_top(new_top);
}
else {
alerter::singleton().chime();
}
}
vis_line_t search_forward_from(textview_curses *tc)
{
vis_line_t height, retval = tc->get_top();
key_repeat_history &krh = lnav_data.ld_key_repeat_history;
unsigned long width;
tc->get_dimensions(height, width);
if (krh.krh_count > 1 &&
retval > (krh.krh_start_line + (1.5 * height))) {
retval += vis_line_t(0.90 * height);
}
return retval;
}
static void handle_rl_key(int ch)
{
switch (ch) {
@ -1898,6 +1940,10 @@ static void looper(void)
escape_index = 0;
continue;
}
lnav_data.ld_key_repeat_history.update(
ch, lnav_data.ld_view_stack.top()->get_top());
switch (ch) {
case CEOF:
case KEY_RESIZE:

@ -174,6 +174,40 @@ private:
size_t ist_index;
};
struct key_repeat_history {
key_repeat_history()
: krh_key(0),
krh_count(0) {
this->krh_last_press_time.tv_sec = 0;
this->krh_last_press_time.tv_usec = 0;
}
int krh_key;
int krh_count;
vis_line_t krh_start_line;
struct timeval krh_last_press_time;
void update(int ch, vis_line_t top) {
struct timeval now, diff;
gettimeofday(&now, NULL);
timersub(&now, &this->krh_last_press_time, &diff);
if (diff.tv_sec >= 1 || diff.tv_usec > (750 * 1000)) {
this->krh_key = 0;
this->krh_count = 0;
}
this->krh_last_press_time = now;
if (this->krh_key == ch) {
this->krh_count += 1;
} else {
this->krh_key = ch;
this->krh_count = 1;
this->krh_start_line = top;
}
};
};
struct _lnav_data {
std::string ld_session_id;
time_t ld_session_time;
@ -264,6 +298,8 @@ struct _lnav_data {
std::map<std::string, std::vector<script_metadata> > ld_scripts;
int ld_fifo_counter;
struct key_repeat_history ld_key_repeat_history;
};
extern struct _lnav_data lnav_data;
@ -298,7 +334,9 @@ vis_line_t next_cluster(
bookmark_type_t *bt,
vis_line_t top);
bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
bookmark_type_t *bt,
vis_line_t top);
bookmark_type_t *bt,
vis_line_t top);
void previous_cluster(bookmark_type_t *bt, textview_curses *tc);
vis_line_t search_forward_from(textview_curses *tc);
#endif

@ -638,7 +638,9 @@ public:
if (first_hit > 0) {
--first_hit;
}
this->set_top(first_hit);
if (first_hit > this->get_top()) {
this->set_top(first_hit);
}
}
}
}

Loading…
Cancel
Save