mirror of https://github.com/tstack/lnav.git
[cmd] next/prev-mark commands
This commit is contained in:
parent
61ece9649d
commit
033c861028
|
@ -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
2
NEWS
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
----
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
},
|
||||
"level-field": "sc_status",
|
||||
"level" : {
|
||||
"error" : "^[^123]"
|
||||
"error" : "^[^123].*"
|
||||
},
|
||||
"value" : {
|
||||
"c_ip" : {
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
37
src/lnav.cc
37
src/lnav.cc
|
@ -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: "
|
||||
|
|
|
@ -234,4 +234,8 @@ void execute_search(lnav_view_t view, const std::string ®ex);
|
|||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue