diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-06-26 15:28:41 +0100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-06-26 15:28:41 +0100 |
| commit | f41d78083aa8d3883bcd4ed819e6784e09e69dba (patch) | |
| tree | a67d2432ecf7f2ed499760eb245120dcae0221f5 /src | |
| parent | dc378aed7290eb9fd90b752a2841fa2457bb91d0 (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.cc | 4 | ||||
| -rw-r--r-- | src/main.cc | 10 | ||||
| -rw-r--r-- | src/selectors.cc | 54 | ||||
| -rw-r--r-- | src/string.cc | 4 | ||||
| -rw-r--r-- | src/unicode.hh | 12 | ||||
| -rw-r--r-- | src/word_db.cc | 4 |
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(); } |
