From ce2bfb4d3a49a27bde7c8bbc6c6b1ef6f80054aa Mon Sep 17 00:00:00 2001 From: KatolaZ Date: Fri, 16 Aug 2019 23:43:24 +0100 Subject: add position marks (Ma/g'a) --- TODO | 2 ++ gramscii.1 | 48 ++++++++++++++++++++++++++++++++++++++---------- gramscii.c | 3 +++ gramscii.h | 9 +++++++++ screen.c | 37 ++++++++++++++++++++++++++++++++++++- 5 files changed, 88 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 1375028..ecd2a35 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ + optimize redraws (redraw only the modified rectangle) - add screen geometry option (-g 25x80?) - (?)maybe move "text" mode to "t" +- implement trapezium - implement ellipse - (?) filled box (B) - (?) manage filled box character (as for other styles) @@ -13,6 +14,7 @@ - allow scrolling (both vertical and horizontal) - catch SIGWINCH and react appropriately (after scrolling is enabled) +* add position marks (Ma / g'a) * implement comment (#: ignore everything until the end of the line) * implement parallelogram mode (z/Z) * fix bug in reading commands from files diff --git a/gramscii.1 b/gramscii.1 index 3370c24..b130530 100644 --- a/gramscii.1 +++ b/gramscii.1 @@ -86,6 +86,17 @@ command). Load (edit) an existing file from disk, discarding any change to the current screen. .TP 5m +.BI M a +Mark (label) the current cursor position as 'a'. The label 'a' must be +one of the 26 ASCII alphabetic characters. The cursor can be moved to a +previously marked position using the global positioning command +.B g +(see below). Position marks are case-insensitive, meaning that both +.I 'c' +and +.I 'C' +indicate the same mark. +.TP 5m .BI N Start a new empty screen. If the current screen has been modified since the last @@ -178,11 +189,13 @@ units at a time (defaults to 5, change LONG_STEP in config.h as you wish). .TP 5m .BI g -Initiate a global positioning command (go). These are two-letter -commands starting with a +Initiate a global positioning command (go). These are two- or +three-letter commands starting with a .BI g -and followed by a direction command or by a character that indicates a -global position, namely: +and followed by a direction command, or by a character that indicates a +global position, or by a valid position mark previously defined with +.B M +and preceded by a single quote. In particular: .RS .TP 5m .BI h @@ -205,9 +218,24 @@ move the cursor to the bottom-right corner of the screen .TP 5m .BI m move the cursor to the middle of the screen. +.TP 5m +.BI 'a +(single-quote followed by a character) move the cursor to the position +previously marked (labelled) with character +.BI 'a' +by the command +.B M +(mark). The character 'a' must be one of the 26 ASCII alphabetic +characters. Notice that position marks are case-insensitive, so the two +commands: +.B g'b +and +.B g'B +move the cursor to the position mark associated to the letter 'b', if it +exists. .PP -For instance, if you want to move the cursor to the first row of the -current column, you would use the two-letter command +If you want to move the cursor to the first row of the current +column, you could use the two-letter command .B gk (which can be read as "go-up"). Similarly, the command .B gh @@ -227,13 +255,13 @@ is equivalent to ). .PP Global positioning commands are available in -.B box, arrow, visual, +.B box, arrow, visual, parallelogram, and .B erase mode. Notice that -.B gg, gG, -and -.B gm, +.B gg, gG, gm +and moves to position marks like +.B g'b, are not available in .B arrow mode. diff --git a/gramscii.c b/gramscii.c index 977a8cb..5c893fe 100644 --- a/gramscii.c +++ b/gramscii.c @@ -142,6 +142,9 @@ void commands(FILE *fc){ mode = REM; get_comment(fc); break; + case 'M': + mark_pos(fc); + break; case 'q': check_modified(fc);/** FALLTHROUGH **/ case 'Q': diff --git a/gramscii.h b/gramscii.h index 8aec939..c2b9170 100644 --- a/gramscii.h +++ b/gramscii.h @@ -90,6 +90,11 @@ typedef struct{ line_t *l; } lineset_t; +typedef struct{ + int x; + int y; +} pos_t; + /** MACROS **/ @@ -105,6 +110,9 @@ lineset_t screen; /* what is visualised */ lineset_t cutbuf; /* cut/paste buffer */ lineset_t *undo; /* undo list */ +pos_t marks[26]; /* position marks */ +char mark_map[26]; /* marks map */ + int undo_sz;/* allocated size of undo list*/ int undo_cur;/* undo position */ int undo_lst;/* last valid undo position */ @@ -175,6 +183,7 @@ void crop_to_nonblank(); void crop_to_rect(); void erase_blank_lines(int y1, int y2); int _isblank(int c); +void mark_pos(FILE *fc); /**/ /** drawing-related functions **/ diff --git a/screen.c b/screen.c index 28d2318..0ef1f69 100644 --- a/screen.c +++ b/screen.c @@ -301,6 +301,24 @@ void handle_goto(FILE *fc, char global){ go_to(MIDDLE); } else step = 0; break; + case '\'': + c = tolower(fgetc(fc)); + if (global) { + dir = DIR_N; + if (isalpha(c) && mark_map[c - 'a']){ + x = marks[c - 'a'].x; + y = marks[c - 'a'].y; +#ifdef DEBUG + fprintf(stderr, "going to valid mark '%c' (%d, %d)\n", c, x, y); +#endif + } +#ifdef DEBUG + else + fprintf(stderr, "invalid mark '%c'\n", c); +#endif + } else step = 0; + break; + } #ifdef DEBUG @@ -435,20 +453,23 @@ void init_screen(){ for (i=0; i