summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatolaZ <katolaz@freaknet.org>2019-08-16 23:43:24 +0100
committerKatolaZ <katolaz@freaknet.org>2019-08-16 23:43:24 +0100
commitce2bfb4d3a49a27bde7c8bbc6c6b1ef6f80054aa (patch)
treed1fcd43773692a8473d7c335303370eada9a1569
parent02c54fe6f289901f5b356ca98a81dec78fef4f36 (diff)
add position marks (Ma/g'a)
-rw-r--r--TODO2
-rw-r--r--gramscii.148
-rw-r--r--gramscii.c3
-rw-r--r--gramscii.h9
-rw-r--r--screen.c37
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<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
+ }
+}