diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/commands.cc | 6 | ||||
| -rw-r--r-- | src/highlighters.cc | 37 | ||||
| -rw-r--r-- | src/option_manager.hh | 7 | ||||
| -rw-r--r-- | src/option_types.hh | 39 |
4 files changed, 83 insertions, 6 deletions
diff --git a/src/commands.cc b/src/commands.cc index d468dc59..dcee70cd 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1104,7 +1104,7 @@ const CommandDesc declare_option_cmd = { " regex: regular expression\n" " int-list: list of integers\n" " str-list: list of character strings\n" - " line-flag-list: list of line flags\n", + " line-flags: list of line flags\n", ParameterDesc{ { { "hidden", { false, "do not display option name when completing" } }, { "docstring", { true, "specify option description" } } }, @@ -1136,8 +1136,8 @@ const CommandDesc declare_option_cmd = { opt = ®.declare_option<Vector<int, MemoryDomain::Options>>(parser[1], docstring, {}, flags); else if (parser[0] == "str-list") opt = ®.declare_option<Vector<String, MemoryDomain::Options>>(parser[1], docstring, {}, flags); - else if (parser[0] == "line-flag-list") - opt = ®.declare_option<Vector<LineAndFlag, MemoryDomain::Options>>(parser[1], docstring, {}, flags); + else if (parser[0] == "line-flags") + opt = ®.declare_option<TimestampedList<LineAndFlag>>(parser[1], docstring, {}, flags); else throw runtime_error(format("unknown type {}", parser[0])); diff --git a/src/highlighters.cc b/src/highlighters.cc index 68f0bdb5..28e36660 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -904,13 +904,44 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params) get_face(default_face); // validate param // throw if wrong option type - GlobalScope::instance().options()[option_name].get<Vector<LineAndFlag, MemoryDomain::Options>>(); + GlobalScope::instance().options()[option_name].get<TimestampedList<LineAndFlag>>(); auto func = [=](const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer, BufferRange) { - auto& lines_opt = context.options()[option_name]; - auto& lines = lines_opt.get<Vector<LineAndFlag, MemoryDomain::Options>>(); + auto& line_flags = context.options()[option_name].get_mutable<TimestampedList<LineAndFlag>>(); + auto& lines = line_flags.list; + + auto& buffer = context.buffer(); + if (line_flags.timestamp != buffer.timestamp()) + { + std::sort(lines.begin(), lines.end(), + [](const LineAndFlag& lhs, const LineAndFlag& rhs) + { return std::get<0>(lhs) < std::get<0>(rhs); }); + + auto modifs = compute_line_modifications(buffer, line_flags.timestamp); + auto ins_pos = lines.begin(); + for (auto it = lines.begin(); it != lines.end(); ++it) + { + auto& line = std::get<0>(*it); // that line is 1 based as it comes from user side + auto modif_it = std::upper_bound(modifs.begin(), modifs.end(), line-1, + [](const LineCount& l, const LineModification& c) + { return l < c.old_line; }); + if (modif_it != modifs.begin()) + { + auto& prev = *(modif_it-1); + if (line-1 < prev.old_line + prev.num_removed) + continue; // line removed + + line += prev.diff(); + } + + if (ins_pos != it) + *ins_pos = std::move(*it); + ++ins_pos; + } + line_flags.timestamp = buffer.timestamp(); + } auto def_face = get_face(default_face); diff --git a/src/option_manager.hh b/src/option_manager.hh index 8e21808c..6c4dce18 100644 --- a/src/option_manager.hh +++ b/src/option_manager.hh @@ -44,6 +44,7 @@ public: virtual ~Option() = default; template<typename T> const T& get() const; + template<typename T> T& get_mutable(); template<typename T> void set(const T& val, bool notify=true); template<typename T> bool is_of_type() const; @@ -122,6 +123,7 @@ public: } } const T& get() const { return m_value; } + T& get_mutable() { return m_value; } String get_as_string() const override { @@ -167,6 +169,11 @@ template<typename T> const T& Option::get() const return typed_opt->get(); } +template<typename T> T& Option::get_mutable() +{ + return const_cast<T&>(get<T>()); +} + template<typename T> void Option::set(const T& val, bool notify) { auto* typed_opt = dynamic_cast<TypedOption<T>*>(this); diff --git a/src/option_types.hh b/src/option_types.hh index 12f5e4fd..73a8bcfb 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -223,6 +223,45 @@ constexpr Array<EnumDesc<DebugFlags>, 3> enum_desc(DebugFlags) } }; } +template<typename T> +struct TimestampedList +{ + size_t timestamp; + Vector<T, MemoryDomain::Options> list; +}; + +template<typename T> +inline bool operator==(const TimestampedList<T>& lhs, const TimestampedList<T>& rhs) +{ + return lhs.timestamp == rhs.timestamp and lhs.list == rhs.list; +} + +template<typename T> +inline bool operator!=(const TimestampedList<T>& lhs, const TimestampedList<T>& rhs) +{ + return not (lhs == rhs); +} + +template<typename T> +inline String option_to_string(const TimestampedList<T>& opt) +{ + return format("{}:{}", opt.timestamp, option_to_string(opt.list)); +} + +template<typename T> +inline void option_from_string(StringView str, TimestampedList<T>& opt) +{ + auto it = find(str, ':'); + opt.timestamp = str_to_int({str.begin(), it}); + option_from_string({it+1, str.end()}, opt.list); +} + +template<typename T> +inline bool option_add(TimestampedList<T>& opt, StringView str) +{ + return option_add(opt.list, str); +} + } #endif // option_types_hh_INCLUDED |
