mirror of
https://github.com/tstack/lnav.git
synced 2024-10-26 13:16:11 +03:00
[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:
This commit is contained in:
parent
95fe6f0d73
commit
02bfd5846b
4
NEWS
4
NEWS
@ -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':
|
||||
|
50
src/lnav.cc
50
src/lnav.cc
@ -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:
|
||||
|
42
src/lnav.hh
42
src/lnav.hh
@ -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…
Reference in New Issue
Block a user