mirror of
https://github.com/tstack/lnav.git
synced 2024-09-11 13:05:51 +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.
|
users.
|
||||||
* Pressing 'n'/'N' to move through the next/previous search hit will now
|
* 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
|
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:
|
Breaking Changes:
|
||||||
* The captured timestamp text in log files must fully match a known format
|
* 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.
|
e/E Move to the next/previous error.
|
||||||
w/W Move to the next/previous warning.
|
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
|
f/F Move to the next/previous file. In the log view, this
|
||||||
moves to the next line from a different file. In the
|
moves to the next line from a different file. In the
|
||||||
text view, this rotates the view to the next file.
|
text view, this rotates the view to the next file.
|
||||||
|
@ -332,21 +332,19 @@ void handle_paging_key(int ch)
|
|||||||
case 'n':
|
case 'n':
|
||||||
moveto_cluster(&bookmark_vector<vis_line_t>::next,
|
moveto_cluster(&bookmark_vector<vis_line_t>::next,
|
||||||
&textview_curses::BM_SEARCH,
|
&textview_curses::BM_SEARCH,
|
||||||
tc->get_top());
|
search_forward_from(tc));
|
||||||
lnav_data.ld_bottom_source.grep_error("");
|
lnav_data.ld_bottom_source.grep_error("");
|
||||||
lnav_data.ld_rl_view->set_alt_value(
|
lnav_data.ld_rl_view->set_alt_value(
|
||||||
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
|
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
|
||||||
"' to scroll horizontally to a search result");
|
"' to scroll horizontally to a search result");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'N':
|
case 'N':
|
||||||
moveto_cluster(&bookmark_vector<vis_line_t>::prev,
|
previous_cluster(&textview_curses::BM_SEARCH, tc);
|
||||||
&textview_curses::BM_SEARCH,
|
|
||||||
tc->get_top());
|
|
||||||
lnav_data.ld_bottom_source.grep_error("");
|
lnav_data.ld_bottom_source.grep_error("");
|
||||||
lnav_data.ld_rl_view->set_alt_value(
|
lnav_data.ld_rl_view->set_alt_value(
|
||||||
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
|
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
|
||||||
"' to scroll horizontally to a search result");
|
"' to scroll horizontally to a search result");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'y':
|
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),
|
bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
|
||||||
bookmark_type_t *bt,
|
bookmark_type_t *bt,
|
||||||
vis_line_t top)
|
vis_line_t top)
|
||||||
{
|
{
|
||||||
textview_curses *tc = lnav_data.ld_view_stack.top();
|
textview_curses *tc = lnav_data.ld_view_stack.top();
|
||||||
vis_line_t new_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;
|
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)
|
static void handle_rl_key(int ch)
|
||||||
{
|
{
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@ -1898,6 +1940,10 @@ static void looper(void)
|
|||||||
escape_index = 0;
|
escape_index = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lnav_data.ld_key_repeat_history.update(
|
||||||
|
ch, lnav_data.ld_view_stack.top()->get_top());
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case CEOF:
|
case CEOF:
|
||||||
case KEY_RESIZE:
|
case KEY_RESIZE:
|
||||||
|
42
src/lnav.hh
42
src/lnav.hh
@ -174,6 +174,40 @@ private:
|
|||||||
size_t ist_index;
|
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 {
|
struct _lnav_data {
|
||||||
std::string ld_session_id;
|
std::string ld_session_id;
|
||||||
time_t ld_session_time;
|
time_t ld_session_time;
|
||||||
@ -264,6 +298,8 @@ struct _lnav_data {
|
|||||||
std::map<std::string, std::vector<script_metadata> > ld_scripts;
|
std::map<std::string, std::vector<script_metadata> > ld_scripts;
|
||||||
|
|
||||||
int ld_fifo_counter;
|
int ld_fifo_counter;
|
||||||
|
|
||||||
|
struct key_repeat_history ld_key_repeat_history;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct _lnav_data lnav_data;
|
extern struct _lnav_data lnav_data;
|
||||||
@ -298,7 +334,9 @@ vis_line_t next_cluster(
|
|||||||
bookmark_type_t *bt,
|
bookmark_type_t *bt,
|
||||||
vis_line_t top);
|
vis_line_t top);
|
||||||
bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
|
bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
|
||||||
bookmark_type_t *bt,
|
bookmark_type_t *bt,
|
||||||
vis_line_t top);
|
vis_line_t top);
|
||||||
|
void previous_cluster(bookmark_type_t *bt, textview_curses *tc);
|
||||||
|
vis_line_t search_forward_from(textview_curses *tc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -638,7 +638,9 @@ public:
|
|||||||
if (first_hit > 0) {
|
if (first_hit > 0) {
|
||||||
--first_hit;
|
--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