Introduction
Introduction Statistics Contact Development Disclaimer Help
add undo support for box, visual, cut/paste - gramscii - A simple editor for AS…
Log
Files
Refs
Tags
README
LICENSE
---
commit f3100ddd486d6f39b0c97c9c492bb6020bf3caf1
parent 526ce3a130732d4a2374a6e36a689d9e0cf5cc34
Author: KatolaZ <[email protected]>
Date: Wed, 31 Jul 2019 11:19:55 +0100
add undo support for box, visual, cut/paste
Diffstat:
M TODO | 4 ++++
M draw.c | 32 +++++++++++++++++------------…
M gramscii.1 | 24 ++++++++++++++++++++++--
M gramscii.h | 4 ++--
M lineset.c | 38 +++++++++++++++++------------…
M screen.c | 4 ++--
6 files changed, 69 insertions(+), 37 deletions(-)
---
diff --git a/TODO b/TODO
@@ -1,5 +1,9 @@
+ optimize redraws (redraw only the modified rectangle)
+ undo (by storing lines changed across insert/remove operations)
+ * re-organise undo-ring management
+ - add undo for arrow mode
+ - add undo for text mode
+ - add undo for erase mode
- fix bug with 'g' commands in arrow mode
- add screen geometry option (-g 25x80?)
- read file at point
diff --git a/draw.c b/draw.c
@@ -112,7 +112,7 @@ void draw_box(int x1, int y1, int fix){
if (fix == FIX){
f = set_xy;
- copy_lines_to_ring(ymin, ymax, CUR);
+ copy_lines_to_ring(ymin, ymax, PRV_STATE);
}
else
f = draw_xy;
@@ -130,7 +130,7 @@ void draw_box(int x1, int y1, int fix){
f(xmax, ymin, corner);
f(xmax, ymax, corner);
if (fix == FIX)
- copy_lines_to_ring(ymin, ymax, LST);
+ copy_lines_to_ring(ymin, ymax, NEW_STATE);
show_cursor();
}
@@ -316,10 +316,10 @@ void visual_box(FILE *fc){
case 'x':/* erase */
if (c == 'x')
yank_region(MIN(orig_x,x), MIN(orig_y,…
- copy_lines_to_ring(MIN(orig_y, y), MAX(orig_y,…
+ copy_lines_to_ring(MIN(orig_y, y), MAX(orig_y,…
erase_box(orig_x, orig_y, f);
erase_blank_lines(MIN(y,orig_y), MAX(y, orig_y…
- copy_lines_to_ring(MIN(orig_y, y), MAX(orig_y,…
+ copy_lines_to_ring(MIN(orig_y, y), MAX(orig_y,…
modified = 1;
goto vis_exit;
@@ -345,9 +345,9 @@ void paste(){
int y2;
y2 = y + cutbuf.num - 1;
- copy_lines_to_ring(y, y2, CUR);
+ copy_lines_to_ring(y, y2, PRV_STATE);
paste_region(x, y);
- copy_lines_to_ring(y, y2, LST);
+ copy_lines_to_ring(y, y2, NEW_STATE);
redraw();
}
@@ -356,28 +356,32 @@ void put_lines(lineset_t *u){
for (i=0; i< u->num; i++){
n = u->l[i].n;
- ensure_line_length(&(screen.l[i]), u->l[i].lst);
+ ensure_line_length(&(screen.l[i]), strlen(u->l[i].s));
strcpy(screen.l[n].s, u->l[i].s);
- screen.l[n].lst = u->l[i].lst;
+ screen.l[n].lst = strlen(u->l[i].s)-1;
}
}
void undo_change(){
if (undo_cur >= 0){
+ if (undo_cur > undo_lst)
+ undo_cur = undo_lst;
put_lines(& (undo[undo_cur]));
- undo_cur --;
+ undo_cur -= 2;
+ modified = 1;
}
redraw();
- modified = 1;
}
void redo_change(){
- if (undo_cur < undo_lst){
- undo_cur ++;
- put_lines(& (undo[undo_cur]));
+ if (undo_cur <= undo_lst-2){
+ if (undo_cur > 0)
+ put_lines(& (undo[undo_cur+1]));
+ undo_cur +=2;
+ put_lines(& (undo[undo_cur+1]));
+ modified = 1;
}
redraw();
- modified = 1;
}
diff --git a/gramscii.1 b/gramscii.1
@@ -63,6 +63,26 @@ buffer contains the rectangle yanked/cut in
.B visual
mode.
.TP 5m
+.BI u
+Undo the last change. gramscii supports an undo history of indefinite
+length. The command
+.BI u
+gets the last change from the history, and moves the history pointer
+back by one change. See the related command
+.BI U
+below.
+.TP 5m
+.BI U
+Redo, i.e., cancel a previous
+.BI u
+command. gramscii supports an undo history of indefinite length. The
+command
+.BI U
+moves to the following change, if possible. For instance, the sequence
+.BI uuU
+will go back two changes, and then forward one, effectively resetting
+the state of the screen to what it was before the last change occurred.
+.TP 5m
.BI q
Quit gramscii, and prompt for a filename if the current screen contains
unsaved changes.
@@ -516,8 +536,8 @@ support scrolling and "virtual" screens of any (reasonable)…
.PP
gramscii currently does
.B not
-provide an "undo" command. This requires a restructuring of buffer
-management, and will most probably be implemented in a future release.
+support "undo" commands for arrow, text, and erase mode. This will be
+added soon.
.SH AUTHORS
gramscii is written and maintained by Vincenzo "KatolaZ" Nicosia
<[email protected]>. You can use, copy, modify, and redistribute
diff --git a/gramscii.h b/gramscii.h
@@ -44,8 +44,8 @@
#define VIDEO_NRM 0
#define VIDEO_REV 7
-#define CUR 0x01
-#define LST 0x02
+#define PRV_STATE 0x01
+#define NEW_STATE 0x02
/** types **/
diff --git a/lineset.c b/lineset.c
@@ -127,19 +127,24 @@ void paste_region(int x1, int y1){
}
void copy_lines_to_ring(int y1, int y2, int which){
- lineset_t *tmp;
- int i, len, *idx;
+ int i, len, idx;
+ int offset;
+ lineset_t *tmp;
if (y1 > y2){
y1 ^= y2;
y2 ^= y1;
y1 ^= y2;
}
- if (which == CUR)
- idx = &undo_cur;
+ if (undo_cur > undo_lst)
+ undo_cur = undo_lst;
+ if (which == PRV_STATE){ /* adding a new previous state */
+ undo_cur += 2;
+ idx = undo_cur;
+ }
else
- idx = &undo_lst;
- if (*idx == undo_sz - 1){
+ idx = undo_cur + 1;
+ if (idx >= undo_sz - 1){
undo_sz += 10;
tmp = realloc(undo, undo_sz * sizeof(lineset_t));
if (tmp == NULL){
@@ -148,22 +153,21 @@ void copy_lines_to_ring(int y1, int y2, int which){
}
undo = tmp;
}
- (*idx) ++;
- ensure_num_lines(&(undo[*idx]), y2 - y1 + 1);
+ ensure_num_lines(&(undo[idx]), y2 - y1 + 1);
for(i=y1; i<=y2; i++){
len = strlen(screen.l[i].s);
- ensure_line_length(&(undo[*idx].l[i-y1]), len);
- strcpy(undo[*idx].l[i-y1].s, screen.l[i].s);
- undo[*idx].l[i-y1].n = i;
- undo[*idx].l[i-y1].lst = screen.l[i].lst;
+ ensure_line_length(&(undo[idx].l[i-y1]), len);
+ strcpy(undo[idx].l[i-y1].s, screen.l[i].s);
+ undo[idx].l[i-y1].n = i;
+ undo[idx].l[i-y1].lst = screen.l[i].lst;
}
- undo[*idx].num = y2 - y1 + 1;
- if (which == CUR)
+ undo[idx].num = y2 - y1 + 1;
+ if (which == PRV_STATE)
undo_lst = undo_cur;
#ifdef DEBUG
- fprintf(stderr, "undo_ring: y1: %d y2: %d idx: %d\n", y1, y2, *idx);
- for(i=0; i<undo[undo_cur].num; i++){
- fprintf(stderr, "UU: %d| %s\n", undo[*idx].l[i].n, undo[*idx].…
+ fprintf(stderr, "undo_ring: y1: %d y2: %d idx: %d\n", y1, y2, idx);
+ for(i=0; i<undo[idx].num; i++){
+ fprintf(stderr, "UU: %d| %s\n", undo[idx].l[i].n, undo[idx].l[…
}
#endif
}
diff --git a/screen.c b/screen.c
@@ -410,8 +410,8 @@ void init_screen(){
cutbuf.num = 0;
undo_sz = 0;
- undo_cur = -1;
- undo_lst = -1;
+ undo_cur = -2;
+ undo_lst = -2;
}
void find_nonblank_rect(int *x1, int *y1, int *x2, int *y2){
You are viewing proxied material from bitreich.org. 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.