summaryrefslogtreecommitdiff
path: root/src/selectors.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2011-09-23 09:17:19 +0000
committerMaxime Coste <frrrwww@gmail.com>2011-09-23 09:17:19 +0000
commit662ba0c904530fff306eaafe5fa347fee71ff67a (patch)
treea42843cfe337afe627bbe6c8a22c4c8d6c290870 /src/selectors.cc
parent5ca901644f98f88d9fcfd751d8d6ee580de0147d (diff)
Selection: do not use [begin, end) semantics but [first, last]
selections are now defined with inclusive iterators, which means that Selection(cursor, cursor) is a valid selection of the charateter pointed by cursor. On the user interface side, that means that the cursor is now part of the selection, selectors were adapted to this behavior (and word selectors are now much more intuitive)
Diffstat (limited to 'src/selectors.cc')
-rw-r--r--src/selectors.cc85
1 files changed, 59 insertions, 26 deletions
diff --git a/src/selectors.cc b/src/selectors.cc
index c8377079..2b73d370 100644
--- a/src/selectors.cc
+++ b/src/selectors.cc
@@ -33,6 +33,22 @@ static bool is_punctuation(char c)
return not (is_word(c) or is_blank(c));
}
+enum class CharCategories
+{
+ Blank,
+ Word,
+ Punctuation,
+};
+
+static CharCategories categorize(char c)
+{
+ if (is_word(c))
+ return CharCategories::Word;
+ if (is_blank(c))
+ return CharCategories::Blank;
+ return CharCategories::Punctuation;
+}
+
template<typename T>
void skip_while(BufferIterator& it, T condition)
{
@@ -50,55 +66,72 @@ void skip_while_reverse(BufferIterator& it, T condition)
Selection select_to_next_word(const BufferIterator& cursor)
{
- BufferIterator end = cursor;
+ BufferIterator begin = cursor;
+ BufferIterator end = cursor+1;
- if (is_word(*end))
- skip_while(end, is_word);
- else if (is_punctuation(*end))
+ if (categorize(*begin) != categorize(*end))
+ {
+ ++begin;
+ ++end;
+ }
+
+ if (is_punctuation(*begin))
skip_while(end, is_punctuation);
+ if (is_word(*begin))
+ skip_while(end, is_word);
+
skip_while(end, is_blank);
- return Selection(cursor, end);
+ return Selection(begin, end-1);
}
Selection select_to_next_word_end(const BufferIterator& cursor)
{
- BufferIterator end = cursor;
+ BufferIterator begin = cursor;
+ BufferIterator end = cursor+1;
+
+ if (categorize(*begin) != categorize(*end))
+ ++begin;
skip_while(end, is_blank);
- if (is_word(*end))
- skip_while(end, is_word);
- else if (is_punctuation(*end))
+ if (is_punctuation(*end))
skip_while(end, is_punctuation);
+ else if (is_word(*end))
+ skip_while(end, is_word);
- return Selection(cursor, end);
+ return Selection(begin, end-1);
}
Selection select_to_previous_word(const BufferIterator& cursor)
{
- BufferIterator end = cursor;
+ BufferIterator begin = cursor;
+ BufferIterator end = cursor-1;
+
+ if (categorize(*begin) != categorize(*end))
+ --begin;
skip_while_reverse(end, is_blank);
- if (is_word(*end))
- skip_while_reverse(end, is_word);
- else if (is_punctuation(*end))
+
+ if (is_punctuation(*end))
skip_while_reverse(end, is_punctuation);
+ else if (is_word(*end))
+ skip_while_reverse(end, is_word);
- return Selection(cursor, end);
+ return Selection(begin, end+1);
}
Selection select_line(const BufferIterator& cursor)
{
- BufferIterator begin = cursor;
- while (not begin.is_begin() and *(begin -1) != '\n')
- --begin;
-
- BufferIterator end = cursor;
- while (not end.is_end() and *end != '\n')
- ++end;
- return Selection(begin, end + 1);
+ BufferIterator first = cursor;
+ while (not first.is_begin() and *(first - 1) != '\n')
+ --first;
+
+ BufferIterator last = cursor;
+ while (not (last + 1).is_end() and *last != '\n')
+ ++last;
+ return Selection(first, last);
}
Selection move_select(Window& window, const BufferIterator& cursor, const WindowCoord& offset)
@@ -136,7 +169,7 @@ Selection select_matching(const BufferIterator& cursor)
if (*it == opening)
++level;
else if (*it == closing and --level == 0)
- return Selection(begin, it+1);
+ return Selection(begin, it);
++it;
}
@@ -151,7 +184,7 @@ Selection select_matching(const BufferIterator& cursor)
if (*it == closing)
++level;
else if (*it == opening and --level == 0)
- return Selection(begin, it-1);
+ return Selection(begin, it);
--it;
}
}
@@ -163,7 +196,7 @@ Selection select_to(const BufferIterator& cursor, char c)
BufferIterator end = cursor + 1;
skip_while(end, [c](char cur) { return not is_eol(cur) and cur != c; });
if (not is_eol(*end))
- return Selection(cursor, end);
+ return Selection(cursor, end-1);
return Selection(cursor, cursor);
}