Rename ColorPair to Face and ColorRegistry to FaceRegistry

Face also stores the attributes
This commit is contained in:
Maxime Coste 2014-07-11 00:27:04 +01:00
parent 42611aef1e
commit a32b49acd1
20 changed files with 294 additions and 268 deletions

View File

@ -1,6 +1,6 @@
#include "client.hh" #include "client.hh"
#include "color_registry.hh" #include "face_registry.hh"
#include "context.hh" #include "context.hh"
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "user_interface.hh" #include "user_interface.hh"
@ -52,23 +52,23 @@ DisplayLine Client::generate_mode_line() const
auto col = context().buffer()[pos.line].char_count_to(pos.column); auto col = context().buffer()[pos.line].char_count_to(pos.column);
DisplayLine status; DisplayLine status;
ColorPair info_color = get_color("Information"); Face info_face = get_face("Information");
ColorPair status_color = get_color("StatusLine"); Face status_face = get_face("StatusLine");
ColorPair prompt_color = get_color("Prompt"); Face prompt_face = get_face("Prompt");
status.push_back({ context().buffer().display_name(), status_color }); status.push_back({ context().buffer().display_name(), status_face });
status.push_back({ " " + to_string((int)pos.line+1) + ":" + to_string((int)col+1) + " ", status_color }); status.push_back({ " " + to_string((int)pos.line+1) + ":" + to_string((int)col+1) + " ", status_face });
if (context().buffer().is_modified()) if (context().buffer().is_modified())
status.push_back({ "[+]", info_color }); status.push_back({ "[+]", info_face });
if (m_input_handler.is_recording()) if (m_input_handler.is_recording())
status.push_back({ "[recording ("_str + m_input_handler.recording_reg() + ")]", info_color }); status.push_back({ "[recording ("_str + m_input_handler.recording_reg() + ")]", info_face });
if (context().buffer().flags() & Buffer::Flags::New) if (context().buffer().flags() & Buffer::Flags::New)
status.push_back({ "[new file]", info_color }); status.push_back({ "[new file]", info_face });
if (context().buffer().flags() & Buffer::Flags::Fifo) if (context().buffer().flags() & Buffer::Flags::Fifo)
status.push_back({ "[fifo]", info_color }); status.push_back({ "[fifo]", info_face });
status.push_back({ " ", status_color }); status.push_back({ " ", status_face });
status.push_back({ m_input_handler.mode_string(), prompt_color }); status.push_back({ m_input_handler.mode_string(), prompt_face });
status.push_back({ " - " + context().name() + "@[" + Server::instance().session() + "]", status_color }); status.push_back({ " - " + context().name() + "@[" + Server::instance().session() + "]", status_face });
return status; return status;
} }
@ -118,7 +118,7 @@ static void reload_buffer(Context& context, const String& filename)
context.selections() = SelectionList{ *buf, buf->clamp(cursor_pos)}; context.selections() = SelectionList{ *buf, buf->clamp(cursor_pos)};
context.window().set_position(view_pos); context.window().set_position(view_pos);
context.print_status({ "'" + buf->display_name() + "' reloaded", context.print_status({ "'" + buf->display_name() + "' reloaded",
get_color("Information") }); get_face("Information") });
} }
void Client::check_buffer_fs_timestamp() void Client::check_buffer_fs_timestamp()
@ -140,7 +140,7 @@ void Client::check_buffer_fs_timestamp()
"reload '" + buffer.display_name() + "' ?", "reload '" + buffer.display_name() + "' ?",
"'" + buffer.display_name() + "' was modified externally\n" "'" + buffer.display_name() + "' was modified externally\n"
"press r or y to reload, k or n to keep", "press r or y to reload, k or n to keep",
pos, get_color("Information"), MenuStyle::Prompt); pos, get_face("Information"), MenuStyle::Prompt);
m_input_handler.on_next_key([this, filename, ts](Key key, Context& context) { m_input_handler.on_next_key([this, filename, ts](Key key, Context& context) {
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename); Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
@ -154,12 +154,12 @@ void Client::check_buffer_fs_timestamp()
{ {
buf->set_fs_timestamp(ts); buf->set_fs_timestamp(ts);
print_status({ "'" + buf->display_name() + "' kept", print_status({ "'" + buf->display_name() + "' kept",
get_color("Information") }); get_face("Information") });
} }
else else
{ {
print_status({ "'" + key_to_str(key) + "' is not a valid choice", print_status({ "'" + key_to_str(key) + "' is not a valid choice",
get_color("Error") }); get_face("Error") });
check_buffer_fs_timestamp(); check_buffer_fs_timestamp();
} }
}); });

View File

@ -1,9 +1,9 @@
#include "client_manager.hh" #include "client_manager.hh"
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh" #include "command_manager.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "user_interface.hh" #include "user_interface.hh"
#include "window.hh" #include "window.hh"
@ -40,7 +40,7 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
} }
catch (Kakoune::runtime_error& error) catch (Kakoune::runtime_error& error)
{ {
client->context().print_status({ error.what(), get_color("Error") }); client->context().print_status({ error.what(), get_face("Error") });
client->context().hooks().run_hook("RuntimeError", error.what(), client->context().hooks().run_hook("RuntimeError", error.what(),
client->context()); client->context());
} }
@ -57,7 +57,7 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
} }
catch (Kakoune::runtime_error& error) catch (Kakoune::runtime_error& error)
{ {
client->context().print_status({ error.what(), get_color("Error") }); client->context().print_status({ error.what(), get_face("Error") });
client->context().hooks().run_hook("RuntimeError", error.what(), client->context().hooks().run_hook("RuntimeError", error.what(),
client->context()); client->context());
} }

View File

@ -40,8 +40,6 @@ struct Color
{ return color != c.color or r != c.r or g != c.g or b != c.b; } { return color != c.color or r != c.r or g != c.g or b != c.b; }
}; };
using ColorPair = std::pair<Color, Color>;
Color str_to_color(const String& color); Color str_to_color(const String& color);
String color_to_str(Color color); String color_to_str(Color color);

View File

@ -1,36 +0,0 @@
#ifndef color_registry_hh_INCLUDED
#define color_registry_hh_INCLUDED
#include "color.hh"
#include "utils.hh"
#include "completion.hh"
#include <unordered_map>
namespace Kakoune
{
class ColorRegistry : public Singleton<ColorRegistry>
{
public:
ColorRegistry();
const ColorPair& operator[](const String& colordesc);
void register_alias(const String& name, const String& colordesc,
bool override = false);
CandidateList complete_alias_name(StringView prefix,
ByteCount cursor_pos) const;
private:
std::unordered_map<String, ColorPair> m_aliases;
};
inline const ColorPair& get_color(const String& colordesc)
{
return ColorRegistry::instance()[colordesc];
}
}
#endif // color_registry_hh_INCLUDED

View File

@ -5,12 +5,12 @@
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "client.hh" #include "client.hh"
#include "client_manager.hh" #include "client_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh" #include "command_manager.hh"
#include "completion.hh" #include "completion.hh"
#include "context.hh" #include "context.hh"
#include "debug.hh" #include "debug.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "highlighter.hh" #include "highlighter.hh"
#include "highlighters.hh" #include "highlighters.hh"
@ -39,7 +39,7 @@ Buffer* open_or_create(const String& filename, Context& context)
Buffer* buffer = create_buffer_from_file(filename); Buffer* buffer = create_buffer_from_file(filename);
if (not buffer) if (not buffer)
{ {
context.print_status({ "new file " + filename, get_color("StatusLine") }); context.print_status({ "new file " + filename, get_face("StatusLine") });
buffer = new Buffer(filename, Buffer::Flags::File | Buffer::Flags::New); buffer = new Buffer(filename, Buffer::Flags::File | Buffer::Flags::New);
} }
return buffer; return buffer;
@ -720,9 +720,9 @@ const CommandDesc echo_cmd = {
write_debug(message); write_debug(message);
else else
{ {
auto color = get_color(parser.has_option("color") ? auto face = get_face(parser.has_option("color") ?
parser.option_value("color") : "StatusLine"); parser.option_value("color") : "StatusLine");
context.print_status({ std::move(message), color } ); context.print_status({ std::move(message), face } );
} }
} }
}; };
@ -1117,7 +1117,7 @@ const CommandDesc prompt_cmd = {
initstr = params.option_value("init"); initstr = params.option_value("init");
context.input_handler().prompt( context.input_handler().prompt(
params[0], std::move(initstr), get_color("Prompt"), Completer{}, params[0], std::move(initstr), get_face("Prompt"), Completer{},
[=](const String& str, PromptEvent event, Context& context) [=](const String& str, PromptEvent event, Context& context)
{ {
if (event != PromptEvent::Validate) if (event != PromptEvent::Validate)
@ -1209,7 +1209,7 @@ const CommandDesc info_cmd = {
pos = context.window().display_position(it); pos = context.window().display_position(it);
} }
const String& title = parser.has_option("title") ? parser.option_value("title") : ""; const String& title = parser.has_option("title") ? parser.option_value("title") : "";
context.ui().info_show(title, parser[0], pos, get_color("Information"), style); context.ui().info_show(title, parser[0], pos, get_face("Information"), style);
} }
} }
}; };
@ -1249,7 +1249,7 @@ static Completions complete_colalias(const Context&, CompletionFlags flags,
const String& prefix, ByteCount cursor_pos) const String& prefix, ByteCount cursor_pos)
{ {
return {0_byte, cursor_pos, return {0_byte, cursor_pos,
ColorRegistry::instance().complete_alias_name(prefix, cursor_pos)}; FaceRegistry::instance().complete_alias_name(prefix, cursor_pos)};
} }
const CommandDesc define_color_alias_cmd = { const CommandDesc define_color_alias_cmd = {
@ -1261,7 +1261,7 @@ const CommandDesc define_color_alias_cmd = {
PerArgumentCommandCompleter({ complete_colalias, complete_colalias }), PerArgumentCommandCompleter({ complete_colalias, complete_colalias }),
[](const ParametersParser& parser, Context& context) [](const ParametersParser& parser, Context& context)
{ {
ColorRegistry::instance().register_alias(parser[0], parser[1], true); FaceRegistry::instance().register_alias(parser[0], parser[1], true);
} }
}; };

View File

@ -96,8 +96,7 @@ void DisplayLine::optimize()
auto& next_atom = *next_atom_it; auto& next_atom = *next_atom_it;
bool merged = false; bool merged = false;
if (atom.colors == next_atom.colors and if (atom.face == next_atom.face and
atom.attribute == next_atom.attribute and
atom.type() == next_atom.type()) atom.type() == next_atom.type())
{ {
auto type = atom.type(); auto type = atom.type();

View File

@ -2,7 +2,7 @@
#define display_buffer_hh_INCLUDED #define display_buffer_hh_INCLUDED
#include "buffer.hh" #include "buffer.hh"
#include "color.hh" #include "face.hh"
#include "coord.hh" #include "coord.hh"
#include "string.hh" #include "string.hh"
#include "utf8.hh" #include "utf8.hh"
@ -12,17 +12,6 @@
namespace Kakoune namespace Kakoune
{ {
using Attribute = char;
enum Attributes
{
Normal = 0,
Underline = 1,
Reverse = 2,
Blink = 4,
Bold = 8
};
struct DisplayAtom struct DisplayAtom
{ {
public: public:
@ -32,9 +21,8 @@ public:
: m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end) : m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end)
{ check_invariant(); } { check_invariant(); }
DisplayAtom(String str, ColorPair colors = { Colors::Default, Colors::Default }, DisplayAtom(String str, Face face = Face{})
Attribute attribute = Normal) : m_type(Text), m_text(std::move(str)), face(face)
: m_type(Text), m_text(std::move(str)), colors(colors), attribute(attribute)
{ check_invariant(); } { check_invariant(); }
StringView content() const StringView content() const
@ -108,13 +96,11 @@ public:
bool operator==(const DisplayAtom& other) const bool operator==(const DisplayAtom& other) const
{ {
return colors == other.colors or attribute == other.attribute or return face == other.face and content() == other.content();
content() == other.content();
} }
public: public:
ColorPair colors = {Colors::Default, Colors::Default}; Face face;
Attribute attribute = Normal;
private: private:
friend class DisplayLine; friend class DisplayLine;
@ -139,8 +125,8 @@ public:
DisplayLine() = default; DisplayLine() = default;
DisplayLine(AtomList atoms); DisplayLine(AtomList atoms);
DisplayLine(String str, ColorPair color) DisplayLine(String str, Face face)
{ push_back({ std::move(str), color }); } { push_back({ std::move(str), face }); }
iterator begin() { return m_atoms.begin(); } iterator begin() { return m_atoms.begin(); }
iterator end() { return m_atoms.end(); } iterator end() { return m_atoms.end(); }

45
src/face.hh Normal file
View File

@ -0,0 +1,45 @@
#ifndef face_hh_INCLUDED
#define face_hh_INCLUDED
#include "color.hh"
namespace Kakoune
{
using Attribute = char;
enum Attributes
{
Normal = 0,
Underline = 1,
Reverse = 2,
Blink = 4,
Bold = 8
};
struct Face
{
Color fg;
Color bg;
Attribute attributes;
Face(Color fg = Colors::Default, Color bg = Colors::Default,
Attribute attributes = 0)
: fg{fg}, bg{bg}, attributes{attributes} {}
};
inline bool operator==(const Face& lhs, const Face& rhs)
{
return lhs.fg == rhs.fg and
lhs.bg == rhs.bg and
lhs.attributes == rhs.attributes;
}
inline bool operator!=(const Face& lhs, const Face& rhs)
{
return not (lhs == rhs);
}
}
#endif // face_hh_INCLUDED

View File

@ -1,27 +1,27 @@
#include "color_registry.hh" #include "face_registry.hh"
#include "exception.hh" #include "exception.hh"
namespace Kakoune namespace Kakoune
{ {
static ColorPair parse_color_pair(const String& colordesc) static Face parse_face(const String& facedesc)
{ {
auto it = std::find(colordesc.begin(), colordesc.end(), ','); auto it = std::find(facedesc.begin(), facedesc.end(), ',');
return { str_to_color({colordesc.begin(), it}), return { str_to_color({facedesc.begin(), it}),
it != colordesc.end() ? str_to_color({it+1, colordesc.end()}) it != facedesc.end() ? str_to_color({it+1, facedesc.end()})
: Colors::Default }; : Colors::Default };
} }
const ColorPair& ColorRegistry::operator[](const String& colordesc) const Face& FaceRegistry::operator[](const String& facedesc)
{ {
auto it = m_aliases.find(colordesc); auto it = m_aliases.find(facedesc);
if (it != m_aliases.end()) if (it != m_aliases.end())
return it->second; return it->second;
return (m_aliases[colordesc] = parse_color_pair(colordesc)); return (m_aliases[facedesc] = parse_face(facedesc));
} }
void ColorRegistry::register_alias(const String& name, const String& colordesc, void FaceRegistry::register_alias(const String& name, const String& facedesc,
bool override) bool override)
{ {
if (not override and m_aliases.find(name) != m_aliases.end()) if (not override and m_aliases.find(name) != m_aliases.end())
@ -31,12 +31,12 @@ void ColorRegistry::register_alias(const String& name, const String& colordesc,
find_if(name, [](char c){ return not isalnum(c); }) != name.end()) find_if(name, [](char c){ return not isalnum(c); }) != name.end())
throw runtime_error("invalid alias name"); throw runtime_error("invalid alias name");
auto it = m_aliases.find(colordesc); auto it = m_aliases.find(facedesc);
m_aliases[name] = (it != m_aliases.end()) ? m_aliases[name] = (it != m_aliases.end()) ?
it->second : parse_color_pair(colordesc); it->second : parse_face(facedesc);
} }
CandidateList ColorRegistry::complete_alias_name(StringView prefix, CandidateList FaceRegistry::complete_alias_name(StringView prefix,
ByteCount cursor_pos) const ByteCount cursor_pos) const
{ {
CandidateList res; CandidateList res;
@ -49,7 +49,7 @@ CandidateList ColorRegistry::complete_alias_name(StringView prefix,
return res; return res;
} }
ColorRegistry::ColorRegistry() FaceRegistry::FaceRegistry()
: m_aliases{ : m_aliases{
{ "PrimarySelection", { Colors::Cyan, Colors::Blue } }, { "PrimarySelection", { Colors::Cyan, Colors::Blue } },
{ "SecondarySelection", { Colors::Black, Colors::Blue } }, { "SecondarySelection", { Colors::Black, Colors::Blue } },

36
src/face_registry.hh Normal file
View File

@ -0,0 +1,36 @@
#ifndef face_registry_hh_INCLUDED
#define face_registry_hh_INCLUDED
#include "face.hh"
#include "utils.hh"
#include "completion.hh"
#include <unordered_map>
namespace Kakoune
{
class FaceRegistry : public Singleton<FaceRegistry>
{
public:
FaceRegistry();
const Face& operator[](const String& facedesc);
void register_alias(const String& name, const String& facedesc,
bool override = false);
CandidateList complete_alias_name(StringView prefix,
ByteCount cursor_pos) const;
private:
std::unordered_map<String, Face> m_aliases;
};
inline const Face& get_face(const String& facedesc)
{
return FaceRegistry::instance()[facedesc];
}
}
#endif // face_registry_hh_INCLUDED

View File

@ -1,18 +1,18 @@
#include "highlighters.hh" #include "highlighters.hh"
#include "highlighter_group.hh"
#include "assert.hh" #include "assert.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "color_registry.hh"
#include "context.hh" #include "context.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "face_registry.hh"
#include "highlighter_group.hh"
#include "line_modification.hh" #include "line_modification.hh"
#include "option_types.hh" #include "option_types.hh"
#include "parameters_parser.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "string.hh" #include "string.hh"
#include "utf8.hh" #include "utf8.hh"
#include "utf8_iterator.hh" #include "utf8_iterator.hh"
#include "parameters_parser.hh"
#include <sstream> #include <sstream>
#include <locale> #include <locale>
@ -149,39 +149,41 @@ void apply_highlighter(const Context& context,
display_buffer.compute_range(); display_buffer.compute_range();
} }
auto apply_colors = [](const ColorPair& colors) auto apply_face = [](const Face& face)
{ {
return [&colors](DisplayAtom& atom) { return [&face](DisplayAtom& atom) {
if (colors.first != Colors::Default) if (face.fg != Colors::Default)
atom.colors.first = colors.first; atom.face.fg = face.fg;
if (colors.second != Colors::Default) if (face.bg != Colors::Default)
atom.colors.second = colors.second; atom.face.bg = face.bg;
if (face.attributes != Normal)
atom.face.attributes |= face.attributes;
}; };
}; };
using ColorSpec = std::unordered_map<size_t, const ColorPair*>; using FaceSpec = std::unordered_map<size_t, const Face*>;
struct Fill struct Fill
{ {
Fill(ColorPair colors) : m_colors(colors) {} Fill(Face face) : m_face(face) {}
void operator()(const Context& context, HighlightFlags flags, void operator()(const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer) DisplayBuffer& display_buffer)
{ {
auto range = display_buffer.range(); auto range = display_buffer.range();
highlight_range(display_buffer, range.first, range.second, true, highlight_range(display_buffer, range.first, range.second, true,
apply_colors(m_colors)); apply_face(m_face));
} }
ColorPair m_colors; Face m_face;
}; };
HighlighterAndId fill_factory(HighlighterParameters params) HighlighterAndId fill_factory(HighlighterParameters params)
{ {
if (params.size() != 1) if (params.size() != 1)
throw runtime_error("wrong parameter count"); throw runtime_error("wrong parameter count");
ColorPair colors = get_color(params[0]); Face face = get_face(params[0]);
return HighlighterAndId("fill_" + params[0], Fill(colors)); return HighlighterAndId("fill_" + params[0], Fill(face));
} }
template<typename T> template<typename T>
@ -203,8 +205,8 @@ private:
class RegexColorizer class RegexColorizer
{ {
public: public:
RegexColorizer(Regex regex, ColorSpec colors) RegexColorizer(Regex regex, FaceSpec faces)
: m_regex{std::move(regex)}, m_colors{std::move(colors)} : m_regex{std::move(regex)}, m_faces{std::move(faces)}
{ {
} }
@ -217,12 +219,12 @@ public:
{ {
for (size_t n = 0; n < match.size(); ++n) for (size_t n = 0; n < match.size(); ++n)
{ {
auto col_it = m_colors.find(n); auto face_it = m_faces.find(n);
if (col_it == m_colors.end()) if (face_it == m_faces.end())
continue; continue;
highlight_range(display_buffer, match[n].first, match[n].second, true, highlight_range(display_buffer, match[n].first, match[n].second, true,
apply_colors(*col_it->second)); apply_face(*face_it->second));
} }
} }
} }
@ -237,7 +239,7 @@ private:
BufferSideCache<Cache> m_cache; BufferSideCache<Cache> m_cache;
Regex m_regex; Regex m_regex;
ColorSpec m_colors; FaceSpec m_faces;
Cache& update_cache_ifn(const Buffer& buffer, const BufferRange& range) Cache& update_cache_ifn(const Buffer& buffer, const BufferRange& range)
{ {
@ -277,18 +279,18 @@ HighlighterAndId colorize_regex_factory(HighlighterParameters params)
try try
{ {
static Regex color_spec_ex(R"((\d+):(\w+(,\w+)?))"); static Regex face_spec_ex(R"((\d+):(\w+(,\w+)?))");
ColorSpec colors; FaceSpec faces;
for (auto it = params.begin() + 1; it != params.end(); ++it) for (auto it = params.begin() + 1; it != params.end(); ++it)
{ {
boost::smatch res; boost::smatch res;
if (not boost::regex_match(it->begin(), it->end(), res, color_spec_ex)) if (not boost::regex_match(it->begin(), it->end(), res, face_spec_ex))
throw runtime_error("wrong colorspec: '" + *it + throw runtime_error("wrong face spec: '" + *it +
"' expected <capture>:<fgcolor>[,<bgcolor>]"); "' expected <capture>:<fgcolor>[,<bgcolor>]");
int capture = str_to_int(res[1].str()); int capture = str_to_int(res[1].str());
const ColorPair*& color = colors[capture]; const Face*& face = faces[capture];
color = &get_color(res[2].str()); face = &get_face(res[2].str());
} }
String id = "colre'" + params[0] + "'"; String id = "colre'" + params[0] + "'";
@ -296,7 +298,7 @@ HighlighterAndId colorize_regex_factory(HighlighterParameters params)
Regex ex{params[0].begin(), params[0].end(), Regex::optimize}; Regex ex{params[0].begin(), params[0].end(), Regex::optimize};
return HighlighterAndId(id, RegexColorizer(std::move(ex), return HighlighterAndId(id, RegexColorizer(std::move(ex),
std::move(colors))); std::move(faces)));
} }
catch (boost::regex_error& err) catch (boost::regex_error& err)
{ {
@ -304,14 +306,14 @@ HighlighterAndId colorize_regex_factory(HighlighterParameters params)
} }
} }
template<typename RegexGetter, typename ColorGetter> template<typename RegexGetter, typename FaceGetter>
class DynamicRegexHighlighter class DynamicRegexHighlighter
{ {
public: public:
DynamicRegexHighlighter(RegexGetter regex_getter, ColorGetter color_getter) DynamicRegexHighlighter(RegexGetter regex_getter, FaceGetter face_getter)
: m_regex_getter(std::move(regex_getter)), : m_regex_getter(std::move(regex_getter)),
m_color_getter(std::move(color_getter)), m_face_getter(std::move(face_getter)),
m_colorizer(Regex(), ColorSpec{}) {} m_colorizer(Regex(), FaceSpec{}) {}
void operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) void operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
{ {
@ -319,34 +321,34 @@ public:
return; return;
Regex regex = m_regex_getter(context); Regex regex = m_regex_getter(context);
ColorSpec color = m_color_getter(context); FaceSpec face = m_face_getter(context);
if (regex != m_last_regex or color != m_last_color) if (regex != m_last_regex or face != m_last_face)
{ {
m_last_regex = regex; m_last_regex = regex;
m_last_color = color; m_last_face = face;
if (not m_last_regex.empty()) if (not m_last_regex.empty())
m_colorizer = RegexColorizer{m_last_regex, color}; m_colorizer = RegexColorizer{m_last_regex, face};
} }
if (not m_last_regex.empty() and not m_last_color.empty()) if (not m_last_regex.empty() and not m_last_face.empty())
m_colorizer(context, flags, display_buffer); m_colorizer(context, flags, display_buffer);
} }
private: private:
Regex m_last_regex; Regex m_last_regex;
RegexGetter m_regex_getter; RegexGetter m_regex_getter;
ColorSpec m_last_color; FaceSpec m_last_face;
ColorGetter m_color_getter; FaceGetter m_face_getter;
RegexColorizer m_colorizer; RegexColorizer m_colorizer;
}; };
template<typename RegexGetter, typename ColorGetter> template<typename RegexGetter, typename FaceGetter>
DynamicRegexHighlighter<RegexGetter, ColorGetter> DynamicRegexHighlighter<RegexGetter, FaceGetter>
make_dynamic_regex_highlighter(RegexGetter regex_getter, ColorGetter color_getter) make_dynamic_regex_highlighter(RegexGetter regex_getter, FaceGetter face_getter)
{ {
return DynamicRegexHighlighter<RegexGetter, ColorGetter>( return DynamicRegexHighlighter<RegexGetter, FaceGetter>(
std::move(regex_getter), std::move(color_getter)); std::move(regex_getter), std::move(face_getter));
} }
@ -354,8 +356,8 @@ HighlighterAndId highlight_search_factory(HighlighterParameters params)
{ {
if (params.size() != 0) if (params.size() != 0)
throw runtime_error("wrong parameter count"); throw runtime_error("wrong parameter count");
auto get_color = [](const Context& context){ auto get_face = [](const Context& context){
return ColorSpec{ { 0, &Kakoune::get_color("Search") } }; return FaceSpec{ { 0, &Kakoune::get_face("Search") } };
}; };
auto get_regex = [](const Context&){ auto get_regex = [](const Context&){
auto s = Context().main_sel_register_value("/"); auto s = Context().main_sel_register_value("/");
@ -368,7 +370,7 @@ HighlighterAndId highlight_search_factory(HighlighterParameters params)
return Regex{}; return Regex{};
} }
}; };
return {"hlsearch", make_dynamic_regex_highlighter(get_regex, get_color)}; return {"hlsearch", make_dynamic_regex_highlighter(get_regex, get_face)};
} }
HighlighterAndId highlight_regex_option_factory(HighlighterParameters params) HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
@ -376,9 +378,9 @@ HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
if (params.size() != 2) if (params.size() != 2)
throw runtime_error("wrong parameter count"); throw runtime_error("wrong parameter count");
const ColorPair& color = get_color(params[1]); const Face& face = get_face(params[1]);
auto get_color = [&](const Context&){ auto get_face = [&](const Context&){
return ColorSpec{ { 0, &color } }; return FaceSpec{ { 0, &face } };
}; };
String option_name = params[0]; String option_name = params[0];
@ -388,7 +390,7 @@ HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
auto get_regex = [option_name](const Context& context){ auto get_regex = [option_name](const Context& context){
return context.options()[option_name].get<Regex>(); return context.options()[option_name].get<Regex>();
}; };
return {"hloption_" + option_name, make_dynamic_regex_highlighter(get_regex, get_color)}; return {"hloption_" + option_name, make_dynamic_regex_highlighter(get_regex, get_face)};
} }
HighlighterAndId highlight_line_option_factory(HighlighterParameters params) HighlighterAndId highlight_line_option_factory(HighlighterParameters params)
@ -396,7 +398,7 @@ HighlighterAndId highlight_line_option_factory(HighlighterParameters params)
if (params.size() != 2) if (params.size() != 2)
throw runtime_error("wrong parameter count"); throw runtime_error("wrong parameter count");
const ColorPair& color = get_color(params[1]); const Face& face = get_face(params[1]);
String option_name = params[0]; String option_name = params[0];
// verify option type now // verify option type now
@ -407,7 +409,7 @@ HighlighterAndId highlight_line_option_factory(HighlighterParameters params)
{ {
int line = context.options()[option_name].get<int>(); int line = context.options()[option_name].get<int>();
highlight_range(display_buffer, {line-1, 0}, {line, 0}, false, highlight_range(display_buffer, {line-1, 0}, {line, 0}, false,
apply_colors(color)); apply_face(face));
}; };
return {"hlline_" + option_name, std::move(highlighter)}; return {"hlline_" + option_name, std::move(highlighter)};
@ -500,20 +502,20 @@ void show_line_numbers(const Context& context, HighlightFlags flags, DisplayBuff
char format[] = "%?d│"; char format[] = "%?d│";
format[1] = '0' + digit_count; format[1] = '0' + digit_count;
auto& colors = get_color("LineNumbers"); auto& face = get_face("LineNumbers");
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
char buffer[10]; char buffer[10];
snprintf(buffer, 10, format, (int)line.range().first.line + 1); snprintf(buffer, 10, format, (int)line.range().first.line + 1);
DisplayAtom atom{buffer}; DisplayAtom atom{buffer};
atom.colors = colors; atom.face = face;
line.insert(line.begin(), std::move(atom)); line.insert(line.begin(), std::move(atom));
} }
} }
void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
{ {
auto& colors = get_color("MatchingChar"); auto& face = get_face("MatchingChar");
using CodepointPair = std::pair<Codepoint, Codepoint>; using CodepointPair = std::pair<Codepoint, Codepoint>;
static const CodepointPair matching_chars[] = { { '(', ')' }, { '{', '}' }, { '[', ']' }, { '<', '>' } }; static const CodepointPair matching_chars[] = { { '(', ')' }, { '{', '}' }, { '[', ']' }, { '<', '>' } };
const auto range = display_buffer.range(); const auto range = display_buffer.range();
@ -540,7 +542,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
}); });
if (it != end) if (it != end)
highlight_range(display_buffer, it.coord(), (it+1).coord(), false, highlight_range(display_buffer, it.coord(), (it+1).coord(), false,
apply_colors(colors)); apply_face(face));
break; break;
} }
else if (c == pair.second and pos > range.first) else if (c == pair.second and pos > range.first)
@ -556,7 +558,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
}); });
if (it != end or (*end == pair.first and level == 1)) if (it != end or (*end == pair.first and level == 1))
highlight_range(display_buffer, it.coord(), (it+1).coord(), false, highlight_range(display_buffer, it.coord(), (it+1).coord(), false,
apply_colors(colors)); apply_face(face));
break; break;
} }
} }
@ -576,17 +578,17 @@ void highlight_selections(const Context& context, HighlightFlags flags, DisplayB
ByteCoord end = forward ? sel.cursor() : buffer.char_next(sel.anchor()); ByteCoord end = forward ? sel.cursor() : buffer.char_next(sel.anchor());
const bool primary = (i == context.selections().main_index()); const bool primary = (i == context.selections().main_index());
ColorPair sel_colors = get_color(primary ? "PrimarySelection" : "SecondarySelection"); Face sel_face = get_face(primary ? "PrimarySelection" : "SecondarySelection");
highlight_range(display_buffer, begin, end, false, highlight_range(display_buffer, begin, end, false,
apply_colors(sel_colors)); apply_face(sel_face));
} }
for (size_t i = 0; i < context.selections().size(); ++i) for (size_t i = 0; i < context.selections().size(); ++i)
{ {
auto& sel = context.selections()[i]; auto& sel = context.selections()[i];
const bool primary = (i == context.selections().main_index()); const bool primary = (i == context.selections().main_index());
ColorPair cur_colors = get_color(primary ? "PrimaryCursor" : "SecondaryCursor"); Face cur_face = get_face(primary ? "PrimaryCursor" : "SecondaryCursor");
highlight_range(display_buffer, sel.cursor(), buffer.char_next(sel.cursor()), false, highlight_range(display_buffer, sel.cursor(), buffer.char_next(sel.cursor()), false,
apply_colors(cur_colors)); apply_face(cur_face));
} }
} }
@ -614,7 +616,7 @@ void expand_unprintable(const Context& context, HighlightFlags flags, DisplayBuf
if (next.coord() < atom_it->end()) if (next.coord() < atom_it->end())
atom_it = line.split(atom_it, next.coord()); atom_it = line.split(atom_it, next.coord());
atom_it->replace(str); atom_it->replace(str);
atom_it->colors = { Colors::Red, Colors::Black }; atom_it->face = { Colors::Red, Colors::Black };
break; break;
} }
it = next; it = next;
@ -654,7 +656,7 @@ HighlighterAndId flag_lines_factory(HighlighterParameters params)
String content = it != lines.end() ? std::get<2>(*it) : empty; String content = it != lines.end() ? std::get<2>(*it) : empty;
content += String(' ', width - content.char_length()); content += String(' ', width - content.char_length());
DisplayAtom atom{std::move(content)}; DisplayAtom atom{std::move(content)};
atom.colors = { it != lines.end() ? std::get<1>(*it) : Colors::Default , bg }; atom.face = { it != lines.end() ? std::get<1>(*it) : Colors::Default , bg };
line.insert(line.begin(), std::move(atom)); line.insert(line.begin(), std::move(atom));
} }
}}; }};

View File

@ -3,8 +3,8 @@
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "client.hh" #include "client.hh"
#include "color_registry.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "face_registry.hh"
#include "insert_completer.hh" #include "insert_completer.hh"
#include "normal.hh" #include "normal.hh"
#include "register_manager.hh" #include "register_manager.hh"
@ -109,7 +109,7 @@ public:
{ {
if (context().options()["autoinfo"].get<int>() >= 2 and context().has_ui()) if (context().options()["autoinfo"].get<int>() >= 2 and context().has_ui())
{ {
ColorPair col = get_color("Information"); Face col = get_face("Information");
CharCoord pos = context().window().dimensions(); CharCoord pos = context().window().dimensions();
pos.column -= 1; pos.column -= 1;
context().ui().info_show(key_to_str(key), it->second.docstring, pos, col, MenuStyle::Prompt); context().ui().info_show(key_to_str(key), it->second.docstring, pos, col, MenuStyle::Prompt);
@ -212,12 +212,12 @@ public:
m_display_pos = m_cursor_pos + 1 - width; m_display_pos = m_cursor_pos + 1 - width;
if (m_cursor_pos == m_line.char_length()) if (m_cursor_pos == m_line.char_length())
return DisplayLine{{ {m_line.substr(m_display_pos, width-1), get_color("StatusLine")}, return DisplayLine{{ {m_line.substr(m_display_pos, width-1), get_face("StatusLine")},
{" "_str, get_color("StatusCursor")} }}; {" "_str, get_face("StatusCursor")} }};
else else
return DisplayLine({ { m_line.substr(m_display_pos, m_cursor_pos - m_display_pos), get_color("StatusLine") }, return DisplayLine({ { m_line.substr(m_display_pos, m_cursor_pos - m_display_pos), get_face("StatusLine") },
{ m_line.substr(m_cursor_pos,1), get_color("StatusCursor") }, { m_line.substr(m_cursor_pos,1), get_face("StatusCursor") },
{ m_line.substr(m_cursor_pos+1, width - m_cursor_pos + m_display_pos - 1), get_color("StatusLine") } }); { m_line.substr(m_cursor_pos+1, width - m_cursor_pos + m_display_pos - 1), get_face("StatusLine") } });
} }
private: private:
CharCount m_cursor_pos = 0; CharCount m_cursor_pos = 0;
@ -237,8 +237,8 @@ public:
if (not context().has_ui()) if (not context().has_ui())
return; return;
CharCoord menu_pos{ context().ui().dimensions().line, 0_char }; CharCoord menu_pos{ context().ui().dimensions().line, 0_char };
context().ui().menu_show(choices, menu_pos, get_color("MenuForeground"), context().ui().menu_show(choices, menu_pos, get_face("MenuForeground"),
get_color("MenuBackground"), MenuStyle::Prompt); get_face("MenuBackground"), MenuStyle::Prompt);
context().ui().menu_select(0); context().ui().menu_select(0);
} }
@ -314,7 +314,7 @@ public:
auto prompt = "filter:"_str; auto prompt = "filter:"_str;
auto width = context().ui().dimensions().column - prompt.char_length(); auto width = context().ui().dimensions().column - prompt.char_length();
auto display_line = m_filter_editor.build_display_line(width); auto display_line = m_filter_editor.build_display_line(width);
display_line.insert(display_line.begin(), { prompt, get_color("Prompt") }); display_line.insert(display_line.begin(), { prompt, get_face("Prompt") });
context().print_status(display_line); context().print_status(display_line);
} }
} }
@ -381,9 +381,9 @@ class Prompt : public InputMode
{ {
public: public:
Prompt(InputHandler& input_handler, const String& prompt, Prompt(InputHandler& input_handler, const String& prompt,
String initstr, ColorPair colors, Completer completer, String initstr, Face face, Completer completer,
PromptCallback callback) PromptCallback callback)
: InputMode(input_handler), m_prompt(prompt), m_prompt_colors(colors), : InputMode(input_handler), m_prompt(prompt), m_prompt_face(face),
m_completer(completer), m_callback(callback) m_completer(completer), m_callback(callback)
{ {
m_history_it = ms_history[m_prompt].end(); m_history_it = ms_history[m_prompt].end();
@ -554,11 +554,11 @@ public:
m_callback(line, PromptEvent::Change, context()); m_callback(line, PromptEvent::Change, context());
} }
void set_prompt_colors(ColorPair colors) void set_prompt_face(Face face)
{ {
if (colors != m_prompt_colors) if (face != m_prompt_face)
{ {
m_prompt_colors = colors; m_prompt_face = face;
display(); display();
} }
} }
@ -585,8 +585,8 @@ private:
if (context().has_ui() and not candidates.empty()) if (context().has_ui() and not candidates.empty())
{ {
CharCoord menu_pos{ context().ui().dimensions().line, 0_char }; CharCoord menu_pos{ context().ui().dimensions().line, 0_char };
context().ui().menu_show(candidates, menu_pos, get_color("MenuForeground"), context().ui().menu_show(candidates, menu_pos, get_face("MenuForeground"),
get_color("MenuBackground"), MenuStyle::Prompt); get_face("MenuBackground"), MenuStyle::Prompt);
} }
} catch (runtime_error&) {} } catch (runtime_error&) {}
} }
@ -605,7 +605,7 @@ private:
auto width = context().ui().dimensions().column - m_prompt.char_length(); auto width = context().ui().dimensions().column - m_prompt.char_length();
auto display_line = m_line_editor.build_display_line(width); auto display_line = m_line_editor.build_display_line(width);
display_line.insert(display_line.begin(), { m_prompt, m_prompt_colors }); display_line.insert(display_line.begin(), { m_prompt, m_prompt_face });
context().print_status(display_line); context().print_status(display_line);
} }
@ -614,7 +614,7 @@ private:
PromptCallback m_callback; PromptCallback m_callback;
Completer m_completer; Completer m_completer;
const String m_prompt; const String m_prompt;
ColorPair m_prompt_colors; Face m_prompt_face;
Completions m_completions; Completions m_completions;
int m_current_completion = -1; int m_current_completion = -1;
String m_prefix; String m_prefix;
@ -939,19 +939,19 @@ void InputHandler::repeat_last_insert()
} }
void InputHandler::prompt(const String& prompt, String initstr, void InputHandler::prompt(const String& prompt, String initstr,
ColorPair prompt_colors, Completer completer, Face prompt_face, Completer completer,
PromptCallback callback) PromptCallback callback)
{ {
change_input_mode(new InputModes::Prompt(*this, prompt, initstr, change_input_mode(new InputModes::Prompt(*this, prompt, initstr,
prompt_colors, completer, prompt_face, completer,
callback)); callback));
} }
void InputHandler::set_prompt_colors(ColorPair prompt_colors) void InputHandler::set_prompt_face(Face prompt_face)
{ {
InputModes::Prompt* prompt = dynamic_cast<InputModes::Prompt*>(m_mode.get()); InputModes::Prompt* prompt = dynamic_cast<InputModes::Prompt*>(m_mode.get());
if (prompt) if (prompt)
prompt->set_prompt_colors(prompt_colors); prompt->set_prompt_face(prompt_face);
} }
void InputHandler::menu(memoryview<String> choices, void InputHandler::menu(memoryview<String> choices,

View File

@ -1,9 +1,9 @@
#ifndef input_handler_hh_INCLUDED #ifndef input_handler_hh_INCLUDED
#define input_handler_hh_INCLUDED #define input_handler_hh_INCLUDED
#include "color.hh"
#include "completion.hh" #include "completion.hh"
#include "context.hh" #include "context.hh"
#include "face.hh"
#include "normal.hh" #include "normal.hh"
#include "keys.hh" #include "keys.hh"
#include "string.hh" #include "string.hh"
@ -48,16 +48,15 @@ public:
// returns to normal mode after validation if callback does // returns to normal mode after validation if callback does
// not change the mode itself // not change the mode itself
void prompt(const String& prompt, String initstr, void prompt(const String& prompt, String initstr,
ColorPair prompt_colors, Completer completer, Face prompt_face, Completer completer,
PromptCallback callback); PromptCallback callback);
void set_prompt_colors(ColorPair prompt_colors); void set_prompt_face(Face prompt_face);
// enter menu mode, callback is called on each selection change, // enter menu mode, callback is called on each selection change,
// abort or validation with corresponding MenuEvent value // abort or validation with corresponding MenuEvent value
// returns to normal mode after validation if callback does // returns to normal mode after validation if callback does
// not change the mode itself // not change the mode itself
void menu(memoryview<String> choices, void menu(memoryview<String> choices, MenuCallback callback);
MenuCallback callback);
// execute callback on next keypress and returns to normal mode // execute callback on next keypress and returns to normal mode
// if callback does not change the mode itself // if callback does not change the mode itself

View File

@ -2,10 +2,10 @@
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "color_registry.hh"
#include "context.hh" #include "context.hh"
#include "debug.hh" #include "debug.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "user_interface.hh" #include "user_interface.hh"
#include "window.hh" #include "window.hh"
@ -314,8 +314,8 @@ void InsertCompleter::menu_show()
menu_entries.push_back(expand_tabs(candidate, tabstop, column)); menu_entries.push_back(expand_tabs(candidate, tabstop, column));
m_context.ui().menu_show(menu_entries, menu_pos, m_context.ui().menu_show(menu_entries, menu_pos,
get_color("MenuForeground"), get_face("MenuForeground"),
get_color("MenuBackground"), get_face("MenuBackground"),
MenuStyle::Inline); MenuStyle::Inline);
m_context.ui().menu_select(m_current_candidate); m_context.ui().menu_select(m_current_candidate);
} }

View File

@ -3,18 +3,18 @@
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "client_manager.hh" #include "client_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh" #include "command_manager.hh"
#include "commands.hh" #include "commands.hh"
#include "context.hh" #include "context.hh"
#include "debug.hh" #include "debug.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "highlighters.hh" #include "highlighters.hh"
#include "hook_manager.hh" #include "hook_manager.hh"
#include "keymap_manager.hh"
#include "ncurses.hh" #include "ncurses.hh"
#include "option_manager.hh" #include "option_manager.hh"
#include "keymap_manager.hh"
#include "parameters_parser.hh" #include "parameters_parser.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "remote.hh" #include "remote.hh"
@ -363,7 +363,7 @@ int kakoune(const ParametersParser& parser)
RegisterManager register_manager; RegisterManager register_manager;
HighlighterRegistry highlighter_registry; HighlighterRegistry highlighter_registry;
DefinedHighlighters defined_highlighters; DefinedHighlighters defined_highlighters;
ColorRegistry color_registry; FaceRegistry face_registry;
ClientManager client_manager; ClientManager client_manager;
run_unit_tests(); run_unit_tests();

View File

@ -165,34 +165,41 @@ static int nc_color(Color color)
} }
} }
static int get_color_pair(ColorPair colors) static int get_color_pair(const Face& face)
{ {
using ColorPair = std::pair<Color, Color>;
static std::map<ColorPair, int> colorpairs; static std::map<ColorPair, int> colorpairs;
static int next_pair = 1; static int next_pair = 1;
ColorPair colors{face.fg, face.bg};
auto it = colorpairs.find(colors); auto it = colorpairs.find(colors);
if (it != colorpairs.end()) if (it != colorpairs.end())
return it->second; return it->second;
else else
{ {
init_pair(next_pair, nc_color(colors.first), nc_color(colors.second)); init_pair(next_pair, nc_color(face.fg), nc_color(face.bg));
colorpairs[colors] = next_pair; colorpairs[colors] = next_pair;
return next_pair++; return next_pair++;
} }
} }
static void set_color(WINDOW* window, ColorPair colors) static void set_face(WINDOW* window, Face face)
{ {
static int current_pair = -1; static int current_pair = -1;
if (current_pair != -1) if (current_pair != -1)
wattroff(window, COLOR_PAIR(current_pair)); wattroff(window, COLOR_PAIR(current_pair));
if (colors.first != Colors::Default or colors.second != Colors::Default) if (face.fg != Colors::Default or face.bg != Colors::Default)
{ {
current_pair = get_color_pair(colors); current_pair = get_color_pair(face);
wattron(window, COLOR_PAIR(current_pair)); wattron(window, COLOR_PAIR(current_pair));
} }
set_attribute(A_UNDERLINE, face.attributes & Underline);
set_attribute(A_REVERSE, face.attributes & Reverse);
set_attribute(A_BLINK, face.attributes & Blink);
set_attribute(A_BOLD, face.attributes & Bold);
} }
static sig_atomic_t resize_pending = 0; static sig_atomic_t resize_pending = 0;
@ -293,12 +300,7 @@ void NCursesUI::draw_line(const DisplayLine& line, CharCount col_index) const
{ {
for (const DisplayAtom& atom : line) for (const DisplayAtom& atom : line)
{ {
set_attribute(A_UNDERLINE, atom.attribute & Underline); set_face(stdscr, atom.face);
set_attribute(A_REVERSE, atom.attribute & Reverse);
set_attribute(A_BLINK, atom.attribute & Blink);
set_attribute(A_BOLD, atom.attribute & Bold);
set_color(stdscr, atom.colors);
StringView content = atom.content(); StringView content = atom.content();
if (content.empty()) if (content.empty())
@ -337,11 +339,7 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer,
++line_index; ++line_index;
} }
set_attribute(A_UNDERLINE, 0); set_face(stdscr, { Colors::Blue, Colors::Default });
set_attribute(A_REVERSE, 0);
set_attribute(A_BLINK, 0);
set_attribute(A_BOLD, 0);
set_color(stdscr, { Colors::Blue, Colors::Default });
for (;line_index < m_dimensions.line; ++line_index) for (;line_index < m_dimensions.line; ++line_index)
{ {
move((int)line_index, 0); move((int)line_index, 0);
@ -532,7 +530,7 @@ void NCursesUI::draw_menu()
} }
void NCursesUI::menu_show(memoryview<String> items, void NCursesUI::menu_show(memoryview<String> items,
CharCoord anchor, ColorPair fg, ColorPair bg, CharCoord anchor, Face fg, Face bg,
MenuStyle style) MenuStyle style)
{ {
if (m_menu_win) if (m_menu_win)
@ -768,8 +766,7 @@ static String make_info_box(StringView title, StringView message,
} }
void NCursesUI::info_show(StringView title, StringView content, void NCursesUI::info_show(StringView title, StringView content,
CharCoord anchor, ColorPair colors, CharCoord anchor, Face face, MenuStyle style)
MenuStyle style)
{ {
if (m_info_win) if (m_info_win)
{ {
@ -793,7 +790,7 @@ void NCursesUI::info_show(StringView title, StringView content,
m_info_win = (NCursesWin*)newwin((int)size.line, (int)size.column, m_info_win = (NCursesWin*)newwin((int)size.line, (int)size.column,
(int)pos.line, (int)pos.column); (int)pos.line, (int)pos.column);
wbkgd(m_info_win, COLOR_PAIR(get_color_pair(colors))); wbkgd(m_info_win, COLOR_PAIR(get_color_pair(face)));
int line = 0; int line = 0;
auto it = info_box.begin(), end = info_box.end(); auto it = info_box.begin(), end = info_box.end();
while (true) while (true)

View File

@ -27,13 +27,13 @@ public:
Key get_key() override; Key get_key() override;
void menu_show(memoryview<String> items, void menu_show(memoryview<String> items,
CharCoord anchor, ColorPair fg, ColorPair bg, CharCoord anchor, Face fg, Face bg,
MenuStyle style) override; MenuStyle style) override;
void menu_select(int selected) override; void menu_select(int selected) override;
void menu_hide() override; void menu_hide() override;
void info_show(StringView title, StringView content, void info_show(StringView title, StringView content,
CharCoord anchor, ColorPair colors, CharCoord anchor, Face face,
MenuStyle style) override; MenuStyle style) override;
void info_hide() override; void info_hide() override;
@ -54,8 +54,8 @@ private:
NCursesWin* m_menu_win = nullptr; NCursesWin* m_menu_win = nullptr;
std::vector<String> m_items; std::vector<String> m_items;
ColorPair m_menu_fg; Face m_menu_fg;
ColorPair m_menu_bg; Face m_menu_bg;
int m_selected_item = 0; int m_selected_item = 0;
int m_menu_columns = 1; int m_menu_columns = 1;
LineCount m_menu_top_line = 0; LineCount m_menu_top_line = 0;

View File

@ -3,19 +3,19 @@
#include "buffer.hh" #include "buffer.hh"
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "client_manager.hh" #include "client_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh" #include "command_manager.hh"
#include "commands.hh" #include "commands.hh"
#include "context.hh" #include "context.hh"
#include "debug.hh"
#include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "option_manager.hh" #include "option_manager.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "selectors.hh" #include "selectors.hh"
#include "shell_manager.hh" #include "shell_manager.hh"
#include "string.hh" #include "string.hh"
#include "window.hh"
#include "user_interface.hh" #include "user_interface.hh"
#include "debug.hh" #include "window.hh"
namespace Kakoune namespace Kakoune
{ {
@ -109,10 +109,10 @@ bool show_auto_info_ifn(const String& title, const String& info,
{ {
if (context.options()["autoinfo"].get<int>() < 1 or not context.has_ui()) if (context.options()["autoinfo"].get<int>() < 1 or not context.has_ui())
return false; return false;
ColorPair col = get_color("Information"); Face face = get_face("Information");
CharCoord pos = context.window().dimensions(); CharCoord pos = context.window().dimensions();
pos.column -= 1; pos.column -= 1;
context.ui().info_show(title, info, pos , col, MenuStyle::Prompt); context.ui().info_show(title, info, pos , face, MenuStyle::Prompt);
return true; return true;
} }
@ -342,7 +342,7 @@ void for_each_char(Context& context, int)
void command(Context& context, int) void command(Context& context, int)
{ {
context.input_handler().prompt( context.input_handler().prompt(
":", "", get_color("Prompt"), ":", "", get_face("Prompt"),
std::bind(&CommandManager::complete, &CommandManager::instance(), _1, _2, _3, _4), std::bind(&CommandManager::complete, &CommandManager::instance(), _1, _2, _3, _4),
[](const String& cmdline, PromptEvent event, Context& context) { [](const String& cmdline, PromptEvent event, Context& context) {
if (context.has_ui()) if (context.has_ui())
@ -351,7 +351,7 @@ void command(Context& context, int)
if (event == PromptEvent::Change and context.options()["autoinfo"].get<int>() > 0) if (event == PromptEvent::Change and context.options()["autoinfo"].get<int>() > 0)
{ {
auto info = CommandManager::instance().command_info(cmdline); auto info = CommandManager::instance().command_info(cmdline);
ColorPair col = get_color("Information"); Face col = get_face("Information");
CharCoord pos = context.window().dimensions(); CharCoord pos = context.window().dimensions();
pos.column -= 1; pos.column -= 1;
if (not info.first.empty() and not info.second.empty()) if (not info.first.empty() and not info.second.empty())
@ -367,7 +367,7 @@ template<InsertMode mode>
void pipe(Context& context, int) void pipe(Context& context, int)
{ {
const char* prompt = mode == InsertMode::Replace ? "pipe:" : "pipe (ins):"; const char* prompt = mode == InsertMode::Replace ? "pipe:" : "pipe (ins):";
context.input_handler().prompt(prompt, "", get_color("Prompt"), shell_complete, context.input_handler().prompt(prompt, "", get_face("Prompt"), shell_complete,
[](const String& cmdline, PromptEvent event, Context& context) [](const String& cmdline, PromptEvent event, Context& context)
{ {
if (event != PromptEvent::Validate) if (event != PromptEvent::Validate)
@ -431,7 +431,7 @@ void yank(Context& context, int)
{ {
RegisterManager::instance()['"'] = context.selections_content(); RegisterManager::instance()['"'] = context.selections_content();
context.print_status({ "yanked " + to_string(context.selections().size()) + context.print_status({ "yanked " + to_string(context.selections().size()) +
" selections", get_color("Information") }); " selections", get_face("Information") });
} }
void erase_selections(Context& context, int) void erase_selections(Context& context, int)
@ -515,7 +515,7 @@ template<typename T>
void regex_prompt(Context& context, const String prompt, T func) void regex_prompt(Context& context, const String prompt, T func)
{ {
SelectionList selections = context.selections(); SelectionList selections = context.selections();
context.input_handler().prompt(prompt, "", get_color("Prompt"), complete_nothing, context.input_handler().prompt(prompt, "", get_face("Prompt"), complete_nothing,
[=](const String& str, PromptEvent event, Context& context) mutable { [=](const String& str, PromptEvent event, Context& context) mutable {
try try
{ {
@ -523,7 +523,7 @@ void regex_prompt(Context& context, const String prompt, T func)
context.ui().info_hide(); context.ui().info_hide();
selections.update(); selections.update();
context.selections() = selections; context.selections() = selections;
context.input_handler().set_prompt_colors(get_color("Prompt")); context.input_handler().set_prompt_face(get_face("Prompt"));
if (event == PromptEvent::Abort) if (event == PromptEvent::Abort)
return; return;
if (event == PromptEvent::Change and if (event == PromptEvent::Change and
@ -539,7 +539,7 @@ void regex_prompt(Context& context, const String prompt, T func)
if (event == PromptEvent::Validate) if (event == PromptEvent::Validate)
throw runtime_error("regex error: "_str + err.what()); throw runtime_error("regex error: "_str + err.what());
else else
context.input_handler().set_prompt_colors(get_color("Error")); context.input_handler().set_prompt_face(get_face("Error"));
} }
catch (std::runtime_error& err) catch (std::runtime_error& err)
{ {
@ -547,13 +547,13 @@ void regex_prompt(Context& context, const String prompt, T func)
throw runtime_error("regex error: "_str + err.what()); throw runtime_error("regex error: "_str + err.what());
else else
{ {
context.input_handler().set_prompt_colors(get_color("Error")); context.input_handler().set_prompt_face(get_face("Error"));
if (context.has_ui()) if (context.has_ui())
{ {
ColorPair col = get_color("Information"); Face face = get_face("Information");
CharCoord pos = context.window().dimensions(); CharCoord pos = context.window().dimensions();
pos.column -= 1; pos.column -= 1;
context.ui().info_show("regex error", err.what(), pos, col, MenuStyle::Prompt); context.ui().info_show("regex error", err.what(), pos, face, MenuStyle::Prompt);
} }
} }
} }
@ -731,7 +731,7 @@ void keep(Context& context, int)
void keep_pipe(Context& context, int) void keep_pipe(Context& context, int)
{ {
context.input_handler().prompt( context.input_handler().prompt(
"keep pipe:", "", get_color("Prompt"), shell_complete, "keep pipe:", "", get_face("Prompt"), shell_complete,
[](const String& cmdline, PromptEvent event, Context& context) { [](const String& cmdline, PromptEvent event, Context& context) {
if (event != PromptEvent::Validate) if (event != PromptEvent::Validate)
return; return;
@ -1012,7 +1012,7 @@ void save_selections(Context& context, int)
{ {
context.push_jump(); context.push_jump();
context.print_status({ "saved " + to_string(context.selections().size()) + context.print_status({ "saved " + to_string(context.selections().size()) +
" selections", get_color("Information") }); " selections", get_face("Information") });
} }
void align(Context& context, int) void align(Context& context, int)
@ -1171,7 +1171,7 @@ void undo(Context& context, int)
context.set_selections(std::move(ranges)); context.set_selections(std::move(ranges));
} }
else if (not res) else if (not res)
context.print_status({ "nothing left to undo", get_color("Information") }); context.print_status({ "nothing left to undo", get_face("Information") });
} }
void redo(Context& context, int) void redo(Context& context, int)
@ -1188,7 +1188,7 @@ void redo(Context& context, int)
} }
else if (not res) else if (not res)
context.print_status({ "nothing left to redo", get_color("Information") }); context.print_status({ "nothing left to redo", get_face("Information") });
} }
template<typename T> template<typename T>

View File

@ -102,17 +102,17 @@ public:
} }
} }
void write(ColorPair colors) void write(Face face)
{ {
write(colors.first); write(face.fg);
write(colors.second); write(face.bg);
write(face.attributes);
} }
void write(const DisplayAtom& atom) void write(const DisplayAtom& atom)
{ {
write(atom.content()); write(atom.content());
write(atom.colors); write(atom.face);
write(atom.attribute);
} }
void write(const DisplayLine& line) void write(const DisplayLine& line)
@ -198,11 +198,12 @@ Color read<Color>(int socket)
} }
template<> template<>
ColorPair read<ColorPair>(int socket) Face read<Face>(int socket)
{ {
ColorPair res; Face res;
res.first = read<Color>(socket); res.fg = read<Color>(socket);
res.second = read<Color>(socket); res.bg = read<Color>(socket);
res.attributes = read<Attribute>(socket);
return res; return res;
} }
@ -210,8 +211,7 @@ template<>
DisplayAtom read<DisplayAtom>(int socket) DisplayAtom read<DisplayAtom>(int socket)
{ {
DisplayAtom atom(read<String>(socket)); DisplayAtom atom(read<String>(socket));
atom.colors = read<ColorPair>(socket); atom.face = read<Face>(socket);
atom.attribute = read<Attribute>(socket);
return atom; return atom;
} }
template<> template<>
@ -249,13 +249,13 @@ public:
~RemoteUI(); ~RemoteUI();
void menu_show(memoryview<String> choices, void menu_show(memoryview<String> choices,
CharCoord anchor, ColorPair fg, ColorPair bg, CharCoord anchor, Face fg, Face bg,
MenuStyle style) override; MenuStyle style) override;
void menu_select(int selected) override; void menu_select(int selected) override;
void menu_hide() override; void menu_hide() override;
void info_show(StringView title, StringView content, void info_show(StringView title, StringView content,
CharCoord anchor, ColorPair colors, CharCoord anchor, Face face,
MenuStyle style) override; MenuStyle style) override;
void info_hide() override; void info_hide() override;
@ -296,7 +296,7 @@ RemoteUI::~RemoteUI()
} }
void RemoteUI::menu_show(memoryview<String> choices, void RemoteUI::menu_show(memoryview<String> choices,
CharCoord anchor, ColorPair fg, ColorPair bg, CharCoord anchor, Face fg, Face bg,
MenuStyle style) MenuStyle style)
{ {
Message msg(m_socket_watcher.fd()); Message msg(m_socket_watcher.fd());
@ -322,7 +322,7 @@ void RemoteUI::menu_hide()
} }
void RemoteUI::info_show(StringView title, StringView content, void RemoteUI::info_show(StringView title, StringView content,
CharCoord anchor, ColorPair colors, CharCoord anchor, Face face,
MenuStyle style) MenuStyle style)
{ {
Message msg(m_socket_watcher.fd()); Message msg(m_socket_watcher.fd());
@ -330,7 +330,7 @@ void RemoteUI::info_show(StringView title, StringView content,
msg.write(title); msg.write(title);
msg.write(content); msg.write(content);
msg.write(anchor); msg.write(anchor);
msg.write(colors); msg.write(face);
msg.write(style); msg.write(style);
} }
@ -448,8 +448,8 @@ void RemoteClient::process_next_message()
{ {
auto choices = read_vector<String>(socket); auto choices = read_vector<String>(socket);
auto anchor = read<CharCoord>(socket); auto anchor = read<CharCoord>(socket);
auto fg = read<ColorPair>(socket); auto fg = read<Face>(socket);
auto bg = read<ColorPair>(socket); auto bg = read<Face>(socket);
auto style = read<MenuStyle>(socket); auto style = read<MenuStyle>(socket);
m_ui->menu_show(choices, anchor, fg, bg, style); m_ui->menu_show(choices, anchor, fg, bg, style);
break; break;
@ -465,9 +465,9 @@ void RemoteClient::process_next_message()
auto title = read<String>(socket); auto title = read<String>(socket);
auto content = read<String>(socket); auto content = read<String>(socket);
auto anchor = read<CharCoord>(socket); auto anchor = read<CharCoord>(socket);
auto colors = read<ColorPair>(socket); auto face = read<Face>(socket);
auto style = read<MenuStyle>(socket); auto style = read<MenuStyle>(socket);
m_ui->info_show(title, content, anchor, colors, style); m_ui->info_show(title, content, anchor, face, style);
break; break;
} }
case RemoteUIMsg::InfoHide: case RemoteUIMsg::InfoHide:

View File

@ -28,13 +28,13 @@ public:
virtual ~UserInterface() {} virtual ~UserInterface() {}
virtual void menu_show(memoryview<String> choices, virtual void menu_show(memoryview<String> choices,
CharCoord anchor, ColorPair fg, ColorPair bg, CharCoord anchor, Face fg, Face bg,
MenuStyle style) = 0; MenuStyle style) = 0;
virtual void menu_select(int selected) = 0; virtual void menu_select(int selected) = 0;
virtual void menu_hide() = 0; virtual void menu_hide() = 0;
virtual void info_show(StringView title, StringView content, virtual void info_show(StringView title, StringView content,
CharCoord anchor, ColorPair colors, CharCoord anchor, Face face,
MenuStyle style) = 0; MenuStyle style) = 0;
virtual void info_hide() = 0; virtual void info_hide() = 0;