add position marks (Ma/g'a) - gramscii - A simple editor for ASCII box-and-arro… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit ce2bfb4d3a49a27bde7c8bbc6c6b1ef6f80054aa | |
parent 02c54fe6f289901f5b356ca98a81dec78fef4f36 | |
Author: KatolaZ <[email protected]> | |
Date: Fri, 16 Aug 2019 23:43:24 +0100 | |
add position marks (Ma/g'a) | |
Diffstat: | |
M TODO | 2 ++ | |
M gramscii.1 | 48 ++++++++++++++++++++++++-----… | |
M gramscii.c | 3 +++ | |
M gramscii.h | 9 +++++++++ | |
M screen.c | 37 +++++++++++++++++++++++++++++… | |
5 files changed, 88 insertions(+), 11 deletions(-) | |
--- | |
diff --git 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 | |
@@ -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 confi… | |
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 | |
@@ -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 | |
@@ -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 | |
@@ -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 '… | |
+#endif | |
+ } | |
+#ifdef DEBUG | |
+ else | |
+ fprintf(stderr, "invalid mark '%c'\n",… | |
+#endif | |
+ } else step = 0; | |
+ break; | |
+ | |
} | |
#ifdef DEBUG | |
@@ -435,20 +453,23 @@ void init_screen(){ | |
for (i=0; i<HEIGHT; i++){ | |
alloc_line(&(screen.l[i])); | |
} | |
+ /* init markers */ | |
hlines_sz= sizeof(hlines) -1; | |
vlines_sz= sizeof(vlines) -1; | |
corners_sz = sizeof(corners) -1; | |
stmarks_sz = sizeof(st_marks) - 1; | |
endmarks_sz = sizeof(st_marks) - 1; | |
reset_styles(); | |
+ /* init undo ring */ | |
cutbuf.sz = 0; | |
cutbuf.l = NULL; | |
cutbuf.num = 0; | |
- | |
undo = NULL; | |
undo_sz = 0; | |
undo_cur = -2; | |
undo_lst = -2; | |
+ /* init pos marks */ | |
+ memset(mark_map, 0, 26 * sizeof(char)); | |
} | |
void find_nonblank_rect(int *x1, int *y1, int *x2, int *y2){ | |
@@ -507,4 +528,18 @@ void crop_to_nonblank(){ | |
redraw(); | |
} | |
+/** position marks **/ | |
+void mark_pos(FILE *fc){ | |
+ | |
+ char c; | |
+ c = tolower(fgetc(fc)); | |
+ if (isalpha(c)){ | |
+ marks[c - 'a'].x = x; | |
+ marks[c - 'a'].y = y; | |
+ mark_map[c - 'a'] = 1; | |
+#ifdef DEBUG | |
+ fprintf(stderr, "marking pos (%d, %d) as '%c'\n", x, y, c); | |
+#endif | |
+ } | |
+} |