summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-12-17 04:07:09 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-12-17 04:07:49 +0000
commit8dcffd8f5a4a29d89716c114214d24803fe93d9f (patch)
tree68d43656cc3f7f9ebe001f281c1ac528f0f87ef3 /src
parent925d41f59672f2e4fad1355e880193f75dcfd952 (diff)
Initial, WIP spelling implementation
Add a ranges highlighter that takes a timestamped list of ranges and associated face. Add a spell.kak file that uses aspell pipe interface to fill a range-faces option.
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc5
-rw-r--r--src/display_buffer.cc27
-rw-r--r--src/display_buffer.hh3
-rw-r--r--src/highlighters.cc47
-rw-r--r--src/highlighters.hh1
5 files changed, 82 insertions, 1 deletions
diff --git a/src/commands.cc b/src/commands.cc
index dcee70cd..1df0d097 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -1104,7 +1104,8 @@ const CommandDesc declare_option_cmd = {
" regex: regular expression\n"
" int-list: list of integers\n"
" str-list: list of character strings\n"
- " line-flags: list of line flags\n",
+ " line-flags: list of line flags\n"
+ " range-faces: list of range faces\n",
ParameterDesc{
{ { "hidden", { false, "do not display option name when completing" } },
{ "docstring", { true, "specify option description" } } },
@@ -1138,6 +1139,8 @@ const CommandDesc declare_option_cmd = {
opt = &reg.declare_option<Vector<String, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
else if (parser[0] == "line-flags")
opt = &reg.declare_option<TimestampedList<LineAndFlag>>(parser[1], docstring, {}, flags);
+ else if (parser[0] == "range-faces")
+ opt = &reg.declare_option<TimestampedList<RangeAndFace>>(parser[1], docstring, {}, flags);
else
throw runtime_error(format("unknown type {}", parser[0]));
diff --git a/src/display_buffer.cc b/src/display_buffer.cc
index 61078657..c112679d 100644
--- a/src/display_buffer.cc
+++ b/src/display_buffer.cc
@@ -9,6 +9,33 @@
namespace Kakoune
{
+String option_to_string(BufferRange range)
+{
+ return format("{}.{},{}.{}",
+ range.begin.line+1, range.begin.column+1,
+ range.end.line+1, range.end.column+1);
+}
+
+void option_from_string(StringView str, BufferRange& opt)
+{
+ auto comma = find(str, ',');
+ auto dot_begin = find(StringView{str.begin(), comma}, '.');
+ auto dot_end = find(StringView{comma, str.end()}, '.');
+
+ if (comma == str.end() or dot_begin == comma or dot_end == str.end())
+ throw runtime_error(format("'{}' does not follow <line>.<column>,<line>.<column> format", str));
+
+ ByteCoord begin{str_to_int({str.begin(), dot_begin}) - 1,
+ str_to_int({dot_begin+1, comma}) - 1};
+
+ ByteCoord end{str_to_int({comma+1, dot_end}) - 1,
+ str_to_int({dot_end+1, str.end()}) - 1};
+
+ opt.begin = begin;
+ opt.end = end;
+}
+
+
StringView DisplayAtom::content() const
{
switch (m_type)
diff --git a/src/display_buffer.hh b/src/display_buffer.hh
index 177a5920..14e7044e 100644
--- a/src/display_buffer.hh
+++ b/src/display_buffer.hh
@@ -13,6 +13,9 @@ namespace Kakoune
class Buffer;
struct BufferRange{ ByteCoord begin, end; };
+String option_to_string(BufferRange range);
+void option_from_string(StringView str, BufferRange& opt);
+
inline bool operator==(const BufferRange& lhs, const BufferRange& rhs)
{
return lhs.begin == rhs.begin and lhs.end == rhs.end;
diff --git a/src/highlighters.cc b/src/highlighters.cc
index c88f078d..8b0d669d 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -982,6 +982,48 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params)
return {"hlflags_" + params[1], make_simple_highlighter(func) };
}
+HighlighterAndId create_ranges_highlighter(HighlighterParameters params)
+{
+ if (params.size() != 1)
+ throw runtime_error("wrong parameter count");
+
+ const String& option_name = params[0];
+
+ // throw if wrong option type
+ GlobalScope::instance().options()[option_name].get<TimestampedList<RangeAndFace>>();
+
+ auto func = [=](const Context& context, HighlightFlags flags,
+ DisplayBuffer& display_buffer, BufferRange)
+ {
+ auto& range_and_faces = context.options()[option_name].get_mutable<TimestampedList<RangeAndFace>>();
+ auto& ranges = range_and_faces.list;
+
+ auto& buffer = context.buffer();
+ if (range_and_faces.timestamp != buffer.timestamp())
+ {
+ // TODO: update ranges to current timestamp
+ return;
+ }
+
+ for (auto& range : ranges)
+ {
+ try
+ {
+ auto& r = std::get<0>(range);
+ if (not buffer.is_valid(r.begin) or not buffer.is_valid(r.end))
+ continue;
+
+ highlight_range(display_buffer, r.begin, r.end, true,
+ apply_face(get_face(std::get<1>(range))));
+ }
+ catch (runtime_error&)
+ {}
+ }
+ };
+
+ return {"hlranges_" + params[1], make_simple_highlighter(func) };
+}
+
HighlighterAndId create_highlighter_group(HighlighterParameters params)
{
if (params.size() != 1)
@@ -1442,6 +1484,11 @@ void register_highlighters()
"Display flags specified in the line-flag-list option <option name>\n"
"A line-flag is written: <line>|<fg color>|<text>, the list is : separated" } });
registry.append({
+ "ranges",
+ { create_ranges_highlighter,
+ "Parameters: <option name>\n"
+ "Use the range-faces option given as parameter to highlight buffer\n" } });
+ registry.append({
"line",
{ create_line_highlighter,
"Parameters: <value string> <face>\n"
diff --git a/src/highlighters.hh b/src/highlighters.hh
index 26b7a5d1..e4063c52 100644
--- a/src/highlighters.hh
+++ b/src/highlighters.hh
@@ -10,6 +10,7 @@ namespace Kakoune
void register_highlighters();
using LineAndFlag = std::tuple<LineCount, String>;
+using RangeAndFace = std::tuple<BufferRange, String>;
}