aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-04-10 20:58:48 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-04-10 21:34:14 +0200
commit041d162922e679723110e362eeaf6cbdd9892ca9 (patch)
treec3ebc9bcaf051a3390a2c3e6cb2122d13d83262a
parent5bb264e8fc771ef5f24afa531231cbde5066c162 (diff)
downloadvis-041d162922e679723110e362eeaf6cbdd9892ca9.tar.gz
vis-041d162922e679723110e362eeaf6cbdd9892ca9.tar.xz
Highlight matching cursor symbol
-rw-r--r--text-motions.c9
-rw-r--r--text-motions.h2
-rw-r--r--window.c46
3 files changed, 41 insertions, 16 deletions
diff --git a/text-motions.c b/text-motions.c
index 00e3cc8..d2f272c 100644
--- a/text-motions.c
+++ b/text-motions.c
@@ -329,12 +329,17 @@ size_t text_paragraph_prev(Text *txt, size_t pos) {
}
size_t text_bracket_match(Text *txt, size_t pos) {
+ return text_bracket_match_except(txt, pos, NULL);
+}
+
+size_t text_bracket_match_except(Text *txt, size_t pos, const char *except) {
int direction, count = 1;
char search, current, c;
Iterator it = text_iterator_get(txt, pos);
if (!text_iterator_byte_get(&it, &current))
return pos;
-
+ if (except && memchr(except, current, strlen(except)))
+ return pos;
switch (current) {
case '(': search = ')'; direction = 1; break;
case ')': search = '('; direction = -1; break;
@@ -347,7 +352,7 @@ size_t text_bracket_match(Text *txt, size_t pos) {
case '"':
case '`':
case '\'': {
- char special[] = " \n)}]>.,";
+ char special[] = " \n)}]>.,:;";
search = current;
direction = 1;
if (text_iterator_byte_next(&it, &c)) {
diff --git a/text-motions.h b/text-motions.h
index dca9fac..e2dc064 100644
--- a/text-motions.h
+++ b/text-motions.h
@@ -76,6 +76,8 @@ size_t text_section_prev(Text*, size_t pos);
*/
/* search coresponding '(', ')', '{', '}', '[', ']', '>', '<', '"', ''' */
size_t text_bracket_match(Text*, size_t pos);
+/* same as above but ignore symbols contained in last argument */
+size_t text_bracket_match_except(Text*, size_t pos, const char *except);
/* search the given regex pattern in either forward or backward direction,
* starting from pos. does wrap around if no match was found. */
diff --git a/window.c b/window.c
index fe5eac3..1f22988 100644
--- a/window.c
+++ b/window.c
@@ -30,6 +30,7 @@ typedef struct { /* cursor position */
Filepos pos; /* in bytes from the start of the file */
int row, col; /* in terms of zero based screen coordinates */
Line *line; /* screen line on which cursor currently resides */
+ bool highlighted; /* true e.g. when cursor is on a bracket */
} Cursor;
struct Win { /* window showing part of a file */
@@ -234,20 +235,6 @@ CursorPos window_cursor_getpos(Win *win) {
return pos;
}
-/* place the cursor according to the screen coordinates in win->{row,col} and
- * fire user callback. if a selection is active, redraw the window to reflect
- * its changes. */
-static size_t window_cursor_update(Win *win) {
- Cursor *cursor = &win->cursor;
- if (win->sel.start != EPOS) {
- win->sel.end = cursor->pos;
- window_draw(win);
- }
- if (win->ui)
- win->ui->cursor_to(win->ui, cursor->col, cursor->row);
- return cursor->pos;
-}
-
/* snyc current cursor position with internal Line/Cell structures */
static void window_cursor_sync(Win *win) {
int row = 0, col = 0;
@@ -279,6 +266,37 @@ static void window_cursor_sync(Win *win) {
win->cursor.col = col;
}
+/* place the cursor according to the screen coordinates in win->{row,col} and
+ * fire user callback. if a selection is active, redraw the window to reflect
+ * its changes. */
+static size_t window_cursor_update(Win *win) {
+ Cursor *cursor = &win->cursor;
+ if (win->sel.start != EPOS) {
+ win->sel.end = cursor->pos;
+ window_draw(win);
+ } else if (win->ui && win->syntax) {
+ size_t pos = cursor->pos;
+ size_t pos_match = text_bracket_match_except(win->text, pos, "<>");
+ if (pos != pos_match && win->start <= pos_match && pos_match < win->end) {
+ if (cursor->highlighted)
+ window_draw(win); /* clear active highlighting */
+ cursor->pos = pos_match;
+ window_cursor_sync(win);
+ cursor->line->cells[cursor->col].attr |= A_REVERSE;
+ cursor->pos = pos;
+ window_cursor_sync(win);
+ win->ui->draw_text(win->ui, win->topline);
+ cursor->highlighted = true;
+ } else if (cursor->highlighted) {
+ cursor->highlighted = false;
+ window_draw(win);
+ }
+ }
+ if (win->ui)
+ win->ui->cursor_to(win->ui, cursor->col, cursor->row);
+ return cursor->pos;
+}
+
/* move the cursor to the character at pos bytes from the begining of the file.
* if pos is not in the current viewport, redraw the window to make it visible */
void window_cursor_to(Win *win, size_t pos) {