From c1a7759e7faa298f613a43f69689568df9cf059e Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 26 May 2014 21:33:31 +0100 Subject: [PATCH 1/2] Tweak inner indent object code Inner indent is now the set of lines whose indent is >= current line indent, triming lines containing only whitespaces at start and end. Fixes #140 --- src/selectors.cc | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/selectors.cc b/src/selectors.cc index 5d98be52..20e4440e 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -352,6 +352,14 @@ static CharCount get_indent(const String& str, int tabstop) return indent; } +static bool is_only_whitespaces(const String& str) +{ + auto it = str.begin(); + skip_while(it, str.end(), + [](char c){ return c == ' ' or c == '\t' or c == '\n'; }); + return it == str.end(); +} + Selection select_whole_indent(const Buffer& buffer, const Selection& selection, ObjectFlags flags) { int tabstop = buffer.options()["tabstop"].get(); @@ -368,26 +376,22 @@ Selection select_whole_indent(const Buffer& buffer, const Selection& selection, LineCount end_line = line + 1; if (flags & ObjectFlags::ToEnd) { - LineCount end = buffer.line_count(); + const LineCount end = buffer.line_count(); while (end_line < end and (buffer[end_line] == "\n" or get_indent(buffer[end_line], tabstop) >= indent)) ++end_line; } --end_line; - ByteCoord first = begin_line; - // keep the first line indent in inner mode + // remove only whitespaces lines in inner mode if (flags & ObjectFlags::Inner) { - CharCount i = 0; - for (; i < indent; ++first.column) - { - auto c = buffer.byte_at(first); - if (c == ' ') - ++i; - if (c == '\t') - i = (i / tabstop + 1) * tabstop; - } + while (begin_line < end_line and + is_only_whitespaces(buffer[begin_line])) + ++begin_line; + while (begin_line < end_line and + is_only_whitespaces(buffer[end_line])) + --end_line; } - return Selection{first, {end_line, buffer[end_line].length() - 1}}; + return Selection{begin_line, {end_line, buffer[end_line].length() - 1}}; } Selection select_whole_lines(const Buffer& buffer, const Selection& selection) From 9aa38a1ea072f78cb5a1f099b7b4db241de6d96d Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 26 May 2014 21:44:57 +0100 Subject: [PATCH 2/2] Rename select_whole_.* to just select_.* --- src/normal.cc | 14 +++++++------- src/selectors.cc | 12 ++++++------ src/selectors.hh | 26 +++++++++++++++++--------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/normal.cc b/src/normal.cc index 062f512c..882fbc3a 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -913,11 +913,11 @@ void select_object(Context& context, int param) Codepoint key; Selection (*func)(const Buffer&, const Selection&, ObjectFlags); } selectors[] = { - { 'w', select_whole_word }, - { 'W', select_whole_word }, - { 's', select_whole_sentence }, - { 'p', select_whole_paragraph }, - { 'i', select_whole_indent }, + { 'w', select_word }, + { 'W', select_word }, + { 's', select_sentence }, + { 'p', select_paragraph }, + { 'i', select_indent }, }; for (auto& sel : selectors) { @@ -1387,7 +1387,7 @@ KeyMap keymap = { '.', repeat_last_insert }, - { '%', [](Context& context, int) { select_whole_buffer(context.buffer(), context.selections()); } }, + { '%', [](Context& context, int) { select_buffer(context.buffer(), context.selections()); } }, { ':', command }, { '|', pipe }, @@ -1417,7 +1417,7 @@ KeyMap keymap = { 'x', repeated(make_select(select_line)) }, { 'X', repeated(make_select(select_line)) }, - { alt('x'), make_select(select_whole_lines) }, + { alt('x'), make_select(select_lines) }, { alt('X'), make_select(trim_partial_lines) }, { 'm', make_select(select_matching) }, diff --git a/src/selectors.cc b/src/selectors.cc index 20e4440e..94c4fac7 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -223,7 +223,7 @@ static bool is_end_of_sentence(char c) return c == '.' or c == ';' or c == '!' or c == '?'; } -Selection select_whole_sentence(const Buffer& buffer, const Selection& selection, ObjectFlags flags) +Selection select_sentence(const Buffer& buffer, const Selection& selection, ObjectFlags flags) { BufferIterator first = buffer.iterator_at(selection.cursor()); @@ -284,7 +284,7 @@ Selection select_whole_sentence(const Buffer& buffer, const Selection& selection : Selection{last.coord(), first.coord()}; } -Selection select_whole_paragraph(const Buffer& buffer, const Selection& selection, ObjectFlags flags) +Selection select_paragraph(const Buffer& buffer, const Selection& selection, ObjectFlags flags) { BufferIterator first = buffer.iterator_at(selection.cursor()); @@ -360,7 +360,7 @@ static bool is_only_whitespaces(const String& str) return it == str.end(); } -Selection select_whole_indent(const Buffer& buffer, const Selection& selection, ObjectFlags flags) +Selection select_indent(const Buffer& buffer, const Selection& selection, ObjectFlags flags) { int tabstop = buffer.options()["tabstop"].get(); LineCount line = selection.cursor().line; @@ -394,7 +394,7 @@ Selection select_whole_indent(const Buffer& buffer, const Selection& selection, return Selection{begin_line, {end_line, buffer[end_line].length() - 1}}; } -Selection select_whole_lines(const Buffer& buffer, const Selection& selection) +Selection select_lines(const Buffer& buffer, const Selection& selection) { // no need to be utf8 aware for is_eol as we only use \n as line seperator BufferIterator first = buffer.iterator_at(selection.anchor()); @@ -419,7 +419,7 @@ Selection select_whole_lines(const Buffer& buffer, const Selection& selection) Selection trim_partial_lines(const Buffer& buffer, const Selection& selection) { - // same as select_whole_lines + // same as select_lines BufferIterator first = buffer.iterator_at(selection.anchor()); BufferIterator last = buffer.iterator_at(selection.cursor()); BufferIterator& to_line_start = first <= last ? first : last; @@ -433,7 +433,7 @@ Selection trim_partial_lines(const Buffer& buffer, const Selection& selection) return Selection(first.coord(), last.coord()); } -void select_whole_buffer(const Buffer& buffer, SelectionList& selections) +void select_buffer(const Buffer& buffer, SelectionList& selections) { selections = SelectionList{ Selection({0,0}, buffer.back_coord()) }; } diff --git a/src/selectors.hh b/src/selectors.hh index b28febef..e6a3022a 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -159,7 +159,7 @@ constexpr ObjectFlags operator|(ObjectFlags lhs, ObjectFlags rhs) { return (ObjectFlags)((int)lhs | (int) rhs); } template -Selection select_whole_word(const Buffer& buffer, const Selection& selection, ObjectFlags flags) +Selection select_word(const Buffer& buffer, const Selection& selection, ObjectFlags flags) { Utf8Iterator first = buffer.iterator_at(selection.cursor()); Utf8Iterator last = first; @@ -200,16 +200,24 @@ Selection select_whole_word(const Buffer& buffer, const Selection& selection, Ob : utf8_range(last, first); } -Selection select_whole_sentence(const Buffer& buffer, const Selection& selection, - ObjectFlags flags); -Selection select_whole_paragraph(const Buffer& buffer, const Selection& selection, - ObjectFlags flags); -Selection select_whole_indent(const Buffer& buffer, const Selection& selection, - ObjectFlags flags); -Selection select_whole_lines(const Buffer& buffer, const Selection& selection); -void select_whole_buffer(const Buffer& buffer, SelectionList& selections); +Selection select_sentence(const Buffer& buffer, + const Selection& selection, + ObjectFlags flags); + +Selection select_paragraph(const Buffer& buffer, + const Selection& selection, + ObjectFlags flags); + +Selection select_indent(const Buffer& buffer, + const Selection& selection, + ObjectFlags flags); + +Selection select_lines(const Buffer& buffer, const Selection& selection); + Selection trim_partial_lines(const Buffer& buffer, const Selection& selection); +void select_buffer(const Buffer& buffer, SelectionList& selections); + enum Direction { Forward, Backward }; using MatchResults = boost::match_results;