[highlight] choose highlight color based on the regex

Defect Number:
    Reviewed By:
   Testing Done:
This commit is contained in:
Timothy Stack 2016-10-25 06:39:36 -07:00
parent 06ca3c5288
commit b392886f0c
17 changed files with 118 additions and 422 deletions

9
NEWS
View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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;

View File

@ -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 &regex_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 &regex) {
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]);
}

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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));

View File

@ -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];
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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 {

View File

@ -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);
}
};

View File

@ -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