Simplify FlagLines, do not try to update the option

This commit is contained in:
Maxime Coste 2013-11-18 22:44:01 +00:00
parent 2d55ff5feb
commit 255a747fdd

View File

@ -334,123 +334,40 @@ void expand_unprintable(const Window& window, DisplayBuffer& display_buffer)
}
}
class FlagLines : public OptionManagerWatcher_AutoRegister
{
public:
FlagLines(Color bg, String option_name, Window& window)
: OptionManagerWatcher_AutoRegister(window.options()),
m_bg(bg), m_option_name(std::move(option_name)),
m_window(window)
{
// trigger an exception if option is not of right type.
m_window.options()[m_option_name].get<std::vector<LineAndFlag>>();
update_shared_option_updater();
}
void operator()(const Window&, DisplayBuffer& display_buffer)
{
update_shared_option_updater();
auto& lines = m_window.options()[m_option_name].get<std::vector<LineAndFlag>>();
CharCount width = 0;
for (auto& l : lines)
width = std::max(width, std::get<2>(l).char_length());
const String empty{' ', width};
for (auto& line : display_buffer.lines())
{
int line_num = (int)line.range().first.line + 1;
auto it = find_if(lines, [&](const LineAndFlag& l) { return std::get<0>(l) == line_num; });
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 , m_bg };
line.insert(line.begin(), std::move(atom));
}
}
private:
void on_option_changed(const Option& option) override
{
if (option.name() == m_option_name)
m_window.forget_timestamp();
}
struct OptionUpdater : BufferChangeListener_AutoRegister
{
OptionUpdater(Buffer& buffer, Option& option)
: BufferChangeListener_AutoRegister(buffer), m_option(&option)
{
// sanity checks
kak_assert(&m_option->manager() != &GlobalOptions::instance());
m_option->get<std::vector<LineAndFlag>>();
}
void on_insert(const Buffer&, BufferCoord begin, BufferCoord end) override
{
LineCount new_lines = end.line - begin.line;
if (new_lines == 0)
return;
auto lines = m_option->get<std::vector<LineAndFlag>>();
for (auto& line : lines)
{
if (std::get<0>(line) > begin.line)
std::get<0>(line) += new_lines;
}
m_option->set(lines);
}
void on_erase(const Buffer&, BufferCoord begin, BufferCoord end) override
{
LineCount removed_lines = end.line - begin.line;
if (removed_lines == 0)
return;
auto lines = m_option->get<std::vector<LineAndFlag>>();
for (auto& line : lines)
{
if (std::get<0>(line) > begin.line)
std::get<0>(line) -= removed_lines;
}
m_option->set(lines);
}
const Option& option() const { return *m_option; }
private:
safe_ptr<Option> m_option;
};
static std::unordered_map<const Option*, std::weak_ptr<OptionUpdater>> ms_updaters;
void update_shared_option_updater()
{
const Option& option = m_window.options()[m_option_name];
if (&option.manager() == &GlobalOptions::instance() or
(m_updater and &option == &m_updater->option()))
return;
auto& shared_updater = ms_updaters[&option];
if (shared_updater.expired())
{
m_updater = std::make_shared<OptionUpdater>(
m_window.buffer(), option.manager().get_local_option(option.name()));
shared_updater = m_updater;
}
else
m_updater = shared_updater.lock();
}
Color m_bg;
String m_option_name;
Window& m_window;
std::shared_ptr<OptionUpdater> m_updater;
};
std::unordered_map<const Option*, std::weak_ptr<FlagLines::OptionUpdater>> FlagLines::ms_updaters;
HighlighterAndId flag_lines_factory(HighlighterParameters params, Window& window)
{
if (params.size() != 2)
throw runtime_error("wrong parameter count");
return {"hlflags_" + params[1], FlagLines{str_to_color(params[0]), params[1], window}};
const String& option_name = params[1];
Color bg = str_to_color(params[0]);
// throw if wrong option type
GlobalOptions::instance()[option_name].get<std::vector<LineAndFlag>>();
return {"hlflags_" + params[1],
[=](const Window& window, DisplayBuffer& display_buffer)
{
auto& lines_opt = window.options()[option_name];
auto& lines = lines_opt.get<std::vector<LineAndFlag>>();
CharCount width = 0;
for (auto& l : lines)
width = std::max(width, std::get<2>(l).char_length());
const String empty{' ', width};
for (auto& line : display_buffer.lines())
{
int line_num = (int)line.range().first.line + 1;
auto it = find_if(lines,
[&](const LineAndFlag& l)
{ return std::get<0>(l) == line_num; });
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 };
line.insert(line.begin(), std::move(atom));
}
}};
}
template<void (*highlighter_func)(const Window&, DisplayBuffer&)>