[view_curses] colors

Defect Number:
    Reviewed By:
   Testing Done:
This commit is contained in:
Timothy Stack 2019-08-07 09:46:19 -07:00
parent 9a05b9d186
commit 56a341f7f8
10 changed files with 209 additions and 27 deletions

View File

@ -283,6 +283,7 @@ void filter_sub_source::text_value_for_line(textview_curses &tc, int line,
void filter_sub_source::text_attrs_for_line(textview_curses &tc, int line,
string_attrs_t &value_out)
{
auto &vcolors = view_colors::singleton();
textview_curses *top_view = *lnav_data.ld_view_stack.top();
text_sub_source *tss = top_view->get_sub_source();
filter_stack &fs = tss->get_filters();
@ -299,19 +300,23 @@ void filter_sub_source::text_attrs_for_line(textview_curses &tc, int line,
line_range lr{2, 3};
value_out.emplace_back(lr, &view_curses::VC_GRAPHIC, enabled);
if (tf->is_enabled()) {
value_out.emplace_back(lr, &view_curses::VC_FOREGROUND, COLOR_GREEN);
value_out.emplace_back(lr, &view_curses::VC_FOREGROUND,
vcolors.ansi_to_theme_color(COLOR_GREEN));
}
int fg = tf->get_type() == text_filter::INCLUDE ? COLOR_GREEN : COLOR_RED;
value_out.emplace_back(line_range{4, 7}, &view_curses::VC_FOREGROUND, fg);
value_out.emplace_back(line_range{4, 7}, &view_curses::VC_FOREGROUND,
vcolors.ansi_to_theme_color(fg));
value_out.emplace_back(line_range{4, 7}, &view_curses::VC_STYLE, A_BOLD);
value_out.emplace_back(line_range{8, 14}, &view_curses::VC_STYLE, A_BOLD);
value_out.emplace_back(line_range{20, 21}, &view_curses::VC_GRAPHIC, ACS_VLINE);
fg = selected ? COLOR_BLACK : COLOR_WHITE;
value_out.emplace_back(line_range{0, -1}, &view_curses::VC_FOREGROUND, fg);
value_out.emplace_back(line_range{0, -1}, &view_curses::VC_BACKGROUND, bg);
value_out.emplace_back(line_range{0, -1}, &view_curses::VC_FOREGROUND,
vcolors.ansi_to_theme_color(fg));
value_out.emplace_back(line_range{0, -1}, &view_curses::VC_BACKGROUND,
vcolors.ansi_to_theme_color(bg));
}
size_t filter_sub_source::text_size_for_line(textview_curses &tc, int line,

View File

@ -61,6 +61,7 @@ void highlighter::study()
void highlighter::annotate(attr_line_t &al, int start) const
{
auto &vc = view_colors::singleton();
const std::string &str = al.get_string();
string_attrs_t &sa = al.get_attrs();
// The line we pass to pcre_exec will be treated as the start when the
@ -103,9 +104,18 @@ void highlighter::annotate(attr_line_t &al, int start) const
if (this->h_attrs != -1) {
attrs = this->h_attrs;
}
if (!this->h_fg.empty()) {
sa.emplace_back(lr,
&view_curses::VC_FOREGROUND,
vc.match_color(this->h_fg));
}
if (!this->h_bg.empty()) {
sa.emplace_back(lr,
&view_curses::VC_BACKGROUND,
vc.match_color(this->h_bg));
}
if (this->h_role != view_colors::VCR_NONE) {
attrs |= view_colors::singleton().attrs_for_role(
this->h_role);
attrs |= vc.attrs_for_role(this->h_role);
}
sa.emplace_back(lr, &view_curses::VC_STYLE, attrs);

View File

@ -1407,8 +1407,6 @@ static void looper()
for (auto &hl : format->lf_highlighters) {
if (hl.h_fg.empty()) {
hl.with_attrs(hl.h_attrs | vc.attrs_for_ident(hl.h_pattern));
} else {
hl.with_attrs(hl.h_attrs | vc.ensure_color_pair(hl.h_fg, hl.h_bg));
}
lnav_data.ld_views[LNV_LOG].get_highlights()[{

View File

@ -1737,7 +1737,7 @@ void external_log_format::build(std::vector<std::string> &errors) {
}
pcre *code = pcre_compile(pattern.c_str(),
0,
PCRE_CASELESS,
&errptr,
&eoff,
nullptr);

View File

@ -401,8 +401,6 @@ readline_context::readline_context(const std::string &name,
rc_quote_chars("\"'"),
rc_highlighter(nullptr)
{
char *home;
if (commands != nullptr) {
command_map_t::iterator iter;

View File

@ -124,6 +124,46 @@ bool rgb_color::from_str(const string_fragment &color,
return false;
}
bool rgb_color::operator<(const rgb_color &rhs) const
{
if (rc_r < rhs.rc_r)
return true;
if (rhs.rc_r < rc_r)
return false;
if (rc_g < rhs.rc_g)
return true;
if (rhs.rc_g < rc_g)
return false;
return rc_b < rhs.rc_b;
}
bool rgb_color::operator>(const rgb_color &rhs) const
{
return rhs < *this;
}
bool rgb_color::operator<=(const rgb_color &rhs) const
{
return !(rhs < *this);
}
bool rgb_color::operator>=(const rgb_color &rhs) const
{
return !(*this < rhs);
}
bool rgb_color::operator==(const rgb_color &rhs) const
{
return rc_r == rhs.rc_r &&
rc_g == rhs.rc_g &&
rc_b == rhs.rc_b;
}
bool rgb_color::operator!=(const rgb_color &rhs) const
{
return !(rhs == *this);
}
term_color_palette::term_color_palette(const unsigned char *json)
{
yajlpp_parse_context ypc_xterm("palette.json", root_color_handler);

View File

@ -50,6 +50,18 @@ struct rgb_color {
return this->rc_r == -1 && this->rc_g == -1 && this->rc_b == -1;
}
bool operator==(const rgb_color &rhs) const;
bool operator!=(const rgb_color &rhs) const;
bool operator<(const rgb_color &rhs) const;
bool operator>(const rgb_color &rhs) const;
bool operator<=(const rgb_color &rhs) const;
bool operator>=(const rgb_color &rhs) const;
short rc_r;
short rc_g;
short rc_b;
@ -71,6 +83,18 @@ struct lab_color {
return *this;
};
bool operator==(const lab_color &rhs) const;
bool operator!=(const lab_color &rhs) const;
bool operator<(const lab_color &rhs) const;
bool operator>(const lab_color &rhs) const;
bool operator<=(const lab_color &rhs) const;
bool operator>=(const lab_color &rhs) const;
double lc_l;
double lc_a;
double lc_b;

View File

@ -291,9 +291,9 @@ void view_curses::mvwattrline(WINDOW *window,
tab_count = count(line.begin(), line.end(), '\t');
expanded_line = (char *)alloca(line.size() + tab_count * 8 + 1);
unsigned char *fg_color = (unsigned char *) alloca(line_width);
short *fg_color = (short *) alloca(line_width * sizeof(short));
bool has_fg = false;
unsigned char *bg_color = (unsigned char *) alloca(line_width);
short *bg_color = (short *) alloca(line_width * sizeof(short));
bool has_bg = false;
for (size_t lpc = 0; lpc < line.size(); lpc++) {
@ -407,18 +407,18 @@ void view_curses::mvwattrline(WINDOW *window,
if (iter->sa_type == &VC_FOREGROUND) {
if (!has_fg) {
memset(fg_color, COLOR_WHITE, line_width);
memset(fg_color, -1, line_width * sizeof(short));
}
fill(fg_color + attr_range.lr_start, fg_color + attr_range.lr_end, iter->sa_value.sav_int);
fill(&fg_color[attr_range.lr_start], &fg_color[attr_range.lr_end], (short) iter->sa_value.sav_int);
has_fg = true;
continue;
}
if (iter->sa_type == &VC_BACKGROUND) {
if (!has_bg) {
memset(bg_color, COLOR_BLACK, line_width);
memset(bg_color, -1, line_width * sizeof(short));
}
fill(bg_color + attr_range.lr_start, bg_color + attr_range.lr_end, iter->sa_value.sav_int);
fill(bg_color + attr_range.lr_start, bg_color + attr_range.lr_end, (short) iter->sa_value.sav_int);
has_bg = true;
continue;
}
@ -471,10 +471,10 @@ void view_curses::mvwattrline(WINDOW *window,
#if 1
if (has_fg || has_bg) {
if (!has_fg) {
memset(fg_color, COLOR_WHITE, line_width);
memset(fg_color, -1, line_width * sizeof(short));
}
if (!has_bg) {
memset(bg_color, COLOR_BLACK, line_width);
memset(bg_color, -1, line_width * sizeof(short));
}
int x_pos = x + lr.lr_start;
@ -483,7 +483,11 @@ void view_curses::mvwattrline(WINDOW *window,
mvwin_wchnstr(window, y, x_pos, row_ch, ch_width);
for (int lpc = 0; lpc < ch_width; lpc++) {
int color_pair = view_colors::ansi_color_pair_index(fg_color[lpc], bg_color[lpc]);
if (fg_color[lpc] == -1 && bg_color[lpc] == -1) {
continue;
}
int color_pair = vc.ensure_color_pair(fg_color[lpc], bg_color[lpc]);
row_ch[lpc].attr = row_ch[lpc].attr & ~A_COLOR;
#ifdef NCURSES_EXT_COLORS
@ -535,7 +539,7 @@ static string COLOR_NAMES[] = {
class color_listener : public lnav_config_listener {
public:
void reload_config(error_reporter &reporter) {
view_colors &vc = view_colors::singleton();
auto &vc = view_colors::singleton();
for (const auto &pair : lnav_config.lc_ui_theme_defs) {
vc.init_roles(pair.second, reporter);
@ -546,6 +550,8 @@ public:
if (iter == lnav_config.lc_ui_theme_defs.end()) {
reporter(&lnav_config.lc_ui_theme,
"unknown theme -- " + lnav_config.lc_ui_theme);
vc.init_roles(lnav_config.lc_ui_theme_defs["default"], reporter);
return;
}
@ -616,6 +622,8 @@ inline attr_t attr_for_colors(int &pair_base, short fg, short bg)
}
}
require(pair_base < COLOR_PAIRS);
int pair = ++pair_base;
if (view_colors::initialized) {
@ -651,7 +659,9 @@ pair<attr_t, attr_t> view_colors::to_attrs(
reporter(&sc.sc_background_color, errmsg);
}
attr_t retval1 = this->ensure_color_pair(pair_base, fg, bg);
attr_t retval1 = attr_for_colors(pair_base,
this->match_color(fg),
this->match_color(bg));
attr_t retval2 = 0;
if (sc.sc_underline) {
@ -742,6 +752,7 @@ void view_colors::init_roles(const lnav_theme &lt,
bg = ansi_bg;
}
this->vc_ansi_to_theme[ansi_fg] = fg;
init_pair(ansi_color_pair_index(ansi_fg, ansi_bg), fg, bg);
}
}
@ -930,14 +941,53 @@ void view_colors::init_roles(const lnav_theme &lt,
if (initialized && this->vc_color_pair_end == 0) {
this->vc_color_pair_end = color_pair_base + 1;
}
this->vc_dyn_pairs.clear();
}
int view_colors::ensure_color_pair(int &pair_base, short fg, short bg)
{
require(fg >= -1);
require(bg >= -1);
auto index_pair = make_pair(fg, bg);
auto existing = this->vc_dyn_pairs.find(index_pair);
if (existing != this->vc_dyn_pairs.end()) {
return existing->second;
}
short def_pair = PAIR_NUMBER(this->attrs_for_role(VCR_TEXT));
short def_fg, def_bg;
pair_content(def_pair, &def_fg, &def_bg);
int retval = PAIR_NUMBER(attr_for_colors(
pair_base,
fg == -1 ? def_fg : fg,
bg == -1 ? def_bg : bg));
if (this->initialized) {
this->vc_dyn_pairs[index_pair] = retval;
}
return retval;
}
int view_colors::ensure_color_pair(int &pair_base, const rgb_color &rgb_fg, const rgb_color &rgb_bg)
{
return attr_for_colors(
pair_base,
rgb_fg.empty() ? (short) COLOR_WHITE : ACTIVE_PALETTE->match_color(lab_color(rgb_fg)),
rgb_bg.empty() ? (short) COLOR_BLACK : ACTIVE_PALETTE->match_color(lab_color(rgb_bg)));
int fg = this->match_color(rgb_fg);
int bg = this->match_color(rgb_bg);
return this->ensure_color_pair(pair_base, fg, bg);
}
int view_colors::match_color(const rgb_color &color)
{
if (color.empty()) {
return -1;
}
return ACTIVE_PALETTE->match_color(lab_color(color));
}
attr_t view_colors::attrs_for_ident(const char *str, size_t len) const
@ -1002,3 +1052,43 @@ double lab_color::deltaE(const lab_color &other) const
double i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh;
return i < 0.0 ? 0.0 : sqrt(i);
}
bool lab_color::operator<(const lab_color &rhs) const
{
if (lc_l < rhs.lc_l)
return true;
if (rhs.lc_l < lc_l)
return false;
if (lc_a < rhs.lc_a)
return true;
if (rhs.lc_a < lc_a)
return false;
return lc_b < rhs.lc_b;
}
bool lab_color::operator>(const lab_color &rhs) const
{
return rhs < *this;
}
bool lab_color::operator<=(const lab_color &rhs) const
{
return !(rhs < *this);
}
bool lab_color::operator>=(const lab_color &rhs) const
{
return !(*this < rhs);
}
bool lab_color::operator==(const lab_color &rhs) const
{
return lc_l == rhs.lc_l &&
lc_a == rhs.lc_a &&
lc_b == rhs.lc_b;
}
bool lab_color::operator!=(const lab_color &rhs) const
{
return !(rhs == *this);
}

View File

@ -400,12 +400,20 @@ public:
return this->attrs_for_ident(str.c_str(), str.length());
};
int ensure_color_pair(int &pair_base, short fg, short bg);
int ensure_color_pair(short fg, short bg) {
return this->ensure_color_pair(this->vc_color_pair_end, fg, bg);
}
int ensure_color_pair(int &pair_base, const rgb_color &fg, const rgb_color &bg);
int ensure_color_pair(const rgb_color &fg, const rgb_color &bg) {
return this->ensure_color_pair(this->vc_color_pair_end, fg, bg);
}
int match_color(const rgb_color &color);
static inline int ansi_color_pair_index(int fg, int bg)
{
return VC_ANSI_START + ((fg * 8) + bg);
@ -426,6 +434,10 @@ public:
std::pair<attr_t, attr_t> vc_level_attrs[LEVEL__MAX];
short ansi_to_theme_color(short ansi_fg) const {
return this->vc_ansi_to_theme[ansi_fg];
}
static bool initialized;
private:
@ -437,8 +449,9 @@ private:
std::pair<attr_t, attr_t> vc_role_colors[VCR__MAX];
/** Map of role IDs to reverse-video attribute values. */
attr_t vc_role_reverse_colors[VCR__MAX];
short vc_ansi_to_theme[8];
int vc_color_pair_end;
std::map<std::pair<short, short>, int> vc_dyn_pairs;
};
enum mouse_button_t {

View File

@ -1,5 +1,9 @@
#!/usr/bin/env bash
export HOME="./test-config"
rm -rf ./test-config
mkdir -p $HOME/.config
run_test ${lnav_test} -n \
-c ":config /ui/theme-defs/default/styles/text/color #f" \
${test_dir}/logfile_access_log.0