Introduction
Introduction Statistics Contact Development Disclaimer Help
tvi: undo and redo move to the first changed line - neatvi - [fork] simple vi-t…
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit 195dc5459fae177fba03ed32db9e0e1dd57fb972
parent 36dab822780af2effa399289db2caa52398de43e
Author: Ali Gholami Rudi <[email protected]>
Date: Thu, 4 Jun 2015 08:49:39 +0430
vi: undo and redo move to the first changed line
Also '[ and '] point to the first and last changed lines.
Diffstat:
M ex.c | 2 +-
M lbuf.c | 46 +++++++++++++++++++++++------…
M vi.c | 26 ++++++++++++++++----------
M vi.h | 6 +++---
4 files changed, 55 insertions(+), 25 deletions(-)
---
diff --git a/ex.c b/ex.c
t@@ -118,7 +118,7 @@ static int ex_lineno(char *num)
if (num[0] == '+')
n = xrow + (num[1] ? ex_lineno(num + 1) : 1);
if (num[0] == '\'')
- lbuf_markpos(xb, num[1], &n, NULL);
+ lbuf_jump(xb, num[1], &n, NULL);
if (num[0] == '/' && num[1])
n = ex_search(num);
if (num[0] == '?' && num[1])
diff --git a/lbuf.c b/lbuf.c
t@@ -4,7 +4,7 @@
#include <unistd.h>
#include "vi.h"
-#define MARK(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' : 30)
+#define NMARKS 128
/* line operations */
struct lopt {
t@@ -16,14 +16,15 @@ struct lopt {
/* line buffers */
struct lbuf {
- int mark[32]; /* mark lines */
- int mark_off[32]; /* mark line offsets */
+ int mark[NMARKS]; /* mark lines */
+ int mark_off[NMARKS]; /* mark line offsets */
struct lopt hist[128]; /* buffer history */
int undo; /* current index into hist[] */
int useq; /* current operation sequence */
char **ln; /* lines */
int ln_n; /* number of lbuf in l[] */
int ln_sz; /* size of l[] */
+ int mark_mod; /* clear modification marks */
};
struct lbuf *lbuf_make(void)
t@@ -70,6 +71,7 @@ static void lbuf_insert(struct lbuf *lb, int pos, char *s)
int len = strlen(s);
struct sbuf *sb;
int lb_len = lbuf_len(lb);
+ int beg = pos, end;
int i;
sb = sbuf_make();
for (i = 0; i < len; i++) {
t@@ -83,6 +85,12 @@ static void lbuf_insert(struct lbuf *lb, int pos, char *s)
for (i = 0; i < LEN(lb->mark); i++) /* updating marks */
if (lb->mark[i] >= pos)
lb->mark[i] += lbuf_len(lb) - lb_len;
+ end = beg + lbuf_len(lb) - lb_len;
+ if (lb->mark_mod || lb->mark['['] < 0 || lb->mark['['] > beg)
+ lbuf_mark(lb, '[', beg, 0);
+ if (lb->mark_mod || lb->mark[']'] < 0 || lb->mark[']'] < end - 1)
+ lbuf_mark(lb, ']', end - 1, 0);
+ lb->mark_mod = 0;
}
/* low-level deletion */
t@@ -96,6 +104,11 @@ static void lbuf_delete(struct lbuf *lb, int beg, int end)
for (i = 0; i < LEN(lb->mark); i++) /* updating marks */
if (lb->mark[i] > beg)
lb->mark[i] = MAX(beg, lb->mark[i] + beg - end);
+ if (lb->mark_mod || lb->mark['['] < 0 || lb->mark['['] > beg)
+ lbuf_mark(lb, '[', beg, 0);
+ if (lb->mark_mod || lb->mark[']'] < 0 || lb->mark[']'] < beg)
+ lbuf_mark(lb, ']', beg, 0);
+ lb->mark_mod = 0;
}
/* append undo/redo history */
t@@ -180,17 +193,19 @@ int lbuf_len(struct lbuf *lb)
void lbuf_mark(struct lbuf *lbuf, int mark, int pos, int off)
{
- lbuf->mark[MARK(mark)] = pos;
- lbuf->mark_off[MARK(mark)] = off;
+ if (mark >= NMARKS)
+ return;
+ lbuf->mark[mark] = pos;
+ lbuf->mark_off[mark] = off;
}
-int lbuf_markpos(struct lbuf *lbuf, int mark, int *pos, int *off)
+int lbuf_jump(struct lbuf *lbuf, int mark, int *pos, int *off)
{
- if (lbuf->mark[MARK(mark)] < 0)
+ if (mark >= NMARKS || lbuf->mark[mark] < 0)
return 1;
- *pos = lbuf->mark[MARK(mark)];
+ *pos = lbuf->mark[mark];
if (off)
- *off = lbuf->mark_off[MARK(mark)];
+ *off = lbuf->mark_off[mark];
return 0;
}
t@@ -200,10 +215,13 @@ static struct lopt *lbuf_lopt(struct lbuf *lb, int i)
return i >= 0 && i < LEN(lb->hist) && lo->buf ? lo : NULL;
}
-void lbuf_undo(struct lbuf *lb)
+int lbuf_undo(struct lbuf *lb)
{
struct lopt *lo = lbuf_lopt(lb, lb->undo);
int useq = lo ? lo->seq : 0;
+ if (!lo)
+ return 1;
+ lb->mark_mod = 1;
while (lo && lo->seq == useq) {
lb->undo++;
if (lo->ins)
t@@ -212,12 +230,16 @@ void lbuf_undo(struct lbuf *lb)
lbuf_insert(lb, lo->beg, lo->buf);
lo = lbuf_lopt(lb, lb->undo);
}
+ return 0;
}
-void lbuf_redo(struct lbuf *lb)
+int lbuf_redo(struct lbuf *lb)
{
struct lopt *lo = lbuf_lopt(lb, lb->undo - 1);
int useq = lo ? lo->seq : 0;
+ if (!lo)
+ return 1;
+ lb->mark_mod = 1;
while (lo && lo->seq == useq) {
lb->undo--;
if (lo->ins)
t@@ -226,6 +248,7 @@ void lbuf_redo(struct lbuf *lb)
lbuf_delete(lb, lo->beg, lo->end);
lo = lbuf_lopt(lb, lb->undo - 1);
}
+ return 0;
}
void lbuf_undofree(struct lbuf *lb)
t@@ -239,5 +262,6 @@ void lbuf_undofree(struct lbuf *lb)
void lbuf_undomark(struct lbuf *lbuf)
{
+ lbuf->mark_mod = 1;
lbuf->useq++;
}
diff --git a/vi.c b/vi.c
t@@ -233,9 +233,7 @@ static int vi_motionln(int *row, int cmd)
case '\'':
if ((mark = vi_read()) <= 0)
return -1;
- if (!islower(mark) && !strchr("'`", mark))
- return -1;
- if (lbuf_markpos(xb, mark, &mark_row, &mark_off))
+ if (lbuf_jump(xb, mark, &mark_row, &mark_off))
return -1;
*row = mark_row;
break;
t@@ -467,9 +465,7 @@ static int vi_motion(int *row, int *off)
case '`':
if ((mark = vi_read()) <= 0)
return -1;
- if (!islower(mark) && !strchr("'`", mark))
- return -1;
- if (lbuf_markpos(xb, mark, &mark_row, &mark_off))
+ if (lbuf_jump(xb, mark, &mark_row, &mark_off))
return -1;
*row = mark_row;
*off = mark_off;
t@@ -1020,12 +1016,22 @@ static void vi(void)
redraw = 1;
break;
case 'u':
- lbuf_undo(xb);
- redraw = 1;
+ if (!lbuf_undo(xb)) {
+ lbuf_jump(xb, '[', &xrow, &xoff);
+ xoff = lbuf_indents(xb, xrow);
+ redraw = 1;
+ } else {
+ snprintf(vi_msg, sizeof(vi_msg), "undo…
+ }
break;
case TK_CTL('r'):
- lbuf_redo(xb);
- redraw = 1;
+ if (!lbuf_redo(xb)) {
+ lbuf_jump(xb, '[', &xrow, &xoff);
+ xoff = lbuf_indents(xb, xrow);
+ redraw = 1;
+ } else {
+ snprintf(vi_msg, sizeof(vi_msg), "redo…
+ }
break;
case TK_CTL('g'):
vc_status();
diff --git a/vi.h b/vi.h
t@@ -16,9 +16,9 @@ void lbuf_put(struct lbuf *lbuf, int pos, char *s);
char *lbuf_get(struct lbuf *lbuf, int pos);
int lbuf_len(struct lbuf *lbuf);
void lbuf_mark(struct lbuf *lbuf, int mark, int pos, int off);
-int lbuf_markpos(struct lbuf *lbuf, int mark, int *pos, int *off);
-void lbuf_undo(struct lbuf *lbuf);
-void lbuf_redo(struct lbuf *lbuf);
+int lbuf_jump(struct lbuf *lbuf, int mark, int *pos, int *off);
+int lbuf_undo(struct lbuf *lbuf);
+int lbuf_redo(struct lbuf *lbuf);
void lbuf_undomark(struct lbuf *lbuf);
void lbuf_undofree(struct lbuf *lbuf);
int lbuf_indents(struct lbuf *lb, int r);
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.