[cmd] next/prev-mark commands

This commit is contained in:
Timothy Stack 2015-03-29 14:50:34 -07:00
parent 61ece9649d
commit 033c861028
14 changed files with 170 additions and 19 deletions

View File

@ -6,7 +6,7 @@ before_install:
- wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz -O /tmp/automake.tar.gz
- tar -xvf /tmp/automake.tar.gz
- (cd automake-1.15 && ./configure && make && sudo make install)
script: ./autogen.sh && ./configure && make && make check
script: ./autogen.sh && ./configure && make && make check && cat test/test-suite.log
env:
global:

2
NEWS
View File

@ -12,6 +12,8 @@ lnav v0.7.3:
to its current position.
* Experimental support for linking with jemalloc.
* The plain text view now supports filtering.
* Added 'next-mark' and 'prev-mark' commands to jump to the next or
previous bookmarked line (e.g. error, warning, ...)
Fixes:
* Autotools scripts overhaul.

View File

@ -32,6 +32,10 @@ Navigation
file, or the given timestamp in the log view.
* relative-goto <line#|N%> - Move the current view up or down by the given
amount.
* next-mark error|warning|search|user|file|partition - Move to the next
bookmark of the given type in the current view.
* prev-mark error|warning|search|user|file|partition - Move to the previous
bookmark of the given type in the current view.
Time
----

View File

@ -33,6 +33,10 @@
#include "bookmarks.hh"
using namespace std;
std::vector<bookmark_type_t *> bookmark_type_t::ALL_TYPES;
template<typename LineType>
LineType bookmark_vector<LineType>::next(LineType start)
{

View File

@ -108,7 +108,51 @@ public:
* Dummy type whose instances are used to distinguish between
* bookmarks maintained by different source modules.
*/
class bookmark_type_t { };
class bookmark_type_t {
public:
typedef std::vector<bookmark_type_t *>::iterator type_iterator;
static type_iterator type_begin() {
return ALL_TYPES.begin();
};
static type_iterator type_end() {
return ALL_TYPES.end();
};
static bookmark_type_t *find_type(const std::string &name) {
type_iterator iter = find_if(type_begin(), type_end(), mark_eq(name));
bookmark_type_t *retval = NULL;
if (iter != type_end()) {
retval = (*iter);
}
return retval;
};
bookmark_type_t(const std::string &name) : bt_name(name) {
ALL_TYPES.push_back(this);
};
const std::string &get_name() const {
return this->bt_name;
};
private:
struct mark_eq {
mark_eq(const std::string &name) : me_name(name) { };
bool operator()(bookmark_type_t *bt) {
return bt->bt_name == this->me_name;
};
const std::string &me_name;
};
static std::vector<bookmark_type_t *> ALL_TYPES;
const std::string bt_name;
};
/**
* Map of bookmark types to bookmark vectors.

View File

@ -16,7 +16,7 @@
},
"level-field": "sc_status",
"level" : {
"error" : "^[^123]"
"error" : "^[^123].*"
},
"value" : {
"c_ip" : {

View File

@ -375,6 +375,14 @@ COMMANDS
relative-goto <line#|N%>
Move the current view up or down by the given amount.
next-mark error|warning|search|user|file|partition
Move to the next bookmark of the given type in the
current view.
prev-mark error|warning|search|user|file|partition
Move to the previous bookmark of the given type in the
current view.
highlight <regex> Highlight strings that match the given regular
expression.

View File

@ -141,8 +141,8 @@ static struct hist_level HIST_ZOOM_VALUES[] = {
static const int HIST_ZOOM_LEVELS = sizeof(HIST_ZOOM_VALUES) /
sizeof(struct hist_level);
static bookmark_type_t BM_EXAMPLE;
static bookmark_type_t BM_QUERY;
static bookmark_type_t BM_EXAMPLE("");
static bookmark_type_t BM_QUERY("query");
const char *lnav_view_strings[LNV__MAX + 1] = {
"log",
@ -598,6 +598,23 @@ static void add_filter_possibilities(textview_curses *tc)
}
}
static void add_mark_possibilities()
{
readline_curses *rc = lnav_data.ld_rl_view;
rc->clear_possibilities(LNM_COMMAND, "mark-type");
for (bookmark_type_t::type_iterator iter = bookmark_type_t::type_begin();
iter != bookmark_type_t::type_end();
++iter) {
bookmark_type_t *bt = (*iter);
if (bt->get_name().empty()) {
continue;
}
rc->add_possibility(LNM_COMMAND, "mark-type", bt->get_name());
}
}
bool setup_logline_table()
{
// Hidden columns don't show up in the table_info pragma.
@ -1264,17 +1281,19 @@ static vis_line_t next_cluster(
{
textview_curses *tc = lnav_data.ld_view_stack.top();
vis_bookmarks &bm = tc->get_bookmarks();
bookmark_vector<vis_line_t> &bv = bm[bt];
bool top_is_marked = binary_search(bv.begin(), bv.end(), top);
vis_line_t last_top(top);
while ((top = (bm[bt].*f)(top)) != -1) {
while ((top = (bv.*f)(top)) != -1) {
int diff = top - last_top;
if (diff > 1) {
if (!top_is_marked || diff > 1) {
return top;
}
else if (diff < -1) {
last_top = top;
while ((top = (bm[bt].*f)(top)) != -1) {
while ((top = (bv.*f)(top)) != -1) {
if (std::abs(last_top - top) > 1)
break;
last_top = top;
@ -1287,10 +1306,9 @@ static vis_line_t next_cluster(
return vis_line_t(-1);
}
static bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (
vis_line_t),
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)
{
textview_curses *tc = lnav_data.ld_view_stack.top();
vis_line_t new_top;
@ -1985,6 +2003,7 @@ static void handle_paging_key(int ch)
add_possibility(LNM_COMMAND, "filter",
lnav_data.ld_last_search[tc - lnav_data.ld_views]);
add_filter_possibilities(tc);
add_mark_possibilities();
lnav_data.ld_mode = LNM_COMMAND;
lnav_data.ld_rl_view->focus(LNM_COMMAND, ":");
lnav_data.ld_bottom_source.set_prompt("Enter an lnav command: "

View File

@ -234,4 +234,8 @@ void execute_search(lnav_view_t view, const std::string &regex);
void redo_search(lnav_view_t view_index);
bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t),
bookmark_type_t *bt,
vis_line_t top);
#endif

View File

@ -277,6 +277,37 @@ static string com_relative_goto(string cmdline, vector<string> &args)
return retval;
}
static string com_goto_mark(string cmdline, vector<string> &args)
{
string retval = "";
if (args.empty()) {
args.push_back("mark-type");
}
else {
textview_curses *tc = lnav_data.ld_view_stack.top();
string type_name = "user";
if (args.size() > 1) {
type_name = args[1];
}
bookmark_type_t *bt = bookmark_type_t::find_type(type_name);
if (bt == NULL) {
retval = "error: unknown bookmark type";
}
else {
moveto_cluster(args[0] == "next-mark" ?
&bookmark_vector<vis_line_t>::next :
&bookmark_vector<vis_line_t>::prev,
bt,
tc->get_top());
}
}
return retval;
}
static bool csv_needs_quoting(const string &str)
{
return (str.find_first_of(",\"") != string::npos);
@ -1658,6 +1689,8 @@ void init_lnav_commands(readline_context::command_map_t &cmd_map)
cmd_map["current-time"] = com_current_time;
cmd_map["goto"] = com_goto;
cmd_map["relative-goto"] = com_relative_goto;
cmd_map["next-mark"] = com_goto_mark;
cmd_map["prev-mark"] = com_goto_mark;
cmd_map["graph"] = com_graph;
cmd_map["help"] = com_help;
cmd_map["highlight"] = com_highlight;

View File

@ -38,9 +38,9 @@
using namespace std;
bookmark_type_t logfile_sub_source::BM_ERRORS;
bookmark_type_t logfile_sub_source::BM_WARNINGS;
bookmark_type_t logfile_sub_source::BM_FILES;
bookmark_type_t logfile_sub_source::BM_ERRORS("error");
bookmark_type_t logfile_sub_source::BM_WARNINGS("warning");
bookmark_type_t logfile_sub_source::BM_FILES("");
logfile_sub_source::logfile_sub_source()
: lss_flags(0),

View File

@ -53,9 +53,9 @@ void text_filter::add_line(
this->lf_lines_for_message += 1;
}
bookmark_type_t textview_curses::BM_USER;
bookmark_type_t textview_curses::BM_PARTITION;
bookmark_type_t textview_curses::BM_SEARCH;
bookmark_type_t textview_curses::BM_USER("user");
bookmark_type_t textview_curses::BM_PARTITION("partition");
bookmark_type_t textview_curses::BM_SEARCH("search");
string_attr_type textview_curses::SA_BODY;

View File

@ -127,7 +127,7 @@ int main(int argc, char *argv[])
frb[0] = "up";
frb[1] = "down";
static bookmark_type_t SEQUENCE;
static bookmark_type_t SEQUENCE("sequence");
sequence_matcher sm(fc);
vis_bookmarks bm;

View File

@ -54,6 +54,39 @@ check_output "relative-goto -1 is not working" <<EOF
EOF
run_test ${lnav_test} -n \
-c ":goto 0" \
-c ":next-mark error" \
${test_dir}/logfile_access_log.0
check_output "next-mark error is not working" <<EOF
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7"
EOF
run_test ${lnav_test} -n \
-c ":goto -1" \
-c ":prev-mark error" \
${test_dir}/logfile_access_log.0
check_output "prev-mark error is not working" <<EOF
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7"
EOF
run_test ${lnav_test} -n \
-c ":goto 0" \
-c ":next-mark foobar" \
${test_dir}/logfile_access_log.0
check_error_output "goto invalid is not working" <<EOF
error: unknown bookmark type
EOF
check_output "invalid mark-type is working" <<EOF
EOF
run_test ${lnav_test} -n \
-c ":filter-in vmk" \
${test_dir}/logfile_access_log.0