summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-06-26 15:28:41 +0100
committerMaxime Coste <mawww@kakoune.org>2017-06-26 15:28:41 +0100
commitf41d78083aa8d3883bcd4ed819e6784e09e69dba (patch)
treea67d2432ecf7f2ed499760eb245120dcae0221f5 /src
parentdc378aed7290eb9fd90b752a2841fa2457bb91d0 (diff)
Use the extra_word_chars option in word based normal commands
the completion_extra_word_chars is now gone, superseeded by extra_word_chars that gets used both for completion and for normal mode. Fixes #1304
Diffstat (limited to 'src')
-rw-r--r--src/insert_completer.cc4
-rw-r--r--src/main.cc10
-rw-r--r--src/selectors.cc54
-rw-r--r--src/string.cc4
-rw-r--r--src/unicode.hh12
-rw-r--r--src/word_db.cc4
6 files changed, 56 insertions, 32 deletions
diff --git a/src/insert_completer.cc b/src/insert_completer.cc
index dd259756..087dd00a 100644
--- a/src/insert_completer.cc
+++ b/src/insert_completer.cc
@@ -79,8 +79,8 @@ WordDB& get_word_db(const Buffer& buffer)
template<bool other_buffers>
InsertCompletion complete_word(const SelectionList& sels, const OptionManager& options)
{
- auto& extra_word_char = options["completion_extra_word_char"].get<Vector<Codepoint, MemoryDomain::Options>>();
- auto is_word_pred = [extra_word_char](Codepoint c) { return is_word(c) or contains(extra_word_char, c); };
+ ConstArrayView<Codepoint> extra_word_chars = options["extra_word_chars"].get<Vector<Codepoint, MemoryDomain::Options>>();
+ auto is_word_pred = [extra_word_chars](Codepoint c) { return is_word(c, extra_word_chars); };
const Buffer& buffer = sels.buffer();
BufferCoord cursor_pos = sels.main().cursor();
diff --git a/src/main.cc b/src/main.cc
index 85d79ea7..b5b5cddc 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -48,7 +48,9 @@ static const char* startup_info =
" * `*` will now strip surrounding whitespaces from the selection\n"
" * lint/grep/make next/prev commands have been renamed to more\n"
" explicit names (lint-next-error, grep-previous-match, ...)\n"
-" * ctags commands have been renamed to use the ctags- prefix\n";
+" * ctags commands have been renamed to use the ctags- prefix\n"
+" * completion_extra_word_char option is now extra_word_chars (note the plural form)\n"
+" and is used for word selection commands\n";
struct startup_error : runtime_error
{
@@ -251,7 +253,7 @@ static void check_timeout(const int& timeout)
throw runtime_error{"the minimum acceptable timeout is 50 milliseconds"};
}
-static void check_extra_word_char(const Vector<Codepoint, MemoryDomain::Options>& extra_chars)
+static void check_extra_word_chars(const Vector<Codepoint, MemoryDomain::Options>& extra_chars)
{
if (contains_that(extra_chars, is_blank))
throw runtime_error{"blanks are not accepted for extra completion characters"};
@@ -324,8 +326,8 @@ void register_options()
reg.declare_option("debug", "various debug flags", DebugFlags::None);
reg.declare_option("readonly", "prevent buffers from being modified", false);
- reg.declare_option<Vector<Codepoint, MemoryDomain::Options>, check_extra_word_char>(
- "completion_extra_word_char",
+ reg.declare_option<Vector<Codepoint, MemoryDomain::Options>, check_extra_word_chars>(
+ "extra_word_chars",
"Additional characters to be considered as words for insert completion",
{});
}
diff --git a/src/selectors.cc b/src/selectors.cc
index 62ef8363..597619f8 100644
--- a/src/selectors.cc
+++ b/src/selectors.cc
@@ -36,17 +36,24 @@ Selection utf8_range(const Utf8Iterator& first, const Utf8Iterator& last)
return {first.base().coord(), last.base().coord()};
}
+ConstArrayView<Codepoint> get_extra_word_chars(const Context& context)
+{
+ return context.options()["extra_word_chars"].get<Vector<Codepoint, MemoryDomain::Options>>();
+}
+
}
template<WordType word_type>
Optional<Selection>
select_to_next_word(const Context& context, const Selection& selection)
{
+ auto extra_word_chars = get_extra_word_chars(context);
auto& buffer = context.buffer();
Utf8Iterator begin{buffer.iterator_at(selection.cursor()), buffer};
if (begin+1 == buffer.end())
return {};
- if (categorize<word_type>(*begin) != categorize<word_type>(*(begin+1)))
+ if (categorize<word_type>(*begin, extra_word_chars) !=
+ categorize<word_type>(*(begin+1), extra_word_chars))
++begin;
if (not skip_while(begin, buffer.end(),
@@ -54,10 +61,12 @@ select_to_next_word(const Context& context, const Selection& selection)
return {};
Utf8Iterator end = begin+1;
- if (word_type == Word and is_punctuation(*begin))
+ auto is_word = [&](Codepoint c) { return Kakoune::is_word<word_type>(c, extra_word_chars); };
+
+ if (is_word(*begin))
+ skip_while(end, buffer.end(), is_word);
+ else if (is_punctuation(*begin))
skip_while(end, buffer.end(), is_punctuation);
- else if (is_word<word_type>(*begin))
- skip_while(end, buffer.end(), is_word<word_type>);
skip_while(end, buffer.end(), is_horizontal_blank);
@@ -70,11 +79,13 @@ template<WordType word_type>
Optional<Selection>
select_to_next_word_end(const Context& context, const Selection& selection)
{
+ auto extra_word_chars = get_extra_word_chars(context);
auto& buffer = context.buffer();
Utf8Iterator begin{buffer.iterator_at(selection.cursor()), buffer};
if (begin+1 == buffer.end())
return {};
- if (categorize<word_type>(*begin) != categorize<word_type>(*(begin+1)))
+ if (categorize<word_type>(*begin, extra_word_chars) !=
+ categorize<word_type>(*(begin+1), extra_word_chars))
++begin;
if (not skip_while(begin, buffer.end(),
@@ -83,10 +94,12 @@ select_to_next_word_end(const Context& context, const Selection& selection)
Utf8Iterator end = begin;
skip_while(end, buffer.end(), is_horizontal_blank);
- if (word_type == Word and is_punctuation(*end))
+ auto is_word = [&](Codepoint c) { return Kakoune::is_word<word_type>(c, extra_word_chars); };
+
+ if (is_word(*end))
+ skip_while(end, buffer.end(), is_word);
+ else if (is_punctuation(*end))
skip_while(end, buffer.end(), is_punctuation);
- else if (is_word<word_type>(*end))
- skip_while(end, buffer.end(), is_word<word_type>);
return utf8_range(begin, end-1);
}
@@ -97,23 +110,26 @@ template<WordType word_type>
Optional<Selection>
select_to_previous_word(const Context& context, const Selection& selection)
{
+ auto extra_word_chars = get_extra_word_chars(context);
auto& buffer = context.buffer();
Utf8Iterator begin{buffer.iterator_at(selection.cursor()), buffer};
if (begin == buffer.begin())
return {};
- if (categorize<word_type>(*begin) != categorize<word_type>(*(begin-1)))
+ if (categorize<word_type>(*begin, extra_word_chars) !=
+ categorize<word_type>(*(begin-1), extra_word_chars))
--begin;
skip_while_reverse(begin, buffer.begin(), [](Codepoint c){ return is_eol(c); });
Utf8Iterator end = begin;
+ auto is_word = [&](Codepoint c) { return Kakoune::is_word<word_type>(c, extra_word_chars); };
+
bool with_end = skip_while_reverse(end, buffer.begin(), is_horizontal_blank);
- if (word_type == Word and is_punctuation(*end))
+ if (is_word(*end))
+ with_end = skip_while_reverse(end, buffer.begin(), is_word);
+ else if (is_punctuation(*end))
with_end = skip_while_reverse(end, buffer.begin(), is_punctuation);
- else if (is_word<word_type>(*end))
- with_end = skip_while_reverse(end, buffer.begin(), is_word<word_type>);
-
return utf8_range(begin, with_end ? end : end+1);
}
template Optional<Selection> select_to_previous_word<WordType::Word>(const Context&, const Selection&);
@@ -124,21 +140,25 @@ Optional<Selection>
select_word(const Context& context, const Selection& selection,
int count, ObjectFlags flags)
{
+ auto extra_word_chars = get_extra_word_chars(context);
auto& buffer = context.buffer();
+
+ auto is_word = [&](Codepoint c) { return Kakoune::is_word<word_type>(c, extra_word_chars); };
+
Utf8Iterator first{buffer.iterator_at(selection.cursor()), buffer};
- if (not is_word<word_type>(*first))
+ if (not is_word(*first))
return {};
Utf8Iterator last = first;
if (flags & ObjectFlags::ToBegin)
{
- skip_while_reverse(first, buffer.begin(), is_word<word_type>);
- if (not is_word<word_type>(*first))
+ skip_while_reverse(first, buffer.begin(), is_word);
+ if (not is_word(*first))
++first;
}
if (flags & ObjectFlags::ToEnd)
{
- skip_while(last, buffer.end(), is_word<word_type>);
+ skip_while(last, buffer.end(), is_word);
if (not (flags & ObjectFlags::Inner))
skip_while(last, buffer.end(), is_horizontal_blank);
--last;
diff --git a/src/string.cc b/src/string.cc
index 89b7c3fe..1ab56481 100644
--- a/src/string.cc
+++ b/src/string.cc
@@ -429,7 +429,7 @@ Vector<StringView> wrap_lines(StringView text, ColumnCount max_width)
Vector<StringView> lines;
while (it != end)
{
- const CharCategories cat = categorize(*it);
+ const CharCategories cat = categorize(*it, {});
if (cat == CharCategories::EndOfLine)
{
lines.emplace_back(line_begin.base(), it.base());
@@ -438,7 +438,7 @@ Vector<StringView> wrap_lines(StringView text, ColumnCount max_width)
}
Utf8It word_end = it+1;
- while (word_end != end and categorize(*word_end) == cat)
+ while (word_end != end and categorize(*word_end, {}) == cat)
++word_end;
while (word_end > line_begin and
diff --git a/src/unicode.hh b/src/unicode.hh
index eade3510..ba340b3a 100644
--- a/src/unicode.hh
+++ b/src/unicode.hh
@@ -6,6 +6,8 @@
#include <locale>
#include "units.hh"
+#include "array_view.hh"
+#include "containers.hh"
namespace Kakoune
{
@@ -30,13 +32,13 @@ inline bool is_blank(Codepoint c) noexcept
enum WordType { Word, WORD };
template<WordType word_type = Word>
-inline bool is_word(Codepoint c) noexcept
+inline bool is_word(Codepoint c, ConstArrayView<Codepoint> extra_word_chars = {}) noexcept
{
- return c == '_' or iswalnum((wchar_t)c);
+ return c == '_' or iswalnum((wchar_t)c) or contains(extra_word_chars, c);
}
template<>
-inline bool is_word<WORD>(Codepoint c) noexcept
+inline bool is_word<WORD>(Codepoint c, ConstArrayView<Codepoint>) noexcept
{
return not is_blank(c);
}
@@ -65,13 +67,13 @@ enum class CharCategories
};
template<WordType word_type = Word>
-inline CharCategories categorize(Codepoint c) noexcept
+inline CharCategories categorize(Codepoint c, ConstArrayView<Codepoint> extra_word_chars) noexcept
{
if (is_eol(c))
return CharCategories::EndOfLine;
if (is_horizontal_blank(c))
return CharCategories::Blank;
- if (word_type == WORD or is_word(c))
+ if (word_type == WORD or is_word(c, extra_word_chars))
return CharCategories::Word;
return CharCategories::Punctuation;
}
diff --git a/src/word_db.cc b/src/word_db.cc
index a486b86b..8bcfa250 100644
--- a/src/word_db.cc
+++ b/src/word_db.cc
@@ -32,7 +32,7 @@ static WordList get_words(StringView content, ConstArrayView<Codepoint> extra_wo
static ConstArrayView<Codepoint> get_extra_word_chars(const Buffer& buffer)
{
- return buffer.options()["completion_extra_word_char"].get<Vector<Codepoint, MemoryDomain::Options>>();
+ return buffer.options()["extra_word_chars"].get<Vector<Codepoint, MemoryDomain::Options>>();
}
void WordDB::add_words(StringView line)
@@ -147,7 +147,7 @@ void WordDB::update_db()
void WordDB::on_option_changed(const Option& option)
{
- if (option.name() == "completion_extra_word_char")
+ if (option.name() == "extra_word_chars")
rebuild_db();
}