add undo in arrow mode - gramscii - A simple editor for ASCII box-and-arrow cha… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit f660595c236a21555d3558dd51afae4a67d651a3 | |
parent 47996e708ad2ab7e6a18633576c95e93d08e816a | |
Author: KatolaZ <[email protected]> | |
Date: Thu, 1 Aug 2019 09:56:13 +0100 | |
add undo in arrow mode | |
Diffstat: | |
M TODO | 14 +++++++------- | |
M draw.c | 7 +++++-- | |
M gramscii.1 | 6 +++--- | |
M gramscii.h | 57 +++++++++++++++++++++--------… | |
4 files changed, 54 insertions(+), 30 deletions(-) | |
--- | |
diff --git 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 | |
@@ -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 : lin… | |
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 | |
@@ -538,10 +538,10 @@ gramscii currently manages only a fixed screen of the sam… | |
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 | |
<[email protected]>. You can use, copy, modify, and redistribute | |
diff --git 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 |