[hackers][vis][PATCH] Handle quote matching in its own function

From: Silvan Jegen <s.jegen_AT_gmail.com>
Date: Mon, 15 Feb 2016 16:01:48 +0100

Unlike other paired characters neither of the quote types allow for the
search for the closing occurrence to be optimised because there is no
directionality implied. This means theoretically we always have to start
from the beginning of a file to check whether all the quotes until the
occurrence of the one in question have been properly closed before we
can say which one is the closing occurrence of the quote.

This is the justification for introducing this new function that
duplicates some code. Instead of searching from the beginning of a
file we start our search for the corresponding quote character at
an arbitrarily chosen offset of 500 bytes before the occurrence in
question.
---
Consider this to be a bug report for a pet peeve of mine. When you
position the cursor at line 797 of vis.c in vis on the quote after
__DATE__ the quote highlighting will be wrong. The text motion for
"select inner quote" is wrong as well but I think it makes more sense
there to select the text between the quotes instead of selecting nothing
only because the quotes are not actually corresponding to each other.
This patch fixes the highlighting case but it may be overkill for such
marginal issue.
 text-motions.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/text-motions.c b/text-motions.c
index 298d4ac..20218fd 100644
--- a/text-motions.c
+++ b/text-motions.c
_AT_@ -607,6 +607,28 @@ size_t text_bracket_match(Text *txt, size_t pos) {
 	return text_bracket_match_symbol(txt, pos, NULL);
 }
 
+size_t text_bracket_match_quote(Text *txt, size_t pos, char q) {
+	size_t lastqpos = pos;
+	size_t prevpos = pos > 500 ? pos - 500 : 0;
+	char c;
+	bool closed = true;
+
+	Iterator it = text_iterator_get(txt, prevpos);
+	text_iterator_byte_get(&it, &c);
+	do {
+		if (it.pos == pos && !closed)
+			return lastqpos;
+		if (c == q && it.pos != pos) {
+			if (it.pos > pos)
+				return it.pos;
+			lastqpos = it.pos;
+			closed = !closed;
+		}
+	} while (text_iterator_byte_next(&it, &c));
+
+	return pos; /* no match found */
+}
+
 size_t text_bracket_match_symbol(Text *txt, size_t pos, const char *symbols) {
 	int direction, count = 1;
 	char search, current, c;
_AT_@ -627,19 +649,7 @@ size_t text_bracket_match_symbol(Text *txt, size_t pos, const char *symbols) {
 	case '>': search = '<'; direction = -1; break;
 	case '"':
 	case '`':
-	case '\'': {
-		char special[] = " \n)}]>.,:;";
-		search = current;
-		direction = 1;
-		if (text_iterator_byte_next(&it, &c)) {
-			/* if a single or double quote is followed by
-			 * a special character, search backwards */
-			if (memchr(special, c, sizeof(special)))
-				direction = -1;
-			text_iterator_byte_prev(&it, NULL);
-		}
-		break;
-	}
+	case '\'': return text_bracket_match_quote(txt, pos, current);
 	default: return pos;
 	}
 
-- 
2.7.1
Received on Mon Feb 15 2016 - 16:01:48 CET

This archive was generated by hypermail 2.3.0 : Mon Feb 15 2016 - 16:12:13 CET