add undo in arrow mode - gramscii - A simple editor for ASCII box-and-arrow charts
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit f660595c236a21555d3558dd51afae4a67d651a3
 (DIR) parent 47996e708ad2ab7e6a18633576c95e93d08e816a
 (HTM) Author: KatolaZ <katolaz@freaknet.org>
       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(-)
       ---
 (DIR) 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*
 (DIR) 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 : 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();
 (DIR) diff --git 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
 (DIR) 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