commit 21a5cf59f37671c65c75211db93979bb609290da
parent fd8360751a05941c3fba4c34f6a2a6a0836602ee
Author: Dimitris Zervas <dzervas@dzervas.gr>
Date: Tue, 15 Jul 2014 14:55:36 +0300
Fixed unchained undo while multiplying commands
Diffstat:
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/TODO b/TODO
@@ -13,9 +13,9 @@ In no particular order, at sandy.c:
- FINDBW prompt? is it needed?
- Support multiple marks (with S_Parameter)
- Instead of delete, just cut
+- Add folding support
At config.def.h:
-- Bindings!
- Use local/system script path and all
- Choose color-set for either black or white bg
- Define more syntaxes
diff --git a/config.h b/config.h
@@ -172,6 +172,7 @@ static const Key commkeys[] = { /* Command mode keys here */
{ .keyv.c = { '^' }, { 0, 0, 0, 0 }, f_move, { .m = m_bol } },
{ .keyv.c = { 'A' }, { 0, 0, 0, 0 }, f_move, { .m = m_eol } },
{ .keyv.c = { 'A' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } },
+{ .keyv.c = { 'a' }, { t_eol, 0, 0, 0 }, f_toggle, { .i = S_Command } },
{ .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_move, { .m = m_nextchar } },
{ .keyv.c = { 'a' }, { 0, 0, 0, 0 }, f_toggle, { .i = S_Command } },
{ .keyv.c = { 'b' }, { t_sent,0, 0, 0 }, f_adjective, { .m = m_prevword } },
diff --git a/sandy.c b/sandy.c
@@ -369,12 +369,14 @@ f_insert(const Arg *arg) {
Filepos newcur;
newcur=i_addtext((char*)arg->v, fcur);
+
if((statusflags & S_GroupUndo) && undos && (undos->flags & UndoIns) && fcur.o == undos->endo && undos->endl == i_lineno(fcur.l) && ((char*)arg->v)[0] != '\n')
i_addtoundo(newcur, arg->v);
else {
i_addundo(TRUE, fcur, newcur, strdup((char*)arg->v));
if(fcur.l!=newcur.l) fsel=newcur;
}
+
fcur=fsel=newcur;
statusflags|=(S_Modified|S_GroupUndo);
lastaction=LastInsert;
@@ -547,19 +549,23 @@ f_undo(const Arg *arg) {
u=(isredo?redos:undos);
fsel.o=u->starto, fsel.l=i_lineat(u->startl);
fcur=fsel;
+
while(u) {
start.o=u->starto, start.l=i_lineat(u->startl);
end.o=u->endo, end.l=i_lineat(u->endl);
+
if(isredo ^ (u->flags & UndoIns)) {
i_sortpos(&start, &end);
i_deltext(start, end);
fcur=fsel=start;
} else
fcur=fsel=i_addtext(u->str, fcur);
+
if(isredo)
redos=u->prev, u->prev=undos, undos=u;
else
undos=u->prev, u->prev=redos, redos=u;
+
if (!(u->flags & (isredo?RedoMore:UndoMore))) break;
u=(isredo?redos:undos);
}
@@ -582,8 +588,10 @@ i_addtoundo(Filepos newend, const char *s) {
oldsiz=strlen(undos->str), newsiz=strlen(s);
undos->endl=i_lineno(newend.l);
undos->endo=newend.o;
+
if((undos->str=(char*)realloc(undos->str, 1+oldsiz+newsiz)) == NULL)
i_die("Can't malloc.\n");
+
strncat(undos->str, s, newsiz);
}
@@ -591,9 +599,17 @@ void /* Add new undo information to the undo ring */
i_addundo(bool ins, Filepos start, Filepos end, char *s) {
Undo *u;
+ if(strlen(s) == 0) return;
+ if(statusflags & S_GroupUndo) {
+ end.l = i_lineat((undos->endl - undos->startl) + i_lineno(end.l));
+ i_addtoundo(end, s);
+ return;
+ }
+
if(redos) i_killundos(&redos); /* Once you make a change, the old redos go away */
if ((u=(Undo*)calloc(1, sizeof(Undo))) == NULL)
i_die("Can't malloc.\n");
+
u->flags = (ins?UndoIns:0);
u->startl = i_lineno(start.l);
u->endl = i_lineno(end.l);
@@ -1045,10 +1061,13 @@ i_multiply(void (*func)(const Arg *arg), const Arg arg) {
int i;
if(statusflags & S_Multiply) {
- //statusflags|=S_GroupUndo;
- for(i=0; i<multiply; i++)
+ func(&arg);
+ statusflags|=S_GroupUndo;
+
+ for(i=1; i<multiply; i++)
func(&arg);
+ statusflags&=~S_GroupUndo;
statusflags&=~S_Multiply;
multiply=1;
} else