Replace the Exclusive
face attribute with Final
Final is more granular, it consists of FinalFg (f), FinalBg (g) and FinalAttr (a) which control if a face's fg, bg, or attributes fully overwrite the previous face (instead of merging) and if following faces apply on top of this face or not. Fixes #2388 if the Whitespace face has the FinalFg flag.
This commit is contained in:
parent
09546a950e
commit
1631a7d8d9
|
@ -71,6 +71,6 @@ evaluate-commands %sh{
|
||||||
face global Prompt ${yellow}
|
face global Prompt ${yellow}
|
||||||
face global MatchingChar default+b
|
face global MatchingChar default+b
|
||||||
face global BufferPadding ${bg2},${bg}
|
face global BufferPadding ${bg2},${bg}
|
||||||
face global Whitespace ${bg2}
|
face global Whitespace ${bg2}+f
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ Kakoune won't be able to parse named parameters in requests.
|
||||||
Here are the data structures used:
|
Here are the data structures used:
|
||||||
|
|
||||||
* Color: a string, either a named color, or #rrggbb, or 'default'
|
* Color: a string, either a named color, or #rrggbb, or 'default'
|
||||||
* Attribute: one of {exclusive, underline, reverse, blink, bold, dim, italic}
|
* Attribute: one of {underline, reverse, blink, bold, dim, italic, final_fg, final_bg, final_attr}
|
||||||
* Face { Color fg; Color bg; Array<Attribute> attributes; }
|
* Face { Color fg; Color bg; Array<Attribute> attributes; }
|
||||||
* Atom { Face face; String contents; }
|
* Atom { Face face; String contents; }
|
||||||
* Line : Array of Atom
|
* Line : Array of Atom
|
||||||
|
|
|
@ -8,6 +8,13 @@ released versions.
|
||||||
* `remove-hooks` <group> argument is now a regex and removes all
|
* `remove-hooks` <group> argument is now a regex and removes all
|
||||||
hooks whose group matches it.
|
hooks whose group matches it.
|
||||||
|
|
||||||
|
* `exclusive` face attribute (e) has been replaced with more
|
||||||
|
granular `final foreground` (f), `final background` (g), and `final
|
||||||
|
attributes` (a), or the three combined as `final` (F). Semantics
|
||||||
|
changed slightly as those attributes apply to the existing face as
|
||||||
|
well (a final face will not get modified by a following face if that
|
||||||
|
following face does not have the final attribute itself.
|
||||||
|
|
||||||
== Kakoune 2018.09.04
|
== Kakoune 2018.09.04
|
||||||
|
|
||||||
This version contains a significant overhaul of various Kakoune
|
This version contains a significant overhaul of various Kakoune
|
||||||
|
|
|
@ -33,9 +33,19 @@ fg_color[,bg_color][+attributes]
|
||||||
dim
|
dim
|
||||||
*i*:::
|
*i*:::
|
||||||
italic
|
italic
|
||||||
*e*:::
|
*F*:::
|
||||||
exclusive, override previous faces instead of merging
|
final, override the previous face instead of merging with it
|
||||||
with them
|
an will only be replaced if another face with the final
|
||||||
|
attribute is applied
|
||||||
|
*f*:::
|
||||||
|
final foreground, as final but only applies to face's
|
||||||
|
foreground color
|
||||||
|
*g*:::
|
||||||
|
final background, as final but only applies to face's
|
||||||
|
background color
|
||||||
|
*a*:::
|
||||||
|
final attributes, as final but only applies to face's
|
||||||
|
attributes
|
||||||
|
|
||||||
== Builtin faces
|
== Builtin faces
|
||||||
|
|
||||||
|
|
36
src/face.hh
36
src/face.hh
|
@ -10,13 +10,16 @@ namespace Kakoune
|
||||||
enum class Attribute : int
|
enum class Attribute : int
|
||||||
{
|
{
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
Exclusive = 1 << 1,
|
Underline = 1 << 1,
|
||||||
Underline = 1 << 2,
|
Reverse = 1 << 2,
|
||||||
Reverse = 1 << 3,
|
Blink = 1 << 3,
|
||||||
Blink = 1 << 4,
|
Bold = 1 << 4,
|
||||||
Bold = 1 << 5,
|
Dim = 1 << 5,
|
||||||
Dim = 1 << 6,
|
Italic = 1 << 6,
|
||||||
Italic = 1 << 7,
|
FinalFg = 1 << 7,
|
||||||
|
FinalBg = 1 << 8,
|
||||||
|
FinalAttr = 1 << 8,
|
||||||
|
Final = FinalFg | FinalBg | FinalAttr
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool with_bit_ops(Meta::Type<Attribute>) { return true; }
|
constexpr bool with_bit_ops(Meta::Type<Attribute>) { return true; }
|
||||||
|
@ -49,11 +52,22 @@ constexpr size_t hash_value(const Face& val)
|
||||||
return hash_values(val.fg, val.bg, val.attributes);
|
return hash_values(val.fg, val.bg, val.attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Face merge_faces(const Face& base, const Face& face)
|
inline Face merge_faces(const Face& base, const Face& face)
|
||||||
{
|
{
|
||||||
return face.attributes & Attribute::Exclusive ?
|
auto choose = [&](Color Face::*color, Attribute final_attr) {
|
||||||
face : Face{ face.fg == Color::Default ? base.fg : face.fg,
|
if (face.attributes & final_attr)
|
||||||
face.bg == Color::Default ? base.bg : face.bg,
|
return face.*color;
|
||||||
|
if (base.attributes & final_attr)
|
||||||
|
return base.*color;
|
||||||
|
if (face.*color == Color::Default)
|
||||||
|
return base.*color;
|
||||||
|
return face.*color;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Face{ choose(&Face::fg, Attribute::FinalFg),
|
||||||
|
choose(&Face::bg, Attribute::FinalBg),
|
||||||
|
face.attributes & Attribute::FinalAttr ? face.attributes :
|
||||||
|
base.attributes & Attribute::FinalAttr ? base.attributes :
|
||||||
face.attributes | base.attributes };
|
face.attributes | base.attributes };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,16 @@ static Face parse_face(StringView facedesc)
|
||||||
{
|
{
|
||||||
switch (*attr_it)
|
switch (*attr_it)
|
||||||
{
|
{
|
||||||
case 'e': res.attributes |= Attribute::Exclusive; break;
|
|
||||||
case 'u': res.attributes |= Attribute::Underline; break;
|
case 'u': res.attributes |= Attribute::Underline; break;
|
||||||
case 'r': res.attributes |= Attribute::Reverse; break;
|
case 'r': res.attributes |= Attribute::Reverse; break;
|
||||||
case 'b': res.attributes |= Attribute::Bold; break;
|
case 'b': res.attributes |= Attribute::Bold; break;
|
||||||
case 'B': res.attributes |= Attribute::Blink; break;
|
case 'B': res.attributes |= Attribute::Blink; break;
|
||||||
case 'd': res.attributes |= Attribute::Dim; break;
|
case 'd': res.attributes |= Attribute::Dim; break;
|
||||||
case 'i': res.attributes |= Attribute::Italic; break;
|
case 'i': res.attributes |= Attribute::Italic; break;
|
||||||
|
case 'f': res.attributes |= Attribute::FinalFg; break;
|
||||||
|
case 'g': res.attributes |= Attribute::FinalBg; break;
|
||||||
|
case 'a': res.attributes |= Attribute::FinalAttr; break;
|
||||||
|
case 'F': res.attributes |= Attribute::Final; break;
|
||||||
default: throw runtime_error(format("no such face attribute: '{}'", StringView{*attr_it}));
|
default: throw runtime_error(format("no such face attribute: '{}'", StringView{*attr_it}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,13 +53,16 @@ String to_string(Attribute attributes)
|
||||||
|
|
||||||
struct Attr { Attribute attr; StringView name; }
|
struct Attr { Attribute attr; StringView name; }
|
||||||
attrs[] {
|
attrs[] {
|
||||||
{ Attribute::Exclusive, "e" },
|
|
||||||
{ Attribute::Underline, "u" },
|
{ Attribute::Underline, "u" },
|
||||||
{ Attribute::Reverse, "r" },
|
{ Attribute::Reverse, "r" },
|
||||||
{ Attribute::Blink, "B" },
|
{ Attribute::Blink, "B" },
|
||||||
{ Attribute::Bold, "b" },
|
{ Attribute::Bold, "b" },
|
||||||
{ Attribute::Dim, "d" },
|
{ Attribute::Dim, "d" },
|
||||||
{ Attribute::Italic, "i" },
|
{ Attribute::Italic, "i" },
|
||||||
|
{ Attribute::Final, "F" },
|
||||||
|
{ Attribute::FinalFg, "f" },
|
||||||
|
{ Attribute::FinalBg, "b" },
|
||||||
|
{ Attribute::FinalAttr, "a" },
|
||||||
};
|
};
|
||||||
|
|
||||||
auto filteredAttrs = attrs |
|
auto filteredAttrs = attrs |
|
||||||
|
@ -150,7 +156,7 @@ FaceRegistry::FaceRegistry()
|
||||||
{ "Prompt", {Face{ Color::Yellow, Color::Default }} },
|
{ "Prompt", {Face{ Color::Yellow, Color::Default }} },
|
||||||
{ "MatchingChar", {Face{ Color::Default, Color::Default, Attribute::Bold }} },
|
{ "MatchingChar", {Face{ Color::Default, Color::Default, Attribute::Bold }} },
|
||||||
{ "BufferPadding", {Face{ Color::Blue, Color::Default }} },
|
{ "BufferPadding", {Face{ Color::Blue, Color::Default }} },
|
||||||
{ "Whitespace", {Face{ Color::Default, Color::Default }} },
|
{ "Whitespace", {Face{ Color::Default, Color::Default, Attribute::FinalFg }} },
|
||||||
}
|
}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -81,13 +81,15 @@ String to_json(Attribute attributes)
|
||||||
{
|
{
|
||||||
struct Attr { Attribute attr; StringView name; }
|
struct Attr { Attribute attr; StringView name; }
|
||||||
attrs[] {
|
attrs[] {
|
||||||
{ Attribute::Exclusive, "exclusive" },
|
|
||||||
{ Attribute::Underline, "underline" },
|
{ Attribute::Underline, "underline" },
|
||||||
{ Attribute::Reverse, "reverse" },
|
{ Attribute::Reverse, "reverse" },
|
||||||
{ Attribute::Blink, "blink" },
|
{ Attribute::Blink, "blink" },
|
||||||
{ Attribute::Bold, "bold" },
|
{ Attribute::Bold, "bold" },
|
||||||
{ Attribute::Dim, "dim" },
|
{ Attribute::Dim, "dim" },
|
||||||
{ Attribute::Italic, "italic" },
|
{ Attribute::Italic, "italic" },
|
||||||
|
{ Attribute::FinalFg, "final_fg" },
|
||||||
|
{ Attribute::FinalBg, "final_bg" },
|
||||||
|
{ Attribute::FinalAttr, "final_attr" },
|
||||||
};
|
};
|
||||||
|
|
||||||
return "[" + join(attrs |
|
return "[" + join(attrs |
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }
|
{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }
|
||||||
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "·" }, { "face": { "fg": "black", "bg": "cyan", "attributes": [] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "·" }, { "face": { "fg": "default", "bg": "cyan", "attributes": ["final_fg"] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
||||||
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:2 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:2 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||||
{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 1 }] }
|
{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 1 }] }
|
||||||
{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }
|
{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }
|
||||||
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "·" }, { "face": { "fg": "black", "bg": "cyan", "attributes": [] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "·" }, { "face": { "fg": "default", "bg": "cyan", "attributes": ["final_fg"] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
||||||
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:2 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:2 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }
|
{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }
|
||||||
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "this" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "→ " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "is" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "→ " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "a" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "→ " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "test" }, { "face": { "fg": "black", "bg": "cyan", "attributes": [] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "this" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "→ " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "is" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "→ " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "a" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "→ " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "test" }, { "face": { "fg": "default", "bg": "cyan", "attributes": ["final_fg"] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
||||||
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:15 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:15 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user