From 1982144b041a9e1054be5f24ea7c7f4eb77d1826 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 26 Mar 2013 00:14:38 +0100 Subject: [PATCH] Add a special option type LineAndFlag, use it for FlagLines highlighter --- src/commands.cc | 3 +++ src/highlighters.cc | 29 ++++++++++++++++++----------- src/option_manager.cc | 6 ++++++ src/option_types.cc | 26 ++++++++++++++++++++++++++ src/option_types.hh | 29 +++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 src/option_types.cc create mode 100644 src/option_types.hh diff --git a/src/commands.cc b/src/commands.cc index 7731ae11..b8c33dce 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -19,6 +19,7 @@ #include "client_manager.hh" #include "parameters_parser.hh" #include "utf8_iterator.hh" +#include "option_types.hh" #include #include @@ -495,6 +496,8 @@ void declare_option(const CommandParameters& params, Context& context) opt = &GlobalOptions::instance().declare_option>(params[1], {}); else if (params[0] == "str-list") opt = &GlobalOptions::instance().declare_option>(params[1], {}); + else if (params[0] == "line-flag-list") + opt = &GlobalOptions::instance().declare_option>(params[1], {}); else throw runtime_error("unknown type " + params[0]); diff --git a/src/highlighters.cc b/src/highlighters.cc index 7c9de93d..55d9f9e4 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -8,6 +8,8 @@ #include "utf8.hh" #include "utf8_iterator.hh" +#include "option_types.hh" + #include #include @@ -316,30 +318,35 @@ void expand_unprintable(DisplayBuffer& display_buffer) class FlagLines { public: - FlagLines(String flag, String lines_opt_name, const OptionManager& options) - : m_flag(std::move(flag)), m_lines_opt_name(std::move(lines_opt_name)), + FlagLines(Color bg, String option_name, const OptionManager& options) + : m_bg(bg), m_option_name(std::move(option_name)), m_options(options) { // trigger an exception if option is not of right type. - m_options[m_lines_opt_name].get>(); + m_options[m_option_name].get>(); } void operator()(DisplayBuffer& display_buffer) { - auto& lines = m_options[m_lines_opt_name].get>(); - const String empty{' ', m_flag.char_length()}; + auto& lines = m_options[m_option_name].get>(); + + CharCount width = 0; + for (auto& l : lines) + width = std::max(width, l.flag.char_length()); + const String empty{' ', width}; for (auto& line : display_buffer.lines()) { - const bool flagged = contains(lines, (int)line.buffer_line() + 1); - DisplayAtom atom{AtomContent(flagged ? m_flag : empty)}; - atom.colors = { Color::Blue, Color::Cyan }; + int line_num = (int)line.buffer_line() + 1; + auto it = find_if(lines, [&](const LineAndFlag& l) { return l.line == line_num; }); + DisplayAtom atom{AtomContent(it != lines.end() ? it->flag : empty)}; + atom.colors = { it != lines.end() ? it->color : Color::Default , m_bg }; line.insert(line.begin(), std::move(atom)); } } private: - String m_flag; - String m_lines_opt_name; + Color m_bg; + String m_option_name; const OptionManager& m_options; }; @@ -348,7 +355,7 @@ HighlighterAndId flag_lines_factory(const HighlighterParameters& params, const W if (params.size() != 2) throw runtime_error("wrong parameter count"); - return {"hlflags_" + params[1], FlagLines{params[0], params[1], window.options()}}; + return {"hlflags_" + params[1], FlagLines{str_to_color(params[0]), params[1], window.options()}}; } template diff --git a/src/option_manager.cc b/src/option_manager.cc index e866b6f5..46bfce9e 100644 --- a/src/option_manager.cc +++ b/src/option_manager.cc @@ -1,6 +1,8 @@ #include "option_manager.hh" #include "assert.hh" +#include "option_types.hh" + #include namespace Kakoune @@ -144,6 +146,9 @@ template void Option::set>(const std::vector&); template const Regex& Option::get() const; template void Option::set(const Regex&); +template const std::vector& Option::get>() const; +template void Option::set>(const std::vector&); + OptionManager::OptionManager(OptionManager& parent) : m_parent(&parent) { @@ -273,5 +278,6 @@ Option& GlobalOptions::declare_option(const String& name, const T& value) } template Option& GlobalOptions::declare_option<>(const String&, const std::vector&); +template Option& GlobalOptions::declare_option<>(const String&, const std::vector&); } diff --git a/src/option_types.cc b/src/option_types.cc new file mode 100644 index 00000000..29d21e8f --- /dev/null +++ b/src/option_types.cc @@ -0,0 +1,26 @@ +#include "option_types.hh" + +#include "exception.hh" + +namespace Kakoune +{ + +String option_to_string(const LineAndFlag& opt) +{ + return int_to_str((int)opt.line) + ":" + color_to_str(opt.color) + ":" + opt.flag; +} + +void option_from_string(const String& str, LineAndFlag& opt) +{ + static Regex re{R"((\d+):(\w+):(.+))"}; + + boost::match_results res; + if (not boost::regex_match(str.begin(), str.end(), res, re)) + throw runtime_error("wrong syntax, expected ::"); + + opt.line = str_to_int(String{res[1].first, res[1].second}); + opt.color = str_to_color(String{res[2].first, res[2].second}); + opt.flag = String{res[3].first, res[3].second}; +} + +} diff --git a/src/option_types.hh b/src/option_types.hh new file mode 100644 index 00000000..b34d16e0 --- /dev/null +++ b/src/option_types.hh @@ -0,0 +1,29 @@ +#ifndef option_types_hh_INCLUDED +#define option_types_hh_INCLUDED + +#include "units.hh" +#include "string.hh" +#include "color.hh" + +namespace Kakoune +{ + +struct LineAndFlag +{ + LineCount line; + Color color; + String flag; + + bool operator==(const LineAndFlag& other) const + { return line == other.line and color == other.color and flag == other.flag; } + + bool operator!=(const LineAndFlag& other) const + { return not (*this == other); } +}; + +String option_to_string(const LineAndFlag& opt); +void option_from_string(const String& str, LineAndFlag& opt); + +} + +#endif // option_types_hh_INCLUDED