mirror of
https://github.com/tstack/lnav
synced 2024-11-01 21:40:34 +00:00
[highlight] choose highlight color based on the regex
Defect Number: Reviewed By: Testing Done:
This commit is contained in:
parent
06ca3c5288
commit
b392886f0c
9
NEWS
9
NEWS
@ -3,10 +3,17 @@ lnav v0.8.2:
|
||||
Features:
|
||||
* The timestamp format for JSON log files can be specified with the
|
||||
"timestamp-format" option in the "line-format" array.
|
||||
* Added "min-width", "max-width", ""align", and "overflow" options to the
|
||||
* Added "min-width", "max-width", "align", and "overflow" options to the
|
||||
"line-format" in format definitions for JSON log files. These options
|
||||
give you more control over how the displayed line looks.
|
||||
|
||||
Interface Changes:
|
||||
* The color used for text colored via ":highlight" is now based on the
|
||||
the regex instead of randomly picked so that colors are consistent
|
||||
across invocations.
|
||||
* The "graph" view has been removed since it's functionality has been
|
||||
obsoleted by other features, like ":create-search-table".
|
||||
|
||||
lnav v0.8.1:
|
||||
Features:
|
||||
* Added a spectrogram command and view that displays the values of a
|
||||
|
@ -93,7 +93,6 @@ set(diag_STAT_SRCS
|
||||
field_overlay_source.hh
|
||||
filter_observer.hh
|
||||
format-text-files.hh
|
||||
grapher.hh
|
||||
grep_highlighter.hh
|
||||
help.hh
|
||||
hotkeys.hh
|
||||
|
@ -130,7 +130,6 @@ noinst_HEADERS = \
|
||||
field_overlay_source.hh \
|
||||
filter_observer.hh \
|
||||
format-text-files.hh \
|
||||
grapher.hh \
|
||||
grep_highlighter.hh \
|
||||
grep_proc.hh \
|
||||
help.hh \
|
||||
|
139
src/grapher.hh
139
src/grapher.hh
@ -1,139 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2007-2012, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @file grapher.hh
|
||||
*/
|
||||
|
||||
#ifndef _grapher_hh
|
||||
#define _grapher_hh
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "grep_proc.hh"
|
||||
#include "hist_source.hh"
|
||||
#include "textview_curses.hh"
|
||||
|
||||
class grapher
|
||||
: public grep_proc_sink,
|
||||
public hist_source {
|
||||
public:
|
||||
|
||||
grapher()
|
||||
: gr_highlighter(NULL),
|
||||
gr_x(0)
|
||||
{
|
||||
this->set_label_source(&this->gr_label_source);
|
||||
};
|
||||
|
||||
grep_line_t at(int row) { return this->gr_lines[row]; };
|
||||
|
||||
void set_highlighter(textview_curses::highlighter *hl)
|
||||
{
|
||||
this->gr_highlighter = hl;
|
||||
};
|
||||
|
||||
void grep_begin(grep_proc &gp)
|
||||
{
|
||||
this->clear();
|
||||
this->hs_type2role.clear();
|
||||
this->gr_lines.clear();
|
||||
this->gr_x = -1;
|
||||
this->gr_next_field = bucket_type_t(0);
|
||||
};
|
||||
|
||||
void grep_match(grep_proc &gp, grep_line_t line, int start, int end) { };
|
||||
|
||||
void grep_capture(grep_proc &gp,
|
||||
grep_line_t line,
|
||||
int start,
|
||||
int end,
|
||||
char *capture)
|
||||
{
|
||||
float amount = 1.0;
|
||||
|
||||
if (this->gr_lines.empty() || this->gr_lines.back() != line) {
|
||||
this->gr_next_field = bucket_type_t(0);
|
||||
this->gr_x += 1;
|
||||
this->gr_lines.push_back(line);
|
||||
}
|
||||
|
||||
if (this->gr_highlighter != NULL) {
|
||||
if (this->hs_type2role.find(this->gr_next_field) ==
|
||||
this->hs_type2role.end()) {
|
||||
this->hs_type2role[this->gr_next_field] =
|
||||
this->gr_highlighter->get_role(this->gr_next_field);
|
||||
}
|
||||
}
|
||||
if (capture != 0) {
|
||||
sscanf(capture, "%f", &amount);
|
||||
}
|
||||
this->add_value(this->gr_x, this->gr_next_field, amount);
|
||||
|
||||
++this->gr_next_field;
|
||||
};
|
||||
|
||||
void grep_end_batch(grep_proc &gp) { };
|
||||
void grep_end(grep_proc &gp) { };
|
||||
|
||||
private:
|
||||
|
||||
class label_source
|
||||
: public hist_source::label_source {
|
||||
public:
|
||||
label_source() { };
|
||||
|
||||
void hist_label_for_bucket(int bucket_start_value,
|
||||
const hist_source::bucket_t &bucket,
|
||||
std::string &label_out)
|
||||
{
|
||||
hist_source::bucket_t::const_iterator iter;
|
||||
|
||||
for (iter = bucket.begin(); iter != bucket.end(); iter++) {
|
||||
char buffer[64];
|
||||
|
||||
if (iter->second != 0.0) {
|
||||
snprintf(buffer, sizeof(buffer), " %10.2f", iter->second);
|
||||
}
|
||||
else {
|
||||
snprintf(buffer, sizeof(buffer), " %10s", "-");
|
||||
}
|
||||
label_out += std::string(buffer);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
label_source gr_label_source;
|
||||
textview_curses::highlighter *gr_highlighter;
|
||||
std::vector<grep_line_t> gr_lines;
|
||||
int gr_x;
|
||||
bucket_type_t gr_next_field;
|
||||
};
|
||||
#endif
|
@ -1100,10 +1100,6 @@ void handle_paging_key(int ch)
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_CTRL_G:
|
||||
toggle_view(&lnav_data.ld_views[LNV_GRAPH]);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
toggle_view(&lnav_data.ld_views[LNV_HELP]);
|
||||
break;
|
||||
|
116
src/lnav.cc
116
src/lnav.cc
@ -141,6 +141,8 @@ static multimap<lnav_flags_t, string> DEFAULT_FILES;
|
||||
|
||||
struct _lnav_data lnav_data;
|
||||
|
||||
static void setup_highlights(textview_curses::highlight_map_t &hm);
|
||||
|
||||
const int ZOOM_LEVELS[] = {
|
||||
1,
|
||||
30,
|
||||
@ -163,7 +165,6 @@ const char *lnav_view_strings[LNV__MAX + 1] = {
|
||||
"text",
|
||||
"help",
|
||||
"histogram",
|
||||
"graph",
|
||||
"db",
|
||||
"example",
|
||||
"schema",
|
||||
@ -193,7 +194,6 @@ static const char *view_titles[LNV__MAX] = {
|
||||
"TEXT",
|
||||
"HELP",
|
||||
"HIST",
|
||||
"GRAPH",
|
||||
"DB",
|
||||
"EXAMPLE",
|
||||
"SCHEMA",
|
||||
@ -974,8 +974,9 @@ void execute_search(lnav_view_t view, const std::string ®ex_orig)
|
||||
}
|
||||
|
||||
if (code != NULL) {
|
||||
textview_curses::highlighter hl(
|
||||
code, false, view_colors::VCR_SEARCH);
|
||||
textview_curses::highlighter hl(code);
|
||||
|
||||
hl.with_role(view_colors::VCR_SEARCH);
|
||||
|
||||
if (!quoted) {
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
@ -1697,11 +1698,6 @@ static void looper(void)
|
||||
|
||||
lnav_data.ld_rl_view = &rlc;
|
||||
|
||||
lnav_data.ld_rl_view->add_possibility(
|
||||
LNM_COMMAND, "graph", "\\d+(?:\\.\\d+)?");
|
||||
lnav_data.ld_rl_view->add_possibility(
|
||||
LNM_COMMAND, "graph", "([:= \\t]\\d+(?:\\.\\d+)?)");
|
||||
|
||||
lnav_data.ld_rl_view->add_possibility(
|
||||
LNM_COMMAND, "viewname", lnav_view_strings);
|
||||
|
||||
@ -1736,6 +1732,13 @@ static void looper(void)
|
||||
|
||||
view_colors::singleton().init();
|
||||
|
||||
{
|
||||
setup_highlights(lnav_data.ld_views[LNV_LOG].get_highlights());
|
||||
setup_highlights(lnav_data.ld_views[LNV_TEXT].get_highlights());
|
||||
setup_highlights(lnav_data.ld_views[LNV_SCHEMA].get_highlights());
|
||||
setup_highlights(lnav_data.ld_views[LNV_PRETTY].get_highlights());
|
||||
}
|
||||
|
||||
rlc.set_window(lnav_data.ld_window);
|
||||
rlc.set_y(-1);
|
||||
rlc.set_change_action(readline_curses::action(rl_change));
|
||||
@ -1921,10 +1924,6 @@ static void looper(void)
|
||||
|
||||
if (gc.get() != NULL) {
|
||||
gc->get_grep_proc()->check_poll_set(pollfds);
|
||||
if (lpc == LG_GRAPH) {
|
||||
lnav_data.ld_views[LNV_GRAPH].reload_data();
|
||||
/* XXX */
|
||||
}
|
||||
}
|
||||
}
|
||||
for (lpc = 0; lpc < LNV__MAX; lpc++) {
|
||||
@ -2059,6 +2058,11 @@ static void looper(void)
|
||||
}
|
||||
}
|
||||
|
||||
static textview_curses::highlighter static_highlighter(const string ®ex) {
|
||||
return textview_curses::highlighter(xpcre_compile(regex.c_str()))
|
||||
.with_attrs(view_colors::singleton().attrs_for_ident(regex));
|
||||
}
|
||||
|
||||
static void setup_highlights(textview_curses::highlight_map_t &hm)
|
||||
{
|
||||
hm["$kw"] = textview_curses::highlighter(xpcre_compile(
|
||||
@ -2160,51 +2164,45 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
|
||||
"\\bwhere |"
|
||||
"\\bwhile\\b|"
|
||||
"\\b[a-zA-Z][\\w]+_t\\b"
|
||||
")", PCRE_CASELESS),
|
||||
false, view_colors::VCR_KEYWORD);
|
||||
hm["$srcfile"] = textview_curses::
|
||||
highlighter(xpcre_compile(
|
||||
"[\\w\\-_]+\\."
|
||||
"(?:java|a|o|so|c|cc|cpp|cxx|h|hh|hpp|hxx|py|pyc|rb):"
|
||||
"\\d+"));
|
||||
hm["$xml"] = textview_curses::
|
||||
highlighter(xpcre_compile("<(/?[^ >=]+)[^>]*>"));
|
||||
hm["$stringd"] = textview_curses::
|
||||
highlighter(xpcre_compile("\"(?:\\\\.|[^\"])*\""),
|
||||
false, view_colors::VCR_STRING);
|
||||
hm["$strings"] = textview_curses::
|
||||
highlighter(xpcre_compile(
|
||||
"(?<![A-WY-Za-qstv-z])\'(?:\\\\.|[^'])*\'"),
|
||||
false, view_colors::VCR_STRING);
|
||||
hm["$stringb"] = textview_curses::
|
||||
highlighter(xpcre_compile("`(?:\\\\.|[^`])*`"),
|
||||
false, view_colors::VCR_STRING);
|
||||
hm["$diffp"] = textview_curses::
|
||||
highlighter(xpcre_compile(
|
||||
"^\\+.*"), false,
|
||||
view_colors::VCR_DIFF_ADD);
|
||||
hm["$diffm"] = textview_curses::
|
||||
highlighter(xpcre_compile(
|
||||
"^(?:--- .*|-$|-[^-].*)"), false,
|
||||
view_colors::VCR_DIFF_DELETE);
|
||||
hm["$diffs"] = textview_curses::
|
||||
highlighter(xpcre_compile(
|
||||
"^\\@@ .*"), false,
|
||||
view_colors::VCR_DIFF_SECTION);
|
||||
hm["$ip"] = textview_curses::
|
||||
highlighter(xpcre_compile("\\d+\\.\\d+\\.\\d+\\.\\d+"));
|
||||
")", PCRE_CASELESS))
|
||||
.with_role(view_colors::VCR_KEYWORD);
|
||||
hm["$srcfile"] = static_highlighter(
|
||||
"[\\w\\-_]+\\."
|
||||
"(?:java|a|o|so|c|cc|cpp|cxx|h|hh|hpp|hxx|py|pyc|rb):"
|
||||
"\\d+");
|
||||
hm["$xml"] = static_highlighter("<(/?[^ >=]+)[^>]*>");
|
||||
hm["$stringd"] = textview_curses::highlighter(xpcre_compile(
|
||||
"\"(?:\\\\.|[^\"])*\""))
|
||||
.with_role(view_colors::VCR_STRING);
|
||||
hm["$strings"] = textview_curses::highlighter(xpcre_compile(
|
||||
"(?<![A-WY-Za-qstv-z])\'(?:\\\\.|[^'])*\'"))
|
||||
.with_role(view_colors::VCR_STRING);
|
||||
hm["$stringb"] = textview_curses::highlighter(xpcre_compile(
|
||||
"`(?:\\\\.|[^`])*`"))
|
||||
.with_role(view_colors::VCR_STRING);
|
||||
hm["$diffp"] = textview_curses::highlighter(xpcre_compile(
|
||||
"^\\+.*"))
|
||||
.with_role(view_colors::VCR_DIFF_ADD);
|
||||
hm["$diffm"] = textview_curses::highlighter(xpcre_compile(
|
||||
"^(?:--- .*|-$|-[^-].*)"))
|
||||
.with_role(view_colors::VCR_DIFF_DELETE);
|
||||
hm["$diffs"] = textview_curses::highlighter(xpcre_compile(
|
||||
"^\\@@ .*"))
|
||||
.with_role(view_colors::VCR_DIFF_SECTION);
|
||||
hm["$ip"] = static_highlighter("\\d+\\.\\d+\\.\\d+\\.\\d+");
|
||||
hm["$comment"] = textview_curses::highlighter(xpcre_compile(
|
||||
"(?<=[\\s;])//.*|/\\*.*\\*/|\\(\\*.*\\*\\)|^#.*|\\s+#.*|dnl.*"), false, view_colors::VCR_COMMENT);
|
||||
hm["$javadoc"] = textview_curses::highlighter(xpcre_compile(
|
||||
"@(?:author|deprecated|exception|file|param|return|see|since|throws|todo|version)"));
|
||||
"(?<=[\\s;])//.*|/\\*.*\\*/|\\(\\*.*\\*\\)|^#.*|\\s+#.*|dnl.*"))
|
||||
.with_role(view_colors::VCR_COMMENT);
|
||||
hm["$javadoc"] = static_highlighter(
|
||||
"@(?:author|deprecated|exception|file|param|return|see|since|throws|todo|version)");
|
||||
hm["$var"] = textview_curses::highlighter(xpcre_compile(
|
||||
"(?:"
|
||||
"(?:var\\s+)?([\\-\\w]+)\\s*=|"
|
||||
"(?<!\\$)\\$(\\w+)|"
|
||||
"(?<!\\$)\\$\\((\\w+)\\)|"
|
||||
"(?<!\\$)\\$\\{(\\w+)\\}"
|
||||
")"),
|
||||
false, view_colors::VCR_VARIABLE);
|
||||
")"))
|
||||
.with_role(view_colors::VCR_VARIABLE);
|
||||
}
|
||||
|
||||
static void print_errors(vector<string> error_list)
|
||||
@ -2580,8 +2578,6 @@ int main(int argc, char *argv[])
|
||||
.set_sub_source(&lnav_data.ld_text_source);
|
||||
lnav_data.ld_views[LNV_HISTOGRAM]
|
||||
.set_sub_source(&lnav_data.ld_hist_source2);
|
||||
lnav_data.ld_views[LNV_GRAPH]
|
||||
.set_sub_source(&lnav_data.ld_graph_source);
|
||||
lnav_data.ld_views[LNV_DB]
|
||||
.set_sub_source(&lnav_data.ld_db_row_source);
|
||||
lnav_data.ld_db_overlay.dos_labels = &lnav_data.ld_db_row_source;
|
||||
@ -2599,13 +2595,6 @@ int main(int argc, char *argv[])
|
||||
lnav_data.ld_views[lpc].set_gutter_source(new log_gutter_source());
|
||||
}
|
||||
|
||||
{
|
||||
setup_highlights(lnav_data.ld_views[LNV_LOG].get_highlights());
|
||||
setup_highlights(lnav_data.ld_views[LNV_TEXT].get_highlights());
|
||||
setup_highlights(lnav_data.ld_views[LNV_SCHEMA].get_highlights());
|
||||
setup_highlights(lnav_data.ld_views[LNV_PRETTY].get_highlights());
|
||||
}
|
||||
|
||||
{
|
||||
hist_source2 &hs = lnav_data.ld_hist_source2;
|
||||
|
||||
@ -2617,13 +2606,6 @@ int main(int argc, char *argv[])
|
||||
hs.set_time_slice(ZOOM_LEVELS[lnav_data.ld_zoom_level]);
|
||||
}
|
||||
|
||||
{
|
||||
hist_source &hs = lnav_data.ld_graph_source;
|
||||
|
||||
hs.set_bucket_size(1);
|
||||
hs.set_group_size(100);
|
||||
}
|
||||
|
||||
for (lpc = 0; lpc < LNV__MAX; lpc++) {
|
||||
lnav_data.ld_views[lpc].set_title(view_titles[lpc]);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "byte_array.hh"
|
||||
#include "grapher.hh"
|
||||
#include "logfile.hh"
|
||||
#include "hist_source.hh"
|
||||
#include "statusview_curses.hh"
|
||||
@ -116,7 +115,6 @@ typedef enum {
|
||||
LNV_TEXT,
|
||||
LNV_HELP,
|
||||
LNV_HISTOGRAM,
|
||||
LNV_GRAPH,
|
||||
LNV_DB,
|
||||
LNV_EXAMPLE,
|
||||
LNV_SCHEMA,
|
||||
@ -139,7 +137,6 @@ typedef enum {
|
||||
} lnav_status_t;
|
||||
|
||||
typedef enum {
|
||||
LG_GRAPH,
|
||||
LG_CAPTURE,
|
||||
|
||||
LG__MAX
|
||||
@ -236,8 +233,6 @@ struct _lnav_data {
|
||||
std::map<textview_curses *, int> ld_last_user_mark;
|
||||
std::map<textview_curses *, int> ld_select_start;
|
||||
|
||||
grapher ld_graph_source;
|
||||
|
||||
db_label_source ld_db_row_source;
|
||||
db_overlay_source ld_db_overlay;
|
||||
std::vector<std::string> ld_db_key_names;
|
||||
|
@ -820,7 +820,9 @@ static string com_highlight(string cmdline, vector<string> &args)
|
||||
retval = "error: " + string(errptr);
|
||||
}
|
||||
else {
|
||||
textview_curses::highlighter hl(code, false);
|
||||
textview_curses::highlighter hl(code);
|
||||
|
||||
hl.with_attrs(view_colors::singleton().attrs_for_ident(args[1]));
|
||||
|
||||
hm[args[1]] = hl;
|
||||
|
||||
@ -864,54 +866,6 @@ static string com_clear_highlight(string cmdline, vector<string> &args)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_graph(string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "error: expecting regular expression to graph";
|
||||
|
||||
if (args.size() == 0) {
|
||||
args.push_back("graph");
|
||||
}
|
||||
else if (args.size() > 1) {
|
||||
const char *errptr;
|
||||
pcre * code;
|
||||
int eoff;
|
||||
|
||||
args[1] = remaining_args(cmdline, args);
|
||||
if ((code = pcre_compile(args[1].c_str(),
|
||||
PCRE_CASELESS,
|
||||
&errptr,
|
||||
&eoff,
|
||||
NULL)) == NULL) {
|
||||
retval = "error: " + string(errptr);
|
||||
}
|
||||
else {
|
||||
textview_curses & tc = lnav_data.ld_views[LNV_LOG];
|
||||
textview_curses::highlighter hl(code, true);
|
||||
|
||||
textview_curses::highlight_map_t &hm = tc.get_highlights();
|
||||
|
||||
hm["(graph"] = hl;
|
||||
lnav_data.ld_graph_source.set_highlighter(&hm["(graph"]);
|
||||
|
||||
auto_ptr<grep_proc> gp(new grep_proc(code, tc));
|
||||
|
||||
gp->queue_request();
|
||||
gp->start();
|
||||
gp->set_sink(&lnav_data.ld_graph_source);
|
||||
|
||||
auto_ptr<grep_highlighter>
|
||||
gh(new grep_highlighter(gp, "(graph", hm));
|
||||
lnav_data.ld_grep_child[LG_GRAPH] = gh;
|
||||
|
||||
toggle_view(&lnav_data.ld_views[LNV_GRAPH]);
|
||||
|
||||
retval = "";
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_help(string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "";
|
||||
@ -2798,12 +2752,6 @@ readline_context::command_t STD_COMMANDS[] = {
|
||||
"Move to the previous bookmark of the given type in the current view",
|
||||
com_goto_mark,
|
||||
},
|
||||
{
|
||||
"graph",
|
||||
"<regex>",
|
||||
"Graph the number values captured by the given regex that are found in the log view",
|
||||
com_graph,
|
||||
},
|
||||
{
|
||||
"help",
|
||||
NULL,
|
||||
|
@ -207,7 +207,7 @@ public:
|
||||
memcpy(scan_value,
|
||||
line.get_data() + pvalue.e_capture.c_begin,
|
||||
pvalue.e_capture.length());
|
||||
scan_value[line.length()] = '\0';
|
||||
scan_value[pvalue.e_capture.length()] = '\0';
|
||||
if (sscanf(scan_value, "%lf", &d) != 1) {
|
||||
d = 0.0;
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ void readline_regex_highlighter(attr_line_t &al, int x)
|
||||
|
||||
void readline_command_highlighter(attr_line_t &al, int x)
|
||||
{
|
||||
static const pcrepp RE_PREFIXES("^:(filter-in|filter-out|highlight|graph)");
|
||||
static const pcrepp RE_PREFIXES("^:(filter-in|filter-out|highlight)");
|
||||
static const pcrepp SH_PREFIXES("^:(eval|open|append-to|write-to|write-csv-to|write-json-to)");
|
||||
static int keyword_attrs = (
|
||||
A_BOLD|view_colors::ansi_color_pair(COLOR_CYAN, COLOR_BLACK));
|
||||
|
@ -141,7 +141,7 @@ void textview_curses::listview_value_for_row(const listview_curses &lv,
|
||||
iter++) {
|
||||
// XXX testing for '$search' here sucks
|
||||
bool internal_hl = iter->first[0] == '$' && iter->first != "$search";
|
||||
int off, hcount = 0;
|
||||
int off;
|
||||
size_t re_end;
|
||||
|
||||
if (body.lr_end > 8192)
|
||||
@ -173,8 +173,7 @@ void textview_curses::listview_value_for_row(const listview_curses &lv,
|
||||
|
||||
if (lr.lr_end > lr.lr_start) {
|
||||
sa.push_back(string_attr(
|
||||
lr, &view_curses::VC_STYLE, iter->second.get_attrs(hcount)));
|
||||
hcount++;
|
||||
lr, &view_curses::VC_STYLE, iter->second.get_attrs()));
|
||||
|
||||
off = matches[1];
|
||||
}
|
||||
|
@ -439,24 +439,12 @@ public:
|
||||
highlighter()
|
||||
: h_code(NULL),
|
||||
h_code_extra(NULL),
|
||||
h_multiple(false) { };
|
||||
highlighter(pcre *code,
|
||||
bool multiple = false,
|
||||
view_colors::role_t role = view_colors::VCR_NONE)
|
||||
: h_code(code),
|
||||
h_multiple(multiple)
|
||||
h_attrs(-1) { };
|
||||
highlighter(pcre *code)
|
||||
: h_code(code), h_attrs(-1)
|
||||
{
|
||||
const char *errptr;
|
||||
|
||||
if (!multiple) {
|
||||
if (role == view_colors::VCR_NONE) {
|
||||
this->h_roles.
|
||||
push_back(view_colors::singleton().next_highlight());
|
||||
}
|
||||
else {
|
||||
this->h_roles.push_back(role);
|
||||
}
|
||||
}
|
||||
this->h_code_extra = pcre_study(this->h_code, 0, &errptr);
|
||||
if (!this->h_code_extra && errptr) {
|
||||
log_error("pcre_study error: %s", errptr);
|
||||
@ -471,34 +459,28 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
view_colors::role_t get_role(unsigned int index)
|
||||
{
|
||||
view_colors & vc = view_colors::singleton();
|
||||
view_colors::role_t retval;
|
||||
highlighter &with_role(view_colors::role_t role) {
|
||||
this->h_attrs = view_colors::singleton().attrs_for_role(role);
|
||||
|
||||
if (this->h_multiple) {
|
||||
while (index >= this->h_roles.size()) {
|
||||
this->h_roles.push_back(vc.next_highlight());
|
||||
}
|
||||
retval = this->h_roles[index];
|
||||
}
|
||||
else {
|
||||
retval = this->h_roles[0];
|
||||
}
|
||||
|
||||
return retval;
|
||||
return *this;
|
||||
};
|
||||
|
||||
int get_attrs(int index)
|
||||
highlighter &with_attrs(int attrs) {
|
||||
this->h_attrs = attrs;
|
||||
|
||||
return *this;
|
||||
};
|
||||
|
||||
int get_attrs() const
|
||||
{
|
||||
return view_colors::singleton().
|
||||
attrs_for_role(this->get_role(index));
|
||||
ensure(this->h_attrs != -1);
|
||||
|
||||
return this->h_attrs;
|
||||
};
|
||||
|
||||
pcre * h_code;
|
||||
pcre_extra * h_code_extra;
|
||||
bool h_multiple;
|
||||
std::vector<view_colors::role_t> h_roles;
|
||||
int h_attrs;
|
||||
};
|
||||
|
||||
textview_curses();
|
||||
|
@ -260,6 +260,17 @@ class color_listener : public lnav_config_listener {
|
||||
|
||||
static color_listener _COLOR_LISTENER;
|
||||
|
||||
int view_colors::BASIC_HL_PAIRS[view_colors::BASIC_COLOR_COUNT] = {
|
||||
ansi_color_pair(COLOR_BLUE, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_CYAN, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_GREEN, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_MAGENTA, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_BLUE, COLOR_WHITE),
|
||||
ansi_color_pair(COLOR_CYAN, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_GREEN, COLOR_WHITE),
|
||||
ansi_color_pair(COLOR_MAGENTA, COLOR_WHITE),
|
||||
};
|
||||
|
||||
view_colors &view_colors::singleton(void)
|
||||
{
|
||||
static view_colors s_vc;
|
||||
@ -268,10 +279,11 @@ view_colors &view_colors::singleton(void)
|
||||
}
|
||||
|
||||
view_colors::view_colors()
|
||||
: vc_next_highlight(0), vc_next_plain_highlight(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool view_colors::initialized = false;
|
||||
|
||||
void view_colors::init(void)
|
||||
{
|
||||
if (has_colors()) {
|
||||
@ -307,12 +319,7 @@ void view_colors::init(void)
|
||||
for (int y = 1; y < 6; y += 2) {
|
||||
int fg = 16 + x + (y * 6) + (z * 6 * 6);
|
||||
|
||||
init_pair(color_pair_base,
|
||||
fg,
|
||||
COLOR_BLACK);
|
||||
init_pair(color_pair_base + HL_COLOR_COUNT,
|
||||
COLOR_BLACK,
|
||||
fg);
|
||||
init_pair(color_pair_base, fg, COLOR_BLACK);
|
||||
color_pair_base += 1;
|
||||
}
|
||||
}
|
||||
@ -321,12 +328,12 @@ void view_colors::init(void)
|
||||
}
|
||||
|
||||
singleton().init_roles();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void view_colors::init_roles(void)
|
||||
{
|
||||
int lpc;
|
||||
|
||||
/* Setup the mappings from roles to actual colors. */
|
||||
this->vc_role_colors[VCR_TEXT] =
|
||||
ansi_color_pair(COLOR_WHITE, COLOR_BLACK);
|
||||
@ -369,74 +376,4 @@ void view_colors::init_roles(void)
|
||||
this->vc_role_colors[VCR_LOW_THRESHOLD] = ansi_color_pair(COLOR_BLACK, COLOR_GREEN);
|
||||
this->vc_role_colors[VCR_MED_THRESHOLD] = ansi_color_pair(COLOR_BLACK, COLOR_YELLOW);
|
||||
this->vc_role_colors[VCR_HIGH_THRESHOLD] = ansi_color_pair(COLOR_BLACK, COLOR_RED);
|
||||
|
||||
for (lpc = 0; lpc < VCR_HIGHLIGHT_START; lpc++) {
|
||||
this->vc_role_reverse_colors[lpc] =
|
||||
this->vc_role_colors[lpc] | A_REVERSE;
|
||||
}
|
||||
|
||||
static int basic_hl_pairs[HL_BASIC_COLOR_COUNT] = {
|
||||
ansi_color_pair(COLOR_BLUE, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_CYAN, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_GREEN, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_MAGENTA, COLOR_BLACK),
|
||||
};
|
||||
|
||||
static int basic_rev_hl_pairs[HL_BASIC_COLOR_COUNT] = {
|
||||
ansi_color_pair(COLOR_BLUE, COLOR_WHITE),
|
||||
ansi_color_pair(COLOR_CYAN, COLOR_BLACK),
|
||||
ansi_color_pair(COLOR_GREEN, COLOR_WHITE),
|
||||
ansi_color_pair(COLOR_MAGENTA, COLOR_WHITE),
|
||||
};
|
||||
|
||||
for (lpc = 0; lpc < HL_COLOR_COUNT / 2; lpc++) {
|
||||
this->vc_role_colors[VCR_HIGHLIGHT_START + (lpc * 2)] = basic_hl_pairs[
|
||||
lpc % HL_BASIC_COLOR_COUNT];
|
||||
this->vc_role_colors[VCR_HIGHLIGHT_START + (lpc * 2) + 1] = basic_hl_pairs[
|
||||
lpc % HL_BASIC_COLOR_COUNT] | A_BOLD;
|
||||
|
||||
this->vc_role_reverse_colors[VCR_HIGHLIGHT_START + (lpc * 2)] = basic_rev_hl_pairs[
|
||||
lpc % HL_BASIC_COLOR_COUNT] | A_REVERSE;
|
||||
this->vc_role_reverse_colors[VCR_HIGHLIGHT_START + (lpc * 2) + 1] = basic_rev_hl_pairs[
|
||||
lpc % HL_BASIC_COLOR_COUNT] | A_BOLD | A_REVERSE;
|
||||
}
|
||||
|
||||
if (COLORS >= 256) {
|
||||
int color_pair_base = VC_ANSI_END;
|
||||
|
||||
/*
|
||||
* Prime the highlight vector. The first HL_COLOR_COUNT color
|
||||
* pairs are assumed to be the highlight colors.
|
||||
*/
|
||||
for (lpc = VCR_HIGHLIGHT_START + HL_BASIC_COLOR_COUNT * 2;
|
||||
lpc < VCR__MAX;
|
||||
lpc++) {
|
||||
|
||||
this->vc_role_colors[lpc] = COLOR_PAIR(color_pair_base);
|
||||
|
||||
this->vc_role_reverse_colors[lpc] =
|
||||
COLOR_PAIR(color_pair_base) | A_REVERSE;
|
||||
|
||||
color_pair_base += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view_colors::role_t view_colors::next_highlight()
|
||||
{
|
||||
role_t retval = (role_t)(VCR_HIGHLIGHT_START + this->vc_next_highlight);
|
||||
|
||||
this->vc_next_highlight = (this->vc_next_highlight + 1) % HL_COLOR_COUNT;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
view_colors::role_t view_colors::next_plain_highlight()
|
||||
{
|
||||
role_t retval = (role_t)(VCR_HIGHLIGHT_START + this->vc_next_plain_highlight);
|
||||
|
||||
this->vc_next_plain_highlight = (this->vc_next_plain_highlight + 2) %
|
||||
(HL_COLOR_COUNT);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -536,9 +536,10 @@ private:
|
||||
*/
|
||||
class view_colors {
|
||||
public:
|
||||
/** The number of colors used for highlighting. */
|
||||
static const int HL_BASIC_COLOR_COUNT = 4;
|
||||
static const int HL_COLOR_COUNT = 2 * HL_BASIC_COLOR_COUNT + 9 * 6;
|
||||
static const unsigned long BASIC_COLOR_COUNT = 8;
|
||||
static const unsigned long HI_COLOR_COUNT = 6 * 3 * 3;
|
||||
|
||||
static int BASIC_HL_PAIRS[BASIC_COLOR_COUNT];
|
||||
|
||||
/** Roles that can be mapped to curses attributes using attrs_for_role() */
|
||||
typedef enum {
|
||||
@ -573,9 +574,6 @@ public:
|
||||
VCR_MED_THRESHOLD,
|
||||
VCR_HIGH_THRESHOLD,
|
||||
|
||||
VCR_HIGHLIGHT_START,
|
||||
VCR_HIGHLIGHT_END = VCR_HIGHLIGHT_START + HL_COLOR_COUNT,
|
||||
|
||||
VCR__MAX
|
||||
} role_t;
|
||||
|
||||
@ -611,27 +609,16 @@ public:
|
||||
return this->vc_role_reverse_colors[role];
|
||||
};
|
||||
|
||||
/**
|
||||
* @return The next set of attributes to use for highlighting text. This
|
||||
* method will iterate through eight-or-so attributes combinations so there
|
||||
* is some variety in how text is highlighted.
|
||||
*/
|
||||
role_t next_highlight();
|
||||
|
||||
role_t next_plain_highlight();
|
||||
|
||||
int attrs_for_ident(const char *str, size_t len) const {
|
||||
int index = crc32(1, (const Bytef*)str, len);
|
||||
unsigned long index = crc32(1, (const Bytef*)str, len);
|
||||
int retval;
|
||||
|
||||
if (COLORS >= 256) {
|
||||
retval = this->vc_role_colors[
|
||||
VCR_HIGHLIGHT_START + HL_BASIC_COLOR_COUNT * 2 +
|
||||
(abs(index) % (HL_COLOR_COUNT - HL_BASIC_COLOR_COUNT * 2))];
|
||||
unsigned long offset = index % HI_COLOR_COUNT;
|
||||
retval = COLOR_PAIR(VC_ANSI_END + offset);
|
||||
}
|
||||
else {
|
||||
retval = this->vc_role_colors[
|
||||
VCR_HIGHLIGHT_START + (abs(index) % HL_COLOR_COUNT)];
|
||||
retval = BASIC_HL_PAIRS[index % BASIC_COLOR_COUNT];
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -661,13 +648,12 @@ private:
|
||||
/** Private constructor that initializes the member fields. */
|
||||
view_colors();
|
||||
|
||||
static bool initialized;
|
||||
|
||||
/** Map of role IDs to attribute values. */
|
||||
int vc_role_colors[VCR__MAX];
|
||||
/** Map of role IDs to reverse-video attribute values. */
|
||||
int vc_role_reverse_colors[VCR__MAX];
|
||||
/** The index of the next highlight color to use. */
|
||||
int vc_next_highlight;
|
||||
int vc_next_plain_highlight;
|
||||
};
|
||||
|
||||
enum mouse_button_t {
|
||||
|
@ -47,14 +47,19 @@ public:
|
||||
int lpc;
|
||||
|
||||
for (lpc = 0; lpc < 16; lpc++) {
|
||||
view_colors::role_t role;
|
||||
int attrs;
|
||||
char label[64];
|
||||
attr_line_t al;
|
||||
line_range lr;
|
||||
|
||||
role = view_colors::singleton().next_highlight();
|
||||
snprintf(label, sizeof(label), "This is line: %d", lpc);
|
||||
attrs = view_colors::singleton().attrs_for_ident(label);
|
||||
al = label;
|
||||
al.get_attrs().push_back(string_attr(
|
||||
line_range(0, -1),
|
||||
&view_curses::VC_STYLE,
|
||||
attrs
|
||||
));
|
||||
lr.lr_start = 0;
|
||||
lr.lr_end = 40;
|
||||
this->mvwattrline(this->tc_window,
|
||||
@ -62,7 +67,7 @@ public:
|
||||
0,
|
||||
al,
|
||||
lr,
|
||||
role);
|
||||
view_colors::VCR_TEXT);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -431,7 +431,7 @@ run_test ${lnav_test} -n \
|
||||
|
||||
check_output "delete from lnav_views table works?" <<EOF
|
||||
count(*)
|
||||
10
|
||||
9
|
||||
EOF
|
||||
|
||||
|
||||
@ -443,7 +443,7 @@ run_test ${lnav_test} -n \
|
||||
|
||||
check_output "insert into lnav_views table works?" <<EOF
|
||||
count(*)
|
||||
10
|
||||
9
|
||||
EOF
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user