summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-05-25 08:38:11 +0100
committerMaxime Coste <mawww@kakoune.org>2017-05-25 19:54:08 +0100
commit83d85df26e68687ca124c3affb42e246fd77188a (patch)
tree87260753f599c46706e6aa77249c35e5e1c7aed4 /src
parentf014eb7052082f7a6760dbd2aec9204b0cb4e1dc (diff)
Add an update-option command to update range-descs/line-descs options
update-option will make the range-descs and line-descs option up to date with the latest buffer modfications, changing the ranges/lines to where they moved according the modifications since the timestamp on the option.
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc59
-rw-r--r--src/highlighters.cc98
-rw-r--r--src/highlighters.hh16
-rw-r--r--src/option_manager.hh6
-rw-r--r--src/option_types.hh5
5 files changed, 115 insertions, 69 deletions
diff --git a/src/commands.cc b/src/commands.cc
index b11db6a5..34908f28 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -43,16 +43,6 @@
namespace Kakoune
{
-StringView option_type_name(Meta::Type<TimestampedList<LineAndSpec>>)
-{
- return "line-specs";
-}
-
-StringView option_type_name(Meta::Type<TimestampedList<RangeAndString>>)
-{
- return "range-specs";
-}
-
namespace
{
@@ -1289,6 +1279,21 @@ const CommandDesc set_option_cmd = {
}
};
+Completions complete_option(const Context& context, CompletionFlags,
+ CommandParameters params, size_t token_to_complete,
+ ByteCount pos_in_token)
+{
+ if (token_to_complete == 0)
+ {
+ static constexpr auto scopes = { "buffer", "window", "current" };
+ return { 0_byte, params[0].length(), complete(params[0], pos_in_token, scopes) };
+ }
+ else if (token_to_complete == 1)
+ return { 0_byte, params[1].length(),
+ GlobalScope::instance().option_registry().complete_option_name(params[1], pos_in_token) };
+ return Completions{};
+}
+
const CommandDesc unset_option_cmd = {
"unset-option",
"unset",
@@ -1298,20 +1303,7 @@ const CommandDesc unset_option_cmd = {
ParameterDesc{ {}, ParameterDesc::Flags::None, 2, 2 },
CommandFlags::None,
option_doc_helper,
- [](const Context& context, CompletionFlags,
- CommandParameters params, size_t token_to_complete,
- ByteCount pos_in_token) -> Completions
- {
- if (token_to_complete == 0)
- {
- static constexpr auto scopes = { "buffer", "window", "current" };
- return { 0_byte, params[0].length(), complete(params[0], pos_in_token, scopes) };
- }
- else if (token_to_complete == 1)
- return { 0_byte, params[1].length(),
- GlobalScope::instance().option_registry().complete_option_name(params[1], pos_in_token) };
- return Completions{};
- },
+ complete_option,
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
auto& options = get_options(parser[0], context, parser[1]);
@@ -1321,6 +1313,24 @@ const CommandDesc unset_option_cmd = {
}
};
+const CommandDesc update_option_cmd = {
+ "update-option",
+ nullptr,
+ "update-option <scope> <name>: update <name> option from scope\n"
+ "some option types, such as line-descs or range-descs can be updated to latest buffer timestamp\n"
+ "<scope> can be buffer, window, or current which refers to the narrowest\n"
+ "scope the option is set in",
+ ParameterDesc{ {}, ParameterDesc::Flags::None, 2, 2 },
+ CommandFlags::None,
+ option_doc_helper,
+ complete_option,
+ [](const ParametersParser& parser, Context& context, const ShellContext&)
+ {
+ Option& opt = get_options(parser[0], context, parser[1]).get_local_option(parser[1]);
+ opt.update(context);
+ }
+};
+
const CommandDesc declare_option_cmd = {
"declare-option",
"decl",
@@ -2142,6 +2152,7 @@ void register_commands()
register_command(source_cmd);
register_command(set_option_cmd);
register_command(unset_option_cmd);
+ register_command(update_option_cmd);
register_command(declare_option_cmd);
register_command(map_key_cmd);
register_command(unmap_key_cmd);
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 610ddffd..3df17ccb 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -1177,6 +1177,47 @@ void expand_unprintable(const Context& context, HighlightPass, DisplayBuffer& di
}
}
+static void update_line_specs_ifn(const Buffer& buffer, LineAndSpecList& line_flags)
+{
+ if (line_flags.prefix == buffer.timestamp())
+ return;
+
+ auto& lines = line_flags.list;
+
+ std::sort(lines.begin(), lines.end(),
+ [](const LineAndSpec& lhs, const LineAndSpec& rhs)
+ { return std::get<0>(lhs) < std::get<0>(rhs); });
+
+ auto modifs = compute_line_modifications(buffer, line_flags.prefix);
+ 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;
+ }
+ lines.erase(ins_pos, lines.end());
+ line_flags.prefix = buffer.timestamp();
+}
+
+void option_update(LineAndSpecList& opt, const Context& context)
+{
+ update_line_specs_ifn(context.buffer(), opt);
+}
+
struct FlagLinesHighlighter : Highlighter
{
FlagLinesHighlighter(String option_name, String default_face)
@@ -1184,8 +1225,6 @@ struct FlagLinesHighlighter : Highlighter
m_option_name{std::move(option_name)},
m_default_face{std::move(default_face)} {}
- using LineAndSpecList = TimestampedList<LineAndSpec>;
-
static HighlighterAndId create(HighlighterParameters params)
{
if (params.size() != 2)
@@ -1207,7 +1246,7 @@ private:
{
auto& line_flags = context.options()[m_option_name].get_mutable<LineAndSpecList>();
auto& buffer = context.buffer();
- update_line_flags_ifn(buffer, line_flags);
+ update_line_specs_ifn(buffer, line_flags);
auto def_face = get_face(m_default_face);
Vector<DisplayLine> display_lines;
@@ -1257,7 +1296,7 @@ private:
{
auto& line_flags = context.options()[m_option_name].get_mutable<LineAndSpecList>();
auto& buffer = context.buffer();
- update_line_flags_ifn(buffer, line_flags);
+ update_line_specs_ifn(buffer, line_flags);
ColumnCount width = 0;
try
@@ -1274,42 +1313,6 @@ private:
setup.window_range.column -= width;
}
- void update_line_flags_ifn(const Buffer& buffer, LineAndSpecList& line_flags)
- {
- if (line_flags.prefix == buffer.timestamp())
- return;
-
- auto& lines = line_flags.list;
-
- std::sort(lines.begin(), lines.end(),
- [](const LineAndSpec& lhs, const LineAndSpec& rhs)
- { return std::get<0>(lhs) < std::get<0>(rhs); });
-
- auto modifs = compute_line_modifications(buffer, line_flags.prefix);
- 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;
- }
- lines.erase(ins_pos, lines.end());
- line_flags.prefix = buffer.timestamp();
- }
-
String m_option_name;
String m_default_face;
};
@@ -1348,7 +1351,7 @@ void option_from_string(StringView str, InclusiveBufferRange& opt)
BufferCoord& get_first(RangeAndString& r) { return std::get<0>(r).first; }
BufferCoord& get_last(RangeAndString& r) { return std::get<0>(r).last; }
-static void update_ranges_ifn(const Buffer& buffer, TimestampedList<RangeAndString>& range_and_faces)
+static void update_ranges_ifn(const Buffer& buffer, RangeAndStringList& range_and_faces)
{
if (range_and_faces.prefix == buffer.timestamp())
return;
@@ -1373,6 +1376,11 @@ static void update_ranges_ifn(const Buffer& buffer, TimestampedList<RangeAndStri
range_and_faces.prefix = buffer.timestamp();
}
+void option_update(RangeAndStringList& opt, const Context& context)
+{
+ update_ranges_ifn(context.buffer(), opt);
+}
+
struct RangesHighlighter : Highlighter
{
RangesHighlighter(String option_name)
@@ -1386,7 +1394,7 @@ struct RangesHighlighter : Highlighter
const String& option_name = params[0];
// throw if wrong option type
- GlobalScope::instance().options()[option_name].get<TimestampedList<RangeAndString>>();
+ GlobalScope::instance().options()[option_name].get<RangeAndStringList>();
return {"hlranges_" + params[0], make_unique<RangesHighlighter>(option_name)};
}
@@ -1395,7 +1403,7 @@ private:
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) override
{
auto& buffer = context.buffer();
- auto& range_and_faces = context.options()[m_option_name].get_mutable<TimestampedList<RangeAndString>>();
+ auto& range_and_faces = context.options()[m_option_name].get_mutable<RangeAndStringList>();
update_ranges_ifn(buffer, range_and_faces);
for (auto& range : range_and_faces.list)
@@ -1428,7 +1436,7 @@ struct ReplaceRangesHighlighter : Highlighter
const String& option_name = params[0];
// throw if wrong option type
- GlobalScope::instance().options()[option_name].get<TimestampedList<RangeAndString>>();
+ GlobalScope::instance().options()[option_name].get<RangeAndStringList>();
return {"replace_ranges_" + params[0], make_unique<ReplaceRangesHighlighter>(option_name)};
}
@@ -1437,7 +1445,7 @@ private:
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) override
{
auto& buffer = context.buffer();
- auto& range_and_faces = context.options()[m_option_name].get_mutable<TimestampedList<RangeAndString>>();
+ auto& range_and_faces = context.options()[m_option_name].get_mutable<RangeAndStringList>();
update_ranges_ifn(buffer, range_and_faces);
for (auto& range : range_and_faces.list)
diff --git a/src/highlighters.hh b/src/highlighters.hh
index a3f1971d..cae0d63e 100644
--- a/src/highlighters.hh
+++ b/src/highlighters.hh
@@ -3,6 +3,7 @@
#include "color.hh"
#include "highlighter.hh"
+#include "option.hh"
namespace Kakoune
{
@@ -19,7 +20,22 @@ String option_to_string(InclusiveBufferRange range);
void option_from_string(StringView str, InclusiveBufferRange& opt);
using LineAndSpec = std::tuple<LineCount, String>;
+using LineAndSpecList = TimestampedList<LineAndSpec>;
+
+constexpr StringView option_type_name(Meta::Type<LineAndSpecList>)
+{
+ return "line-specs";
+}
+void option_update(LineAndSpecList& opt, const Context& context);
+
using RangeAndString = std::tuple<InclusiveBufferRange, String>;
+using RangeAndStringList = TimestampedList<RangeAndString>;
+
+constexpr StringView option_type_name(Meta::Type<RangeAndStringList>)
+{
+ return "range-specs";
+}
+void option_update(RangeAndStringList& opt, const Context& context);
}
diff --git a/src/option_manager.hh b/src/option_manager.hh
index 2970d4e2..97556749 100644
--- a/src/option_manager.hh
+++ b/src/option_manager.hh
@@ -14,6 +14,7 @@ namespace Kakoune
{
class OptionManager;
+class Context;
enum class OptionFlags
{
@@ -52,6 +53,7 @@ public:
virtual String get_as_string() const = 0;
virtual void set_from_string(StringView str) = 0;
virtual void add_from_string(StringView str) = 0;
+ virtual void update(const Context& context) = 0;
virtual Option* clone(OptionManager& manager) const = 0;
OptionManager& manager() const { return m_manager; }
@@ -140,6 +142,10 @@ public:
if (option_add(m_value, str))
m_manager.on_option_changed(*this);
}
+ void update(const Context& context) override
+ {
+ option_update(m_value, context);
+ }
private:
virtual void validate(const T& value) const {}
T m_value;
diff --git a/src/option_types.hh b/src/option_types.hh
index 81dca3bd..56b32e99 100644
--- a/src/option_types.hh
+++ b/src/option_types.hh
@@ -218,6 +218,11 @@ inline bool option_add(WorstMatch, StringView)
throw runtime_error("no add operation supported for this option type");
}
+inline void option_update(WorstMatch, const Context&)
+{
+ throw runtime_error("no update operation supported for this option type");
+}
+
template<typename EffectiveType, typename LineType, typename ColumnType>
inline void option_from_string(StringView str, LineAndColumn<EffectiveType, LineType, ColumnType>& opt)
{