diff options
| author | Quentin Carbonneaux | 2014-11-17 13:52:44 -0500 |
|---|---|---|
| committer | Quentin Carbonneaux | 2014-11-17 13:55:53 -0500 |
| commit | 14769dc6357f05fc18c9607515c2312d9b7905a1 (patch) | |
| tree | 3cb86a7b84d6e6f44c6086d6f3fddf9f772733b0 | |
| parent | 6020f9b426d3d62bfdc897a986c00da65a59ccc5 (diff) | |
add reverse search command N
| -rw-r--r-- | edit.c | 11 | ||||
| -rw-r--r-- | edit.h | 2 | ||||
| -rw-r--r-- | exec.c | 11 | ||||
| -rw-r--r-- | exec.h | 2 | ||||
| -rw-r--r-- | vicmd.w | 9 |
5 files changed, 18 insertions, 17 deletions
@@ -344,18 +344,19 @@ eb_getmark(EBuf *eb, Rune name) } unsigned -eb_look(EBuf *eb, unsigned p, Rune *str, unsigned n) +eb_look(EBuf *eb, unsigned p0, Rune *str, unsigned n, int rev) { - unsigned i, j; + unsigned i, j, l, x; assert(str); - while (p<eb->b.limbo) { - i = p++; + l = eb->b.limbo; + for (x=1; x<l; x++) { + i = (p0 + (rev ? l-x : x)) % l; j = 0; while (buf_get(&eb->b, i++) == str[j++]) if (j == n) - return p-1; + return i-n; } return -1u; } @@ -39,5 +39,5 @@ void eb_undo(EBuf *, int, unsigned *); void eb_yank(EBuf *, unsigned, unsigned, YBuf *); void eb_setmark(EBuf *, Rune, unsigned); unsigned eb_getmark(EBuf *, Rune); -unsigned eb_look(EBuf *, unsigned, Rune *, unsigned); +unsigned eb_look(EBuf *, unsigned, Rune *, unsigned, int); void eb_write(EBuf *, int); @@ -83,18 +83,17 @@ ex_run(W *w, unsigned p0) /* ex_look - Look for a string [s] in window [w] and jump * to the first match after the cursor position. The caller - * is responsible to free the [s] buffer. + * is responsible to free the [s] buffer. If [rev] is true + * the search goes backward. */ int -ex_look(W *w, Rune *s, unsigned n) +ex_look(W *w, Rune *s, unsigned n, int rev) { unsigned p; if (n == 0) return 1; - p = eb_look(w->eb, w->cu+1, s, n); - if (p == -1u) - p = eb_look(w->eb, 0, s, n); + p = eb_look(w->eb, w->cu, s, n, rev); if (p != -1u) { w->cu = p; eb_setmark(w->eb, SelBeg, p); @@ -351,7 +350,7 @@ look(W *w, EBuf *eb, unsigned p0) return 0; p1 = 1 + skipb(&eb->b, buf_eol(&eb->b, p0) - 1, -1); eb_yank(eb, p0, p1, &b); - e = ex_look(w, b.r, b.nr); + e = ex_look(w, b.r, b.nr, 0); free(b.r); if (e) { err(eb, p0, errstr); @@ -1,5 +1,5 @@ int ex_run(W *, unsigned); -int ex_look(W *, Rune *, unsigned); +int ex_look(W *, Rune *, unsigned, int); int ex_put(EBuf *, char *); int ex_get(W *, char *); void ex_cancel(Task *); @@ -858,7 +858,7 @@ the annonymous yank buffer. When a match is found the selection is set to the matched text. If the search hits limbo it wraps around. @<Subr...@>= -static int m_n(int ismotion, Cmd c, Motion *m) +static int m_nN(int ismotion, Cmd c, Motion *m) { YBuf b = {0, 0, 0, 0}, *pb = &yannon; int err = 0; @@ -869,7 +869,7 @@ static int m_n(int ismotion, Cmd c, Motion *m) if (s0 < s1 && s0 != -1u && s1 != -1u) eb_yank(curwin->eb, s0, s1, pb = &b); while (c.count--) - err |= ex_look(curwin, pb->r, pb->nr); + err |= ex_look(curwin, pb->r, pb->nr, c.chr == 'N'); free(b.r); m->end = curwin->cu; if (ismotion) @@ -878,7 +878,7 @@ static int m_n(int ismotion, Cmd c, Motion *m) } @ @<Predecl...@>= -static int m_n(int, Cmd, Motion *); +static int m_nN(int, Cmd, Motion *); @ Because the search functionality is different, the \./ command is free to use. We reuse it as a motion that designates the whole selection. @@ -1306,7 +1306,8 @@ union { ['%'] = Mtn(0, m_match), ['G'] = Mtn(CZeroCount, m_G),@/ ['H'] = Mtn(0, m_HML), ['L'] = Mtn(0, m_HML),@/ ['M'] = Mtn(0, m_HML),@/ -['n'] = Mtn(0, m_n), ['/'] = Mtn(0, m_sel),@/ +['n'] = Mtn(0, m_nN), ['N'] = Mtn(0, m_nN),@/ +['/'] = Mtn(0, m_sel),@/ ['\''] = Mtn(CHasArg, m_mark), ['`'] = Mtn(CHasArg, m_mark),@/ ['d'] = Act(CHasMotion, a_d), ['x'] = Act(0, a_d),@/ ['c'] = Act(CHasMotion, a_c), ['y'] = Act(CHasMotion, a_y),@/ |
