summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatolaZ <katolaz@freaknet.org>2019-08-01 09:56:13 +0100
committerKatolaZ <katolaz@freaknet.org>2019-08-01 09:56:13 +0100
commitf660595c236a21555d3558dd51afae4a67d651a3 (patch)
tree87f3703b944f0fa783a8234caa53116f6dd06a55
parent47996e708ad2ab7e6a18633576c95e93d08e816a (diff)
add undo in arrow mode
-rw-r--r--TODO14
-rw-r--r--draw.c7
-rw-r--r--gramscii.16
-rw-r--r--gramscii.h57
4 files changed, 54 insertions, 30 deletions
diff --git a/TODO b/TODO
index 2514376..ed2ceaf 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,8 @@
+ 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 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?)
@@ -18,16 +18,16 @@
+ parse arrows (text-mode will allow movements as well)
- (?) implement CTRL+G as abort (aside ESC)
- (?) remove extra blanks until EOL when saving to file
-+ visual selection
- - crop-to
- * yank
- * fill
- * cut
- manage special chars (DEL/CANC) during text insert
(also do not print unmanaged chars!)
- allow scrolling (both vertical and horizontal)
- catch SIGWINCH and react appropriately (after scrolling is
enabled)
+* visual selection
+ * crop-to-rectangle
+ * yank
+ * fill
+ * cut
* put yanked content (p)
* turn screen into a lineset
* change alloc/ensure functions to work on line_t* and lineset_t*
diff --git a/draw.c b/draw.c
index ec44c2f..bc6657d 100644
--- a/draw.c
+++ b/draw.c
@@ -173,7 +173,7 @@ void draw_arrow(int x, int y, char *a, int a_len, int fix){
char line;
void (*f)(int, int, char);
-
+ a_miny = a_maxy = y;
if (fix == FIX)
f = set_xy;
else
@@ -198,6 +198,8 @@ void draw_arrow(int x, int y, char *a, int a_len, int fix){
line = (a[i] & DIR_L) || (a[i] & DIR_R) ? line_h : line_v;
x += progr_x(a[i]);
y += progr_y(a[i]);
+ if (y < a_miny) a_miny = y;
+ if (y > a_maxy) a_maxy = y;
f(x, y, line);
}
/* f(x,y,mark_end);*/
@@ -250,8 +252,9 @@ update_arrow:
show_cursor();
}
if (c == 'a' || c == '\n'){
- invalidate_undo();
+ copy_lines_to_ring(a_miny, a_maxy, PRV_STATE);
draw_arrow(orig_x, orig_y, arrow, arrow_len, FIX);
+ copy_lines_to_ring(a_miny, a_maxy, NEW_STATE);
modified = 1;
}
redraw();
diff --git a/gramscii.1 b/gramscii.1
index 39faa09..036ccf5 100644
--- a/gramscii.1
+++ b/gramscii.1
@@ -538,10 +538,10 @@ gramscii currently manages only a fixed screen of the same size of the
screen where it starts from. This will be changed in a future release to
support scrolling and "virtual" screens of any (reasonable) size.
.PP
-Undo commands are only available in box, visual (cut, fill), and text
-mode, and for copy/paste operations. gramscii currently does
+Undo commands are only available in box, visual (cut, fill), arrow, and
+text mode, and for copy/paste operations. gramscii currently does
.B not
-support undo commands for arrow and erase mode. This will be fixed soon.
+support undo commands for erase mode. This will be fixed soon.
.SH AUTHORS
gramscii is written and maintained by Vincenzo "KatolaZ" Nicosia
<katolaz@freaknet.org>. You can use, copy, modify, and redistribute
diff --git a/gramscii.h b/gramscii.h
index 9b95a4e..7c715a6 100644
--- a/gramscii.h
+++ b/gramscii.h
@@ -9,13 +9,16 @@
/** constants **/
+/* modes */
#define MOVE 0x00
#define BOX 0x01
#define ARROW 0x02
#define TEXT 0x04
#define DEL 0x08
#define VIS 0x10
+/**/
+/* directions */
#define DIR_N 0x00
#define DIR_R 0x01
#define DIR_U 0x02
@@ -24,11 +27,12 @@
#define DIR_HOR (DIR_R | DIR_L)
#define DIR_VER (DIR_D | DIR_U)
-
+/**/
#define NOFIX 0x0
#define FIX 0x1
+/* markers */
#define BG ' '
#define PTR '+'
#define UND '_'
@@ -36,21 +40,28 @@
#define ARR_R '>'
#define ARR_U '^'
#define ARR_D 'v'
+/**/
+/* global positions */
#define HOME 0x01
#define END 0x02
#define MIDDLE 0x04
+/**/
+/* video modes */
#define VIDEO_NRM 0
#define VIDEO_REV 7
+/**/
+/* undo buffer elem types */
#define PRV_STATE 0x01
#define NEW_STATE 0x02
+/**/
/** types **/
typedef struct{
- int sz;/* allocated size*/
+ int sz;/* allocated size */
int n;/* line number */
int lst;/* last visible char (before the first \0) */
char *s;
@@ -75,45 +86,52 @@ typedef struct{
/** global variables **/
-lineset_t screen;
-lineset_t cutbuf;
-lineset_t *undo;
+lineset_t screen; /* what is visualised */
+lineset_t cutbuf; /* cut/paste buffer */
+lineset_t *undo; /* undo list */
-int undo_sz;
-int undo_cur;
-int undo_lst;
+int undo_sz;/* allocated size of undo list*/
+int undo_cur;/* undo position */
+int undo_lst;/* last valid undo position */
int WIDTH, HEIGHT;
-int mode;
-int dir;
+int mode;/* mode */
+int dir;/* line direction */
int x;
int y;
-int step;
-int mult;
+int step;/* current step */
+int mult;/* current multiplier */
int force_new;
-char cursor;
char corner;
+/* number of available markers for each type */
int hlines_sz;
int vlines_sz;
int corners_sz;
int stmarks_sz;
int endmarks_sz;
+/**/
+/* line and arrow markers */
int cur_hl, cur_vl, cur_corn, cur_start, cur_end;
char line_h;
char line_v;
char mark_st;
char mark_end;
+/**/
-char modified;
+char modified; /* set to 1 if screen modified since last save */
char fname[256];
-char visual;
-char silent;
-char autoend;
+char silent; /* set to 1 in script-mode */
+char autoend; /* set to 1 in auto-arrow mode */
+
+/* Used by draw_arrow to identify the bounding box */
+int a_miny;
+int a_maxy;
+/**/
struct termios t1, t2, t3;
@@ -141,6 +159,7 @@ void go_to(int where);
void crop_to_nonblank();
void crop_to_rect();
void erase_blank_lines(int y1, int y2);
+/**/
/** drawing-related functions **/
int change_style(char c);
@@ -152,15 +171,16 @@ void visual_box(FILE *fc);
void paste();
void undo_change();
void redo_change();
+/**/
/** file-related functions **/
void write_file(FILE *fc);
void check_modified(FILE *fc);
void load_file(FILE *fc);
void new_file(FILE *fc);
+/**/
/** line-related functions **/
-
void dump_lines(lineset_t ls, FILE *f);
void alloc_line(line_t *l);
void ensure_line_length(line_t *l, int len);
@@ -169,5 +189,6 @@ void yank_region(int x1, int y1, int x2, int y2);
void paste_region(int x1, int y1);
void copy_lines_to_ring(int y1, int y2, int which);
void invalidate_undo();
+/**/
#endif