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 "color_registry.hh"
#include "face_registry.hh"
#include "context.hh"
#include "buffer_manager.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);
DisplayLine status;
ColorPair info_color = get_color("Information");
ColorPair status_color = get_color("StatusLine");
ColorPair prompt_color = get_color("Prompt");
Face info_face = get_face("Information");
Face status_face = get_face("StatusLine");
Face prompt_face = get_face("Prompt");
status.push_back({ context().buffer().display_name(), status_color });
status.push_back({ " " + to_string((int)pos.line+1) + ":" + to_string((int)col+1) + " ", 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_face });
if (context().buffer().is_modified())
status.push_back({ "[+]", info_color });
status.push_back({ "[+]", info_face });
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)
status.push_back({ "[new file]", info_color });
status.push_back({ "[new file]", info_face });
if (context().buffer().flags() & Buffer::Flags::Fifo)
status.push_back({ "[fifo]", info_color });
status.push_back({ " ", status_color });
status.push_back({ m_input_handler.mode_string(), prompt_color });
status.push_back({ " - " + context().name() + "@[" + Server::instance().session() + "]", status_color });
status.push_back({ "[fifo]", info_face });
status.push_back({ " ", status_face });
status.push_back({ m_input_handler.mode_string(), prompt_face });
status.push_back({ " - " + context().name() + "@[" + Server::instance().session() + "]", status_face });
return status;
}
@ -118,7 +118,7 @@ static void reload_buffer(Context& context, const String& filename)
context.selections() = SelectionList{ *buf, buf->clamp(cursor_pos)};
context.window().set_position(view_pos);
context.print_status({ "'" + buf->display_name() + "' reloaded",
get_color("Information") });
get_face("Information") });
}
void Client::check_buffer_fs_timestamp()
@ -140,7 +140,7 @@ void Client::check_buffer_fs_timestamp()
"reload '" + buffer.display_name() + "' ?",
"'" + buffer.display_name() + "' was modified externally\n"
"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) {
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
@ -154,12 +154,12 @@ void Client::check_buffer_fs_timestamp()
{
buf->set_fs_timestamp(ts);
print_status({ "'" + buf->display_name() + "' kept",
get_color("Information") });
get_face("Information") });
}
else
{
print_status({ "'" + key_to_str(key) + "' is not a valid choice",
get_color("Error") });
get_face("Error") });
check_buffer_fs_timestamp();
}
});

View File

@ -1,9 +1,9 @@
#include "client_manager.hh"
#include "buffer_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh"
#include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh"
#include "user_interface.hh"
#include "window.hh"
@ -40,7 +40,7 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
}
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());
}
@ -57,7 +57,7 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
}
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());
}

View File

@ -40,8 +40,6 @@ struct Color
{ 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);
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 "client.hh"
#include "client_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh"
#include "completion.hh"
#include "context.hh"
#include "debug.hh"
#include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh"
#include "highlighter.hh"
#include "highlighters.hh"
@ -39,7 +39,7 @@ Buffer* open_or_create(const String& filename, Context& context)
Buffer* buffer = create_buffer_from_file(filename);
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);
}
return buffer;
@ -720,9 +720,9 @@ const CommandDesc echo_cmd = {
write_debug(message);
else
{
auto color = get_color(parser.has_option("color") ?
auto face = get_face(parser.has_option("color") ?
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");
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)
{
if (event != PromptEvent::Validate)
@ -1209,7 +1209,7 @@ const CommandDesc info_cmd = {
pos = context.window().display_position(it);
}
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)
{
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 = {
@ -1261,7 +1261,7 @@ const CommandDesc define_color_alias_cmd = {
PerArgumentCommandCompleter({ complete_colalias, complete_colalias }),
[](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;
bool merged = false;
if (atom.colors == next_atom.colors and
atom.attribute == next_atom.attribute and
if (atom.face == next_atom.face and
atom.type() == next_atom.type())
{
auto type = atom.type();

View File

@ -2,7 +2,7 @@
#define display_buffer_hh_INCLUDED
#include "buffer.hh"
#include "color.hh"
#include "face.hh"
#include "coord.hh"
#include "string.hh"
#include "utf8.hh"
@ -12,17 +12,6 @@
namespace Kakoune
{
using Attribute = char;
enum Attributes
{
Normal = 0,
Underline = 1,
Reverse = 2,
Blink = 4,
Bold = 8
};
struct DisplayAtom
{
public:
@ -32,9 +21,8 @@ public:
: m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end)
{ check_invariant(); }
DisplayAtom(String str, ColorPair colors = { Colors::Default, Colors::Default },
Attribute attribute = Normal)
: m_type(Text), m_text(std::move(str)), colors(colors), attribute(attribute)
DisplayAtom(String str, Face face = Face{})
: m_type(Text), m_text(std::move(str)), face(face)
{ check_invariant(); }
StringView content() const
@ -108,13 +96,11 @@ public:
bool operator==(const DisplayAtom& other) const
{
return colors == other.colors or attribute == other.attribute or
content() == other.content();
return face == other.face and content() == other.content();
}
public:
ColorPair colors = {Colors::Default, Colors::Default};
Attribute attribute = Normal;
Face face;
private:
friend class DisplayLine;
@ -139,8 +125,8 @@ public:
DisplayLine() = default;
DisplayLine(AtomList atoms);
DisplayLine(String str, ColorPair color)
{ push_back({ std::move(str), color }); }
DisplayLine(String str, Face face)
{ push_back({ std::move(str), face }); }
iterator begin() { return m_atoms.begin(); }
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"
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(), ',');
return { str_to_color({colordesc.begin(), it}),
it != colordesc.end() ? str_to_color({it+1, colordesc.end()})
auto it = std::find(facedesc.begin(), facedesc.end(), ',');
return { str_to_color({facedesc.begin(), it}),
it != facedesc.end() ? str_to_color({it+1, facedesc.end()})
: 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())
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)
{
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())
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()) ?
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
{
CandidateList res;
@ -49,7 +49,7 @@ CandidateList ColorRegistry::complete_alias_name(StringView prefix,
return res;
}
ColorRegistry::ColorRegistry()
FaceRegistry::FaceRegistry()
: m_aliases{
{ "PrimarySelection", { Colors::Cyan, 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 "highlighter_group.hh"
#include "assert.hh"
#include "buffer_utils.hh"
#include "color_registry.hh"
#include "context.hh"
#include "display_buffer.hh"
#include "face_registry.hh"
#include "highlighter_group.hh"
#include "line_modification.hh"
#include "option_types.hh"
#include "parameters_parser.hh"
#include "register_manager.hh"
#include "string.hh"
#include "utf8.hh"
#include "utf8_iterator.hh"
#include "parameters_parser.hh"
#include <sstream>
#include <locale>
@ -149,39 +149,41 @@ void apply_highlighter(const Context& context,
display_buffer.compute_range();
}
auto apply_colors = [](const ColorPair& colors)
auto apply_face = [](const Face& face)
{
return [&colors](DisplayAtom& atom) {
if (colors.first != Colors::Default)
atom.colors.first = colors.first;
if (colors.second != Colors::Default)
atom.colors.second = colors.second;
return [&face](DisplayAtom& atom) {
if (face.fg != Colors::Default)
atom.face.fg = face.fg;
if (face.bg != Colors::Default)
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
{
Fill(ColorPair colors) : m_colors(colors) {}
Fill(Face face) : m_face(face) {}
void operator()(const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer)
{
auto range = display_buffer.range();
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)
{
if (params.size() != 1)
throw runtime_error("wrong parameter count");
ColorPair colors = get_color(params[0]);
return HighlighterAndId("fill_" + params[0], Fill(colors));
Face face = get_face(params[0]);
return HighlighterAndId("fill_" + params[0], Fill(face));
}
template<typename T>
@ -203,8 +205,8 @@ private:
class RegexColorizer
{
public:
RegexColorizer(Regex regex, ColorSpec colors)
: m_regex{std::move(regex)}, m_colors{std::move(colors)}
RegexColorizer(Regex regex, FaceSpec faces)
: m_regex{std::move(regex)}, m_faces{std::move(faces)}
{
}
@ -217,12 +219,12 @@ public:
{
for (size_t n = 0; n < match.size(); ++n)
{
auto col_it = m_colors.find(n);
if (col_it == m_colors.end())
auto face_it = m_faces.find(n);
if (face_it == m_faces.end())
continue;
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;
Regex m_regex;
ColorSpec m_colors;
FaceSpec m_faces;
Cache& update_cache_ifn(const Buffer& buffer, const BufferRange& range)
{
@ -277,18 +279,18 @@ HighlighterAndId colorize_regex_factory(HighlighterParameters params)
try
{
static Regex color_spec_ex(R"((\d+):(\w+(,\w+)?))");
ColorSpec colors;
static Regex face_spec_ex(R"((\d+):(\w+(,\w+)?))");
FaceSpec faces;
for (auto it = params.begin() + 1; it != params.end(); ++it)
{
boost::smatch res;
if (not boost::regex_match(it->begin(), it->end(), res, color_spec_ex))
throw runtime_error("wrong colorspec: '" + *it +
if (not boost::regex_match(it->begin(), it->end(), res, face_spec_ex))
throw runtime_error("wrong face spec: '" + *it +
"' expected <capture>:<fgcolor>[,<bgcolor>]");
int capture = str_to_int(res[1].str());
const ColorPair*& color = colors[capture];
color = &get_color(res[2].str());
const Face*& face = faces[capture];
face = &get_face(res[2].str());
}
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};
return HighlighterAndId(id, RegexColorizer(std::move(ex),
std::move(colors)));
std::move(faces)));
}
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
{
public:
DynamicRegexHighlighter(RegexGetter regex_getter, ColorGetter color_getter)
DynamicRegexHighlighter(RegexGetter regex_getter, FaceGetter face_getter)
: m_regex_getter(std::move(regex_getter)),
m_color_getter(std::move(color_getter)),
m_colorizer(Regex(), ColorSpec{}) {}
m_face_getter(std::move(face_getter)),
m_colorizer(Regex(), FaceSpec{}) {}
void operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer)
{
@ -319,15 +321,15 @@ public:
return;
Regex regex = m_regex_getter(context);
ColorSpec color = m_color_getter(context);
if (regex != m_last_regex or color != m_last_color)
FaceSpec face = m_face_getter(context);
if (regex != m_last_regex or face != m_last_face)
{
m_last_regex = regex;
m_last_color = color;
m_last_face = face;
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);
}
@ -335,18 +337,18 @@ private:
Regex m_last_regex;
RegexGetter m_regex_getter;
ColorSpec m_last_color;
ColorGetter m_color_getter;
FaceSpec m_last_face;
FaceGetter m_face_getter;
RegexColorizer m_colorizer;
};
template<typename RegexGetter, typename ColorGetter>
DynamicRegexHighlighter<RegexGetter, ColorGetter>
make_dynamic_regex_highlighter(RegexGetter regex_getter, ColorGetter color_getter)
template<typename RegexGetter, typename FaceGetter>
DynamicRegexHighlighter<RegexGetter, FaceGetter>
make_dynamic_regex_highlighter(RegexGetter regex_getter, FaceGetter face_getter)
{
return DynamicRegexHighlighter<RegexGetter, ColorGetter>(
std::move(regex_getter), std::move(color_getter));
return DynamicRegexHighlighter<RegexGetter, FaceGetter>(
std::move(regex_getter), std::move(face_getter));
}
@ -354,8 +356,8 @@ HighlighterAndId highlight_search_factory(HighlighterParameters params)
{
if (params.size() != 0)
throw runtime_error("wrong parameter count");
auto get_color = [](const Context& context){
return ColorSpec{ { 0, &Kakoune::get_color("Search") } };
auto get_face = [](const Context& context){
return FaceSpec{ { 0, &Kakoune::get_face("Search") } };
};
auto get_regex = [](const Context&){
auto s = Context().main_sel_register_value("/");
@ -368,7 +370,7 @@ HighlighterAndId highlight_search_factory(HighlighterParameters params)
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)
@ -376,9 +378,9 @@ HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
if (params.size() != 2)
throw runtime_error("wrong parameter count");
const ColorPair& color = get_color(params[1]);
auto get_color = [&](const Context&){
return ColorSpec{ { 0, &color } };
const Face& face = get_face(params[1]);
auto get_face = [&](const Context&){
return FaceSpec{ { 0, &face } };
};
String option_name = params[0];
@ -388,7 +390,7 @@ HighlighterAndId highlight_regex_option_factory(HighlighterParameters params)
auto get_regex = [option_name](const Context& context){
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)
@ -396,7 +398,7 @@ HighlighterAndId highlight_line_option_factory(HighlighterParameters params)
if (params.size() != 2)
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];
// verify option type now
@ -407,7 +409,7 @@ HighlighterAndId highlight_line_option_factory(HighlighterParameters params)
{
int line = context.options()[option_name].get<int>();
highlight_range(display_buffer, {line-1, 0}, {line, 0}, false,
apply_colors(color));
apply_face(face));
};
return {"hlline_" + option_name, std::move(highlighter)};
@ -500,20 +502,20 @@ void show_line_numbers(const Context& context, HighlightFlags flags, DisplayBuff
char format[] = "%?d│";
format[1] = '0' + digit_count;
auto& colors = get_color("LineNumbers");
auto& face = get_face("LineNumbers");
for (auto& line : display_buffer.lines())
{
char buffer[10];
snprintf(buffer, 10, format, (int)line.range().first.line + 1);
DisplayAtom atom{buffer};
atom.colors = colors;
atom.face = face;
line.insert(line.begin(), std::move(atom));
}
}
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>;
static const CodepointPair matching_chars[] = { { '(', ')' }, { '{', '}' }, { '[', ']' }, { '<', '>' } };
const auto range = display_buffer.range();
@ -540,7 +542,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
});
if (it != end)
highlight_range(display_buffer, it.coord(), (it+1).coord(), false,
apply_colors(colors));
apply_face(face));
break;
}
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))
highlight_range(display_buffer, it.coord(), (it+1).coord(), false,
apply_colors(colors));
apply_face(face));
break;
}
}
@ -576,17 +578,17 @@ void highlight_selections(const Context& context, HighlightFlags flags, DisplayB
ByteCoord end = forward ? sel.cursor() : buffer.char_next(sel.anchor());
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,
apply_colors(sel_colors));
apply_face(sel_face));
}
for (size_t i = 0; i < context.selections().size(); ++i)
{
auto& sel = context.selections()[i];
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,
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())
atom_it = line.split(atom_it, next.coord());
atom_it->replace(str);
atom_it->colors = { Colors::Red, Colors::Black };
atom_it->face = { Colors::Red, Colors::Black };
break;
}
it = next;
@ -654,7 +656,7 @@ HighlighterAndId flag_lines_factory(HighlighterParameters params)
String content = it != lines.end() ? std::get<2>(*it) : empty;
content += String(' ', width - content.char_length());
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));
}
}};

View File

@ -3,8 +3,8 @@
#include "buffer_manager.hh"
#include "buffer_utils.hh"
#include "client.hh"
#include "color_registry.hh"
#include "event_manager.hh"
#include "face_registry.hh"
#include "insert_completer.hh"
#include "normal.hh"
#include "register_manager.hh"
@ -109,7 +109,7 @@ public:
{
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();
pos.column -= 1;
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;
if (m_cursor_pos == m_line.char_length())
return DisplayLine{{ {m_line.substr(m_display_pos, width-1), get_color("StatusLine")},
{" "_str, get_color("StatusCursor")} }};
return DisplayLine{{ {m_line.substr(m_display_pos, width-1), get_face("StatusLine")},
{" "_str, get_face("StatusCursor")} }};
else
return DisplayLine({ { m_line.substr(m_display_pos, m_cursor_pos - m_display_pos), get_color("StatusLine") },
{ m_line.substr(m_cursor_pos,1), get_color("StatusCursor") },
{ m_line.substr(m_cursor_pos+1, width - m_cursor_pos + m_display_pos - 1), 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_face("StatusCursor") },
{ m_line.substr(m_cursor_pos+1, width - m_cursor_pos + m_display_pos - 1), get_face("StatusLine") } });
}
private:
CharCount m_cursor_pos = 0;
@ -237,8 +237,8 @@ public:
if (not context().has_ui())
return;
CharCoord menu_pos{ context().ui().dimensions().line, 0_char };
context().ui().menu_show(choices, menu_pos, get_color("MenuForeground"),
get_color("MenuBackground"), MenuStyle::Prompt);
context().ui().menu_show(choices, menu_pos, get_face("MenuForeground"),
get_face("MenuBackground"), MenuStyle::Prompt);
context().ui().menu_select(0);
}
@ -314,7 +314,7 @@ public:
auto prompt = "filter:"_str;
auto width = context().ui().dimensions().column - prompt.char_length();
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);
}
}
@ -381,9 +381,9 @@ class Prompt : public InputMode
{
public:
Prompt(InputHandler& input_handler, const String& prompt,
String initstr, ColorPair colors, Completer completer,
String initstr, Face face, Completer completer,
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_history_it = ms_history[m_prompt].end();
@ -554,11 +554,11 @@ public:
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();
}
}
@ -585,8 +585,8 @@ private:
if (context().has_ui() and not candidates.empty())
{
CharCoord menu_pos{ context().ui().dimensions().line, 0_char };
context().ui().menu_show(candidates, menu_pos, get_color("MenuForeground"),
get_color("MenuBackground"), MenuStyle::Prompt);
context().ui().menu_show(candidates, menu_pos, get_face("MenuForeground"),
get_face("MenuBackground"), MenuStyle::Prompt);
}
} catch (runtime_error&) {}
}
@ -605,7 +605,7 @@ private:
auto width = context().ui().dimensions().column - m_prompt.char_length();
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);
}
@ -614,7 +614,7 @@ private:
PromptCallback m_callback;
Completer m_completer;
const String m_prompt;
ColorPair m_prompt_colors;
Face m_prompt_face;
Completions m_completions;
int m_current_completion = -1;
String m_prefix;
@ -939,19 +939,19 @@ void InputHandler::repeat_last_insert()
}
void InputHandler::prompt(const String& prompt, String initstr,
ColorPair prompt_colors, Completer completer,
Face prompt_face, Completer completer,
PromptCallback callback)
{
change_input_mode(new InputModes::Prompt(*this, prompt, initstr,
prompt_colors, completer,
prompt_face, completer,
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());
if (prompt)
prompt->set_prompt_colors(prompt_colors);
prompt->set_prompt_face(prompt_face);
}
void InputHandler::menu(memoryview<String> choices,

View File

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

View File

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

View File

@ -3,18 +3,18 @@
#include "buffer_manager.hh"
#include "buffer_utils.hh"
#include "client_manager.hh"
#include "color_registry.hh"
#include "command_manager.hh"
#include "commands.hh"
#include "context.hh"
#include "debug.hh"
#include "event_manager.hh"
#include "face_registry.hh"
#include "file.hh"
#include "highlighters.hh"
#include "hook_manager.hh"
#include "keymap_manager.hh"
#include "ncurses.hh"
#include "option_manager.hh"
#include "keymap_manager.hh"
#include "parameters_parser.hh"
#include "register_manager.hh"
#include "remote.hh"
@ -363,7 +363,7 @@ int kakoune(const ParametersParser& parser)
RegisterManager register_manager;
HighlighterRegistry highlighter_registry;
DefinedHighlighters defined_highlighters;
ColorRegistry color_registry;
FaceRegistry face_registry;
ClientManager client_manager;
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 int next_pair = 1;
ColorPair colors{face.fg, face.bg};
auto it = colorpairs.find(colors);
if (it != colorpairs.end())
return it->second;
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;
return next_pair++;
}
}
static void set_color(WINDOW* window, ColorPair colors)
static void set_face(WINDOW* window, Face face)
{
static int current_pair = -1;
if (current_pair != -1)
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));
}
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;
@ -293,12 +300,7 @@ void NCursesUI::draw_line(const DisplayLine& line, CharCount col_index) const
{
for (const DisplayAtom& atom : line)
{
set_attribute(A_UNDERLINE, atom.attribute & Underline);
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);
set_face(stdscr, atom.face);
StringView content = atom.content();
if (content.empty())
@ -337,11 +339,7 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer,
++line_index;
}
set_attribute(A_UNDERLINE, 0);
set_attribute(A_REVERSE, 0);
set_attribute(A_BLINK, 0);
set_attribute(A_BOLD, 0);
set_color(stdscr, { Colors::Blue, Colors::Default });
set_face(stdscr, { Colors::Blue, Colors::Default });
for (;line_index < m_dimensions.line; ++line_index)
{
move((int)line_index, 0);
@ -532,7 +530,7 @@ void NCursesUI::draw_menu()
}
void NCursesUI::menu_show(memoryview<String> items,
CharCoord anchor, ColorPair fg, ColorPair bg,
CharCoord anchor, Face fg, Face bg,
MenuStyle style)
{
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,
CharCoord anchor, ColorPair colors,
MenuStyle style)
CharCoord anchor, Face face, MenuStyle style)
{
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,
(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;
auto it = info_box.begin(), end = info_box.end();
while (true)

View File

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

View File

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

View File

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

View File

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