aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-04-21 08:06:55 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-04-21 11:05:45 +0200
commitaca46a0da8969f15d9356c149687f961b6852516 (patch)
treeffc96967c3110d9a684fec302973845e7de2b23d
parent1b1590ed4f33f3da16ff648c7e0f1a45db6811dd (diff)
downloadvis-aca46a0da8969f15d9356c149687f961b6852516.tar.gz
vis-aca46a0da8969f15d9356c149687f961b6852516.tar.xz
Clean up to/till movements
-rw-r--r--editor.h2
-rw-r--r--text-motions.c18
-rw-r--r--text-motions.h4
-rw-r--r--vis.c34
4 files changed, 40 insertions, 18 deletions
diff --git a/editor.h b/editor.h
index bdf2865..2466f1f 100644
--- a/editor.h
+++ b/editor.h
@@ -108,7 +108,6 @@ typedef struct { /** collects all information until an operator is e
const TextObject *textobj;
Register *reg;
int mark;
- Key key;
Arg arg;
} Action;
@@ -230,6 +229,7 @@ struct Editor {
EditorWin *prompt_window; /* window which was focused before prompt was shown */
char prompt_type; /* command ':' or search '/','?' prompt */
Regex *search_pattern; /* last used search pattern */
+ char search_char[8]; /* last used character to search for via 'f', 'F', 't', 'T' */
int tabwidth; /* how many spaces should be used to display a tab */
bool expandtab; /* whether typed tabs should be converted to spaces */
bool autoindent; /* whether indentation should be copied from previous line on newline */
diff --git a/text-motions.c b/text-motions.c
index d2f272c..59b92e0 100644
--- a/text-motions.c
+++ b/text-motions.c
@@ -45,11 +45,12 @@ size_t text_char_prev(Text *txt, size_t pos) {
return it.pos;
}
-size_t text_find_char_next(Text *txt, size_t pos, const char *s, size_t len) {
- char c;
- size_t matched = 0;
+size_t text_find_next(Text *txt, size_t pos, const char *s) {
+ if (!s)
+ return pos;
+ size_t len = strlen(s), matched = 0;
Iterator it = text_iterator_get(txt, pos);
- while (matched < len && text_iterator_byte_get(&it, &c)) {
+ for (char c; matched < len && text_iterator_byte_get(&it, &c); ) {
if (c == s[matched])
matched++;
else
@@ -59,13 +60,14 @@ size_t text_find_char_next(Text *txt, size_t pos, const char *s, size_t len) {
return matched == len ? it.pos - len : pos;
}
-size_t text_find_char_prev(Text *txt, size_t pos, const char *s, size_t len) {
- char c;
- size_t matched = len - 1;
+size_t text_find_prev(Text *txt, size_t pos, const char *s) {
+ if (!s)
+ return pos;
+ size_t len = strlen(s), matched = len - 1;
Iterator it = text_iterator_get(txt, pos);
if (len == 0)
return pos;
- while (text_iterator_byte_get(&it, &c)) {
+ for (char c; text_iterator_byte_get(&it, &c); ) {
if (c == s[matched]) {
if (matched == 0)
break;
diff --git a/text-motions.h b/text-motions.h
index e2dc064..64f68bf 100644
--- a/text-motions.h
+++ b/text-motions.h
@@ -18,8 +18,8 @@ size_t text_char_prev(Text*, size_t pos);
/* find the given substring either in forward or backward direction.
* does not wrap around at file start / end. if no match is found return
* original position */
-size_t text_find_char_next(Text*, size_t pos, const char *s, size_t len);
-size_t text_find_char_prev(Text*, size_t pos, const char *s, size_t len);
+size_t text_find_next(Text*, size_t pos, const char *s);
+size_t text_find_prev(Text*, size_t pos, const char *s);
/* begin finish end next
* v v v v
diff --git a/vis.c b/vis.c
index 81d1b7d..1510fce 100644
--- a/vis.c
+++ b/vis.c
@@ -649,21 +649,41 @@ static size_t mark_line_goto(const Arg *arg) {
}
static size_t to(const Arg *arg) {
- return text_find_char_next(vis->win->text->data, window_cursor_get(vis->win->win) + 1,
- vis->action.key.str, strlen(vis->action.key.str));
+ char c;
+ Text *txt = vis->win->text->data;
+ size_t pos = window_cursor_get(vis->win->win);
+ size_t hit = text_find_next(txt, pos+1, vis->search_char);
+ if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0])
+ return pos;
+ return hit;
}
static size_t till(const Arg *arg) {
- return text_char_prev(vis->win->text->data, to(arg));
+ size_t pos = window_cursor_get(vis->win->win);
+ size_t hit = to(arg);
+ if (hit != pos)
+ return text_char_prev(vis->win->text->data, hit);
+ return pos;
}
static size_t to_left(const Arg *arg) {
- return text_find_char_prev(vis->win->text->data, window_cursor_get(vis->win->win) - 1,
- vis->action.key.str, strlen(vis->action.key.str));
+ char c;
+ Text *txt = vis->win->text->data;
+ size_t pos = window_cursor_get(vis->win->win);
+ if (pos == 0)
+ return pos;
+ size_t hit = text_find_prev(txt, pos-1, vis->search_char);
+ if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0])
+ return pos;
+ return hit;
}
static size_t till_left(const Arg *arg) {
- return text_char_next(vis->win->text->data, to_left(arg));
+ size_t pos = window_cursor_get(vis->win->win);
+ size_t hit = to_left(arg);
+ if (hit != pos)
+ return text_char_next(vis->win->text->data, hit);
+ return pos;
}
static size_t line(const Arg *arg) {
@@ -822,7 +842,7 @@ static void movement_key(const Arg *arg) {
action_reset(&vis->action);
return;
}
- vis->action.key = k;
+ strncpy(vis->search_char, k.str, sizeof(vis->search_char));
vis->action.movement = &moves[arg->i];
action_do(&vis->action);
}