From 5cf947f84543e175a76dbf07d58f9a6ef4b8cd89 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 17 Sep 2012 19:01:13 +0200 Subject: [PATCH] Add a ColorRegistry class responsible of color parsing and supporting aliases colalias command permits to define names for color pairs --- src/color.hh | 23 ++++++++++++++++++ src/color_registry.cc | 56 +++++++++++++++++++++++++++++++++++++++++++ src/color_registry.hh | 27 +++++++++++++++++++++ src/commands.cc | 7 ++++++ src/display_buffer.hh | 14 +---------- src/highlighters.cc | 24 ++++--------------- src/main.cc | 2 ++ 7 files changed, 120 insertions(+), 33 deletions(-) create mode 100644 src/color.hh create mode 100644 src/color_registry.cc create mode 100644 src/color_registry.hh diff --git a/src/color.hh b/src/color.hh new file mode 100644 index 00000000..64cf6350 --- /dev/null +++ b/src/color.hh @@ -0,0 +1,23 @@ +#ifndef color_hh_INCLUDED +#define color_hh_INCLUDED + +namespace Kakoune +{ + +enum class Color +{ + Default, + Black, + Red, + Green, + Yellow, + Blue, + Magenta, + Cyan, + White +}; + +} + +#endif // color_hh_INCLUDED + diff --git a/src/color_registry.cc b/src/color_registry.cc new file mode 100644 index 00000000..ed1dcac3 --- /dev/null +++ b/src/color_registry.cc @@ -0,0 +1,56 @@ +#include "color_registry.hh" + +#include "exception.hh" + +namespace Kakoune +{ + +static Color parse_color(const String& color) +{ + if (color == "default") return Color::Default; + if (color == "black") return Color::Black; + if (color == "red") return Color::Red; + if (color == "green") return Color::Green; + if (color == "yellow") return Color::Yellow; + if (color == "blue") return Color::Blue; + if (color == "magenta") return Color::Magenta; + if (color == "cyan") return Color::Cyan; + if (color == "white") return Color::White; + throw runtime_error("Unable to parse color '" + color + "'"); + return Color::Default; +} + +const ColorPair& ColorRegistry::operator[](const String& colordesc) +{ + auto alias_it = m_aliases.find(colordesc); + if (alias_it != m_aliases.end()) + return alias_it->second; + + auto it = std::find(colordesc.begin(), colordesc.end(), ','); + ColorPair colpair{ parse_color(String(colordesc.begin(), it)), + it != colordesc.end() ? + parse_color(String(it+1, colordesc.end())) + : Color::Default }; + + m_aliases[colordesc] = colpair; +} + +void ColorRegistry::register_alias(const String& name, const String& colordesc) +{ + if (m_aliases.find(name) != m_aliases.end()) + throw runtime_error("alias '" + name + "' already defined"); + + if (std::find_if(name.begin(), name.end(), + [](Character c) { return not isalnum(c); }) != name.end()) + throw runtime_error("alias names are limited to alpha numeric words"); + + auto it = std::find(colordesc.begin(), colordesc.end(), ','); + auto fg = parse_color(String(colordesc.begin(), it)); + auto bg = Color::Default; + if (it != colordesc.end()) + bg = parse_color(String(it+1, colordesc.end())); + + m_aliases[name] = { fg, bg }; +} + +} diff --git a/src/color_registry.hh b/src/color_registry.hh new file mode 100644 index 00000000..0b249b71 --- /dev/null +++ b/src/color_registry.hh @@ -0,0 +1,27 @@ +#ifndef color_registry_hh_INCLUDED +#define color_registry_hh_INCLUDED + +#include + +#include "color.hh" +#include "utils.hh" + +namespace Kakoune +{ + +using ColorPair = std::pair; + +class ColorRegistry : public Singleton +{ +public: + const ColorPair& operator[](const String& colordesc); + void register_alias(const String& name, const String& colordesc); + +private: + std::unordered_map m_aliases; +}; + +} + +#endif // color_registry_hh_INCLUDED + diff --git a/src/commands.cc b/src/commands.cc index d838090f..fe15593b 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -15,6 +15,7 @@ #include "completion.hh" #include "shell_manager.hh" #include "event_manager.hh" +#include "color_registry.hh" #if defined(__APPLE__) #include @@ -861,6 +862,12 @@ void register_commands() [](const Context& context, const String& prefix, CharCount cursor_pos) { return context.window().option_manager().complete_option_name(prefix, cursor_pos); } })); + + cm.register_commands({"ca", "colalias"}, + [](const CommandParameters& params, Context&) { + if (params.size() != 2) throw wrong_argument_count(); + ColorRegistry::instance().register_alias(params[0], params[1]); + }); } } diff --git a/src/display_buffer.hh b/src/display_buffer.hh index 2fcca28c..3b69bd00 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -4,6 +4,7 @@ #include #include "string.hh" +#include "color.hh" #include "line_and_column.hh" #include "buffer.hh" @@ -31,19 +32,6 @@ enum Attributes Bold = 8 }; -enum class Color -{ - Default, - Black, - Red, - Green, - Yellow, - Blue, - Magenta, - Cyan, - White -}; - struct AtomContent { public: diff --git a/src/highlighters.cc b/src/highlighters.cc index f5f949b0..c0cd686f 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -2,6 +2,7 @@ #include "assert.hh" #include "window.hh" #include "highlighter_registry.hh" +#include "color_registry.hh" #include "highlighter_group.hh" #include "string.hh" @@ -113,20 +114,6 @@ private: } }; -Color parse_color(const String& color) -{ - if (color == "default") return Color::Default; - if (color == "black") return Color::Black; - if (color == "red") return Color::Red; - if (color == "green") return Color::Green; - if (color == "yellow") return Color::Yellow; - if (color == "blue") return Color::Blue; - if (color == "magenta") return Color::Magenta; - if (color == "cyan") return Color::Cyan; - if (color == "white") return Color::White; - return Color::Default; -} - HighlighterAndId colorize_regex_factory(Window& window, const HighlighterParameters params) { @@ -135,7 +122,7 @@ HighlighterAndId colorize_regex_factory(Window& window, try { - static Regex color_spec_ex(LR"((\d+):(\w+)(,(\w+))?)"); + static Regex color_spec_ex(LR"((\d+):(\w+(,\w+)?))"); ColorSpec colors; for (auto it = params.begin() + 1; it != params.end(); ++it) { @@ -145,11 +132,8 @@ HighlighterAndId colorize_regex_factory(Window& window, "' expected :[,]"); int capture = str_to_int(String(res[1].first, res[1].second)); - Color fg_color = parse_color(String(res[2].first, res[2].second)); - Color bg_color = res[4].matched ? - parse_color(String(res[4].first, res[4].second)) - : Color::Default; - colors[capture] = { fg_color, bg_color }; + ColorPair& color = colors[capture]; + color = ColorRegistry::instance()[String(res[2].first, res[2].second)]; } String id = "colre'" + params[0] + "'"; diff --git a/src/main.cc b/src/main.cc index f420114f..929323c3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -18,6 +18,7 @@ #include "context.hh" #include "ncurses.hh" #include "string.hh" +#include "color_registry.hh" #include #include @@ -445,6 +446,7 @@ int main(int argc, char* argv[]) RegisterManager register_manager; HighlighterRegistry highlighter_registry; FilterRegistry filter_registry; + ColorRegistry color_registry; run_unit_tests();