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.
This commit is contained in:
parent
925d41f596
commit
8dcffd8f5a
40
rc/spell.kak
Normal file
40
rc/spell.kak
Normal file
|
@ -0,0 +1,40 @@
|
|||
decl -hidden range-faces spell_regions
|
||||
decl -hidden str spell_tmp_file
|
||||
|
||||
def spell %{
|
||||
try %{ addhl ranges 'spell_regions' }
|
||||
%sh{
|
||||
file=$(mktemp -d -t kak-spell.XXXXXXXX)/buffer
|
||||
echo "write ${file}"
|
||||
echo "set buffer spell_tmp_file ${file}"
|
||||
}
|
||||
%sh{
|
||||
sed -ie 's/^/^/' $kak_opt_spell_tmp_file
|
||||
aspell -a < $kak_opt_spell_tmp_file 2>&1 | {
|
||||
line_num=1
|
||||
regions=$kak_timestamp
|
||||
while read line; do
|
||||
case $line in
|
||||
\&*)
|
||||
word=$(echo "$line" | cut -d ' ' -f 2)
|
||||
begin=$(echo "$line" | cut -d ' ' -f 4 | sed 's/:$//')
|
||||
end=$((begin + ${#word}))
|
||||
# echo "echo -debug -- line: $line_num, word: $word, begin: $begin, end: $end"
|
||||
regions="$regions:$line_num.$begin,$line_num.$end|Error"
|
||||
;;
|
||||
'#'*)
|
||||
word=$(echo "$line" | cut -d ' ' -f 2)
|
||||
begin=$(echo "$line" | cut -d ' ' -f 3)
|
||||
end=$((begin + ${#word}))
|
||||
# echo "echo -debug -- line: $line_num, word: $word, begin: $begin, end: $end"
|
||||
regions="$regions:$line_num.$begin,$line_num.$end|Error"
|
||||
;;
|
||||
'') ((++line_num)) ;;
|
||||
*) ;;
|
||||
esac
|
||||
done
|
||||
echo "set buffer spell_regions %{$regions}"
|
||||
}
|
||||
rm -r $(dirname $kak_opt_spell_tmp_file)
|
||||
}
|
||||
}
|
|
@ -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 = ®.declare_option<Vector<String, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
|
||||
else if (parser[0] == "line-flags")
|
||||
opt = ®.declare_option<TimestampedList<LineAndFlag>>(parser[1], docstring, {}, flags);
|
||||
else if (parser[0] == "range-faces")
|
||||
opt = ®.declare_option<TimestampedList<RangeAndFace>>(parser[1], docstring, {}, flags);
|
||||
else
|
||||
throw runtime_error(format("unknown type {}", parser[0]));
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -1441,6 +1483,11 @@ void register_highlighters()
|
|||
"Parameters: <option name> <bg color>\n"
|
||||
"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,
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Kakoune
|
|||
void register_highlighters();
|
||||
|
||||
using LineAndFlag = std::tuple<LineCount, String>;
|
||||
using RangeAndFace = std::tuple<BufferRange, String>;
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user