sandy

text editor
git clone git://git.suckless.org/sandy
Log | Files | Refs | README | LICENSE

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:
TODO | 2+-
config.h | 1+
sandy.c | 23+++++++++++++++++++++--
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