Simplify FlagLines, do not try to update the option
This commit is contained in:
parent
2d55ff5feb
commit
255a747fdd
|
@ -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&)>
|
||||
|
|
Loading…
Reference in New Issue
Block a user