Enable configuring more pager colors

Originally I sought out to configure the foreground color of the
selected text in the pager. After reading a thread on a github issue I
was inpired to do more: now you can conifgure any part of the pager when
selected, and when a row is secondary. More specifically this commit adds the
ability to specify a pager row's:

- Prefix
- Completion text
- Description
- Background

when said row is selected or secondary.
This commit is contained in:
Dan Zimmerman 2019-01-13 02:16:30 -05:00 committed by ridiculousfish
parent f73b4fb746
commit 50448e4319
4 changed files with 110 additions and 43 deletions

View file

@ -1026,15 +1026,31 @@ The following variables are available to change the highlighting colors in fish:
Additionally, the following variables are available to change the highlighting in the completion pager:
- `fish_pager_color_progress`, the color of the progress bar at the bottom left corner
- `fish_pager_color_background`, the background color of a line
- `fish_pager_color_prefix`, the color of the prefix string, i.e. the string that is to be completed
- `fish_pager_color_completion`, the color of the completion itself
- `fish_pager_color_description`, the color of the completion description
- `fish_pager_color_progress`, the color of the progress bar at the bottom left corner
- `fish_pager_color_secondary_background`, `fish_pager_color_background` of every second unselected completion. Defaults to `fish_pager_color_background`
- `fish_pager_color_secondary`, the background color of the every second completion
- `fish_pager_color_secondary_ prefix`, `fish_pager_color_prefix` of every second unselected completion. Defaults to `fish_pager_color_prefix`
- `fish_pager_color_secondary_completion`, `fish_pager_color_completion` of every second unselected completion. Defaults to `fish_pager_color_completion`
- `fish_pager_color_secondary_description`, `fish_pager_color_description` of every second unselected completion. Defaults to `fish_pager_color_description`
- `fish_pager_color_selected_background`, `fish_pager_color_background` of the selected completion. Defaults to `fish_color_search_match`
- `fish_pager_color_selected_ prefix`, `fish_pager_color_prefix` of the selected completion. Defaults to `fish_pager_color_prefix`
- `fish_pager_color_selected_completion`, `fish_pager_color_completion` of the selected completion. Defaults to `fish_pager_color_completion`
- `fish_pager_color_selected_description`, `fish_pager_color_description` of the selected completion. Defaults to `fish_pager_color_description`
Example:

View file

@ -42,28 +42,69 @@ namespace g = grammar;
/// Number of elements in the highlight_var array.
#define VAR_COUNT (sizeof(highlight_var) / sizeof(wchar_t *))
static const wchar_t *const highlight_var[] = {
[highlight_spec_normal] = L"fish_color_normal",
[highlight_spec_error] = L"fish_color_error",
[highlight_spec_command] = L"fish_color_command",
[highlight_spec_statement_terminator] = L"fish_color_end",
[highlight_spec_param] = L"fish_color_param",
[highlight_spec_comment] = L"fish_color_comment",
[highlight_spec_match] = L"fish_color_match",
[highlight_spec_search_match] = L"fish_color_search_match",
[highlight_spec_operator] = L"fish_color_operator",
[highlight_spec_escape] = L"fish_color_escape",
[highlight_spec_quote] = L"fish_color_quote",
[highlight_spec_redirection] = L"fish_color_redirection",
[highlight_spec_autosuggestion] = L"fish_color_autosuggestion",
[highlight_spec_selection] = L"fish_color_selection",
[highlight_spec_pager_prefix] = L"fish_pager_color_prefix",
[highlight_spec_pager_completion] = L"fish_pager_color_completion",
[highlight_spec_pager_description] = L"fish_pager_color_description",
[highlight_spec_pager_progress] = L"fish_pager_color_progress",
[highlight_spec_pager_secondary] = L"fish_pager_color_secondary",
[highlight_spec_normal] = L"fish_color_normal",
[highlight_spec_error] = L"fish_color_error",
[highlight_spec_command] = L"fish_color_command",
[highlight_spec_statement_terminator] = L"fish_color_end",
[highlight_spec_param] = L"fish_color_param",
[highlight_spec_comment] = L"fish_color_comment",
[highlight_spec_match] = L"fish_color_match",
[highlight_spec_search_match] = L"fish_color_search_match",
[highlight_spec_operator] = L"fish_color_operator",
[highlight_spec_escape] = L"fish_color_escape",
[highlight_spec_quote] = L"fish_color_quote",
[highlight_spec_redirection] = L"fish_color_redirection",
[highlight_spec_autosuggestion] = L"fish_color_autosuggestion",
[highlight_spec_selection] = L"fish_color_selection",
[highlight_spec_pager_progress] = L"fish_pager_color_progress",
[highlight_spec_pager_background] = L"fish_pager_color_background",
[highlight_spec_pager_prefix] = L"fish_pager_color_prefix",
[highlight_spec_pager_completion] = L"fish_pager_color_completion",
[highlight_spec_pager_description] = L"fish_pager_color_description",
[highlight_spec_pager_secondary_background] = L"fish_pager_color_secondary_background",
[highlight_spec_pager_secondary_prefix] = L"fish_pager_color_secondary_prefix",
[highlight_spec_pager_secondary_completion] = L"fish_pager_color_secondary_completion",
[highlight_spec_pager_secondary_description] = L"fish_pager_color_secondary_description",
[highlight_spec_pager_selected_background] = L"fish_pager_color_selected_background",
[highlight_spec_pager_selected_prefix] = L"fish_pager_color_selected_prefix",
[highlight_spec_pager_selected_completion] = L"fish_pager_color_selected_completion",
[highlight_spec_pager_selected_description] = L"fish_pager_color_selected_description",
};
static_assert(VAR_COUNT == HIGHLIGHT_SPEC_MAX, "Every color spec has a corresponding env var");
// Table used to fetch fallback highlights in case the specified one
// wasn't set.
static const highlight_spec_t fallbacks[] = {
[highlight_spec_normal] = highlight_spec_normal,
[highlight_spec_error] = highlight_spec_normal,
[highlight_spec_command] = highlight_spec_normal,
[highlight_spec_statement_terminator] = highlight_spec_normal,
[highlight_spec_param] = highlight_spec_normal,
[highlight_spec_comment] = highlight_spec_normal,
[highlight_spec_match] = highlight_spec_normal,
[highlight_spec_search_match] = highlight_spec_normal,
[highlight_spec_operator] = highlight_spec_normal,
[highlight_spec_escape] = highlight_spec_normal,
[highlight_spec_quote] = highlight_spec_normal,
[highlight_spec_redirection] = highlight_spec_normal,
[highlight_spec_autosuggestion] = highlight_spec_normal,
[highlight_spec_selection] = highlight_spec_normal,
[highlight_spec_pager_progress] = highlight_spec_normal,
[highlight_spec_pager_background] = highlight_spec_normal,
[highlight_spec_pager_prefix] = highlight_spec_normal,
[highlight_spec_pager_completion] = highlight_spec_normal,
[highlight_spec_pager_description] = highlight_spec_normal,
[highlight_spec_pager_secondary_background] = highlight_spec_pager_background,
[highlight_spec_pager_secondary_prefix] = highlight_spec_pager_prefix,
[highlight_spec_pager_secondary_completion] = highlight_spec_pager_completion,
[highlight_spec_pager_secondary_description] = highlight_spec_pager_description,
[highlight_spec_pager_selected_background] = highlight_spec_search_match,
[highlight_spec_pager_selected_prefix] = highlight_spec_pager_prefix,
[highlight_spec_pager_selected_completion] = highlight_spec_pager_completion,
[highlight_spec_pager_selected_description] = highlight_spec_pager_description,
};
static_assert(sizeof(fallbacks) / sizeof(fallbacks[0]) == HIGHLIGHT_SPEC_MAX, "No missing fallbacks");
/// Determine if the filesystem containing the given fd is case insensitive for lookups regardless
/// of whether it preserves the case when saving a pathname.
///
@ -270,6 +311,7 @@ rgb_color_t highlight_get_color(highlight_spec_t highlight, bool is_background)
// debug( 1, L"%d -> %d -> %ls", highlight, idx, val );
if (!var) var = vars.get(highlight_var[fallbacks[idx]]);
if (!var) var = vars.get(highlight_var[0]);
if (var) result = parse_color(*var, treat_as_background);

View file

@ -33,11 +33,20 @@ enum {
highlight_spec_selection,
// Pager support.
// NOTE: pager.cpp relies on these being in this order.
highlight_spec_pager_progress,
highlight_spec_pager_background,
highlight_spec_pager_prefix,
highlight_spec_pager_completion,
highlight_spec_pager_description,
highlight_spec_pager_progress,
highlight_spec_pager_secondary,
highlight_spec_pager_secondary_background,
highlight_spec_pager_secondary_prefix,
highlight_spec_pager_secondary_completion,
highlight_spec_pager_secondary_description,
highlight_spec_pager_selected_background,
highlight_spec_pager_selected_prefix,
highlight_spec_pager_selected_completion,
highlight_spec_pager_selected_description,
// Used to double check a data structure in highlight.cpp
HIGHLIGHT_SPEC_MAX,

View file

@ -137,18 +137,24 @@ line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, s
assert(comp_width <= width);
}
int bg_color = secondary ? highlight_spec_pager_secondary : highlight_spec_normal;
if (selected) {
bg_color = highlight_spec_search_match;
}
int offset = selected
? (highlight_spec_pager_selected_background - highlight_spec_pager_background)
: (secondary
? (highlight_spec_pager_secondary_background - highlight_spec_pager_background)
: 0);
highlight_spec_t bg_color = highlight_spec_pager_background + offset;
highlight_spec_t prefix_fg = highlight_spec_pager_prefix + offset;
highlight_spec_t comp_fg = highlight_spec_pager_completion + offset;
highlight_spec_t desc_fg = highlight_spec_pager_description + offset;
auto bg = highlight_make_background(bg_color);
auto prefix_col = prefix_fg | bg;
auto comp_col = comp_fg | bg;
auto desc_col = desc_fg | bg;
// Print the completion part
size_t comp_remaining = comp_width;
for (size_t i = 0; i < c->comp.size(); i++) {
const wcstring &comp = c->comp.at(i);
highlight_spec_t packed_color =
highlight_spec_pager_prefix | bg;
if (i > 0) {
comp_remaining -= print_max(PAGER_SPACER_STRING, bg, comp_remaining,
@ -156,33 +162,27 @@ line_t pager_t::completion_print_item(const wcstring &prefix, const comp_t *c, s
}
comp_remaining -=
print_max(prefix, packed_color, comp_remaining, !comp.empty(), &line_data);
packed_color = highlight_spec_pager_completion | bg;
print_max(prefix, prefix_col, comp_remaining, !comp.empty(), &line_data);
comp_remaining -=
print_max(comp, packed_color, comp_remaining, i + 1 < c->comp.size(), &line_data);
print_max(comp, comp_col, comp_remaining, i + 1 < c->comp.size(), &line_data);
}
size_t desc_remaining = width - comp_width + comp_remaining;
if (c->desc_width > 0 && desc_remaining > 4) {
highlight_spec_t desc_color =
highlight_spec_pager_description | bg;
highlight_spec_t punct_color =
highlight_spec_pager_completion | bg;
// always have at least two spaces to separate completion and description
desc_remaining -= print_max(L" ", punct_color, 2, false, &line_data);
desc_remaining -= print_max(L" ", bg, 2, false, &line_data);
// right-justify the description by adding spaces
// the 2 here refers to the parenthesis below
while (desc_remaining > c->desc_width + 2) {
desc_remaining -= print_max(L" ", punct_color, 1, false, &line_data);
desc_remaining -= print_max(L" ", bg, 1, false, &line_data);
}
assert(desc_remaining >= 2);
desc_remaining -= print_max(L"(", punct_color, 1, false, &line_data);
desc_remaining -= print_max(c->desc, desc_color, desc_remaining - 1, false, &line_data);
desc_remaining -= print_max(L")", punct_color, 1, false, &line_data);
auto paren_col = highlight_spec_pager_completion | bg;
desc_remaining -= print_max(L"(", paren_col, 1, false, &line_data);
desc_remaining -= print_max(c->desc, desc_col, desc_remaining - 1, false, &line_data);
desc_remaining -= print_max(L")", paren_col, 1, false, &line_data);
} else {
// No description, or it won't fit. Just add spaces.
print_max(wcstring(desc_remaining, L' '), bg, desc_remaining, false, &line_data);