Introduction
Introduction Statistics Contact Development Disclaimer Help
add auto-arrow, multipliers, -s, -h - gramscii - A simple editor for ASCII box-…
Log
Files
Refs
Tags
README
LICENSE
---
commit f0200b8cc94cd6859ee91b7b47d1d89b41b195ed
parent cbfdf55b79d29e94b1f3d263dc74ee55140bbc66
Author: KatolaZ <[email protected]>
Date: Fri, 26 Jul 2019 10:26:40 +0100
add auto-arrow, multipliers, -s, -h
Diffstat:
M README.md | 13 +++++++++++++
M TODO | 11 ++++++-----
M config.mk | 2 +-
M gramscii.1 | 56 +++++++++++++++++++++++++++++…
M gramscii.c | 114 ++++++++++++++++++++++++++++-…
5 files changed, 180 insertions(+), 16 deletions(-)
---
diff --git a/README.md b/README.md
@@ -74,3 +74,16 @@ intellectual, a philosopher, and an artist, and maintained t…
changes are only possible when a class exerts intellectual and moral
leadership over its contemporaries. So just get rid of all your shiny
iPointless things and come back to reality.
+
+COPYING
+=======
+
+`gramscii` is written and maintained by Vincenzo 'KatolaZ' Nicosia
+<[email protected]>. You can use, modify and/or redistribute it under
+the terms of the GNU General Public Licence, either version 3 of the
+License or, at your option, any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
diff --git a/TODO b/TODO
@@ -1,14 +1,13 @@
+ optimize redraws (redraw only the modified rectangle)
- change screen management (i.e., dynamic array of lines)
-- add action multiplier (e.g., "7h" moves left by 7 cols)
-- add scripting mode option ("-s"?)
- add screen geometry option (-g 25x80?)
- read file at point
+ - read output of command (!)
- use [ENTER] to exit from text insert
- maybe move "text" mode to "t"
- implement ellipse
-- parse control characters
- - parse arrows (text-mode will allow movements as well)
++ parse control characters
+ + parse arrows (text-mode will allow movements as well)
- (?) implement CTRL+G as abort (aside ESC)
- add crop command (c)
- remove extra blanks until EOL when saving to file
@@ -23,7 +22,9 @@
- allow scrolling (both vertical and horizontal)
- catch SIGWINCH and react appropriately (after scroll is
enabled)
-- auto-arrow 'A' (automatic end-char)
+* add action multiplier (e.g., "7h" moves left by 7 cols)
+* add scripting mode option ("-s"?)
+* auto-arrow 'A' (automatic end-char)
* move configs in config.h
* get screen geometry
* allow the use of [ENTER] to confirm arrow, boxes (useful
diff --git a/config.mk b/config.mk
@@ -3,4 +3,4 @@ BINDIR = ${PREFIX}/bin
MANDIR = ${PREFIX}/share/man
CFLAGS = -O3 -std=c90 -pedantic -Wall
-##CC = cc
+CC = cc
diff --git a/gramscii.1 b/gramscii.1
@@ -4,6 +4,9 @@ gramscii \- simple editor for ASCII box diagrams
.SH SYNOPSIS
.PP
gramscii
+.RI [-s]
+.RI [-h]
+.RI [file ...]
.PP
.SH DESCRIPTION
.PP
@@ -11,6 +14,18 @@ gramscii is a simple interactive editor to create ASCII box-…
diagrams. It uses vi-like keybindings for drawing and editing boxes,
arrows, and text.
.PP
+.SH OPTIONS
+.TP 5m
+.BI -s
+Start gramscii in script-mode. In this mode the screen is set to 25 rows
+by 80 columns, no status bar is present, drawings and cursor movements
+are not shown, and the state of the screen is dumped to stdout when the
+program ends. With this flag, gramscii can be used in a pipeline,
+getting commands from stdin (or from a file) and making its output
+available for further processing.
+.TP
+.BI -h
+Print short usage unstructions and exit.
.SH COMMANDS
gramscii is a visual modal editor. Commands are associated to
keystrokes, and keystrokes have different meaning in different modes.
@@ -97,7 +112,9 @@ move the cursor right by 1 column
.PP
gramscii accepts also the uppercase commands
.B H, J, K, L,
-which will move in the corresponding direction by 5 units at a time.
+which will move in the corresponding direction by a LONG_STEP number of
+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
@@ -152,8 +169,35 @@ Typing
.BI g
followed by any character that is not listed above has no effect on the
cursor.
+.SS MULTIPLIERS
+Simple cursor movement commands (hjklHJKL) can be preceded by a number
+that acts as a multiplier. For instance, the command:
+.PP
+.RS
+14h
+.PP
.RE
-
+will move the cursor by 14 steps to the left. Similarily, the command:
+.PP
+.RS
+7J
+.PP
+.RE
+will move the cursor by 7 LONG_STEPs rows down (with the default
+LONG_STEP equal to 5, this will correspond to 35 rows down).
+.PP
+Multipliers can be used whenever a movement command is legal, i.e. in
+move, box, arrox, visual, and erase mode. So for instance the sequence:
+.RS
+ggb13l18jb
+.PP
+.RE
+will draw a 18x13 box whose top-left corner coincides with the top-left
+corner of the screen.
+.PP
+Multipliers are ignored by global positioning commands (i.e., those
+starting with
+.B g)
.SS MODES
The currently supported modes are:
.B move,
@@ -233,6 +277,14 @@ styles. See
.B STYLES
below for more information.
.TP 7m
+.BI A
+Exactly as
+.BI a
+toggles
+.B arrow
+mode, but the end point marker is automatically set according to the
+direction of the arrow.
+.TP 7m
.BI x
Toggle
.B erase
diff --git a/gramscii.c b/gramscii.c
@@ -27,6 +27,7 @@
#include <signal.h>
#include <string.h>
#include <sys/ioctl.h>
+#include <ctype.h>
#include "config.h"
@@ -80,6 +81,7 @@ int dir;
int x;
int y;
int step;
+int mult;
int force_new;
char cursor;
char corner;
@@ -101,6 +103,7 @@ char fname[256];
char visual;
char silent;
+char autoend;
char *argv0;
@@ -147,6 +150,20 @@ char* state_str(){
return "ERR";
}
+char get_mark(char dir){
+ switch(dir){
+ case DIR_U:
+ return '^';
+ case DIR_D:
+ return 'v';
+ case DIR_L:
+ return '<';
+ case DIR_R:
+ return '>';
+ }
+ return '>';
+}
+
void status_bar(){
@@ -355,26 +372,78 @@ void handle_goto(){
show_cursor();
}
-int move_around(char c){
+int get_escape(FILE *fc){
+ char c[4];
+
+ c[0] = fgetc(fc);
+ if (c[0] == '['){
+ c[1] = fgetc(fc);
+ switch(c[1]){
+ case 'D':
+ dir = DIR_L;
+ x -= step;
+ break;
+ case 'B':
+ dir = DIR_D;
+ y += step;
+ break;
+ case 'A':
+ dir = DIR_U;
+ y -= step;
+ break;
+ case 'C':
+ dir = DIR_R;
+ x += step;
+ break;
+ }
+ return 1;
+ }
+ else{
+ ungetc(c[0], fc);
+ return 0;
+ }
+
+}
+
+
+int move_around(char c, FILE *fc){
+
+ if (isdigit(c)){
+ if (mult)
+ mult *=10;
+ mult += c - '0';
+ return 0;
+ }
switch(c){
+ case 27: /* control sequence? */
+ c = get_escape(fc);
+ break;
case 'H': step = LONG_STEP;/** FALLTHROUGH **/
case 'h':
dir = DIR_L;
+ if (mult)
+ step *= mult;
x -= step;
break;
case 'J': step = LONG_STEP;/** FALLTHROUGH **/
case 'j':
+ if (mult)
+ step *= mult;
dir = DIR_D;
y += step;
break;
case 'K': step = LONG_STEP;/** FALLTHROUGH **/
case 'k':
+ if (mult)
+ step *= mult;
dir = DIR_U;
y -= step;
break;
case 'L': step = LONG_STEP;/** FALLTHROUGH **/
case 'l':
+ if (mult)
+ step *= mult;
dir = DIR_R;
x += step;
break;
@@ -384,6 +453,7 @@ int move_around(char c){
default:
return 0;
}
+ mult = 0;
return c;
}
@@ -535,7 +605,7 @@ void get_box(FILE *fc){
while((c=fgetc(fc))!=EOF && c != 27 && c!= 'b' && c != '\n'){
if (change_style(c))
goto update_box;
- if (!move_around(c))
+ if (!move_around(c, fc))
continue;
check_bound();
redraw();
@@ -589,7 +659,12 @@ void draw_arrow(int x, int y, char *a, int a_len, int fix){
/* f(x,y,mark_end);*/
cur_dir = a[i];
}
- f(x,y,mark_end);
+ if (autoend){
+ if (cur_dir != DIR_N)
+ f(x,y, get_mark(cur_dir));
+ }
+ else
+ f(x,y,mark_end);
show_cursor();
}
@@ -613,7 +688,7 @@ void get_arrow(FILE *fc){
while((c=fgetc(fc))!=EOF && c != 27 && c!= 'a' && c != '\n'){
if (change_style(c))
goto update_arrow;
- if (!move_around(c))
+ if (!move_around(c, fc))
continue;
check_bound();
/* FIXME: if we are out of bound, do nothing? */
@@ -664,7 +739,7 @@ void delete(FILE *fc){
status_bar();
show_cursor();
while((c=fgetc(fc))!=EOF && c!=27 && c!= 'x' && c != '\n'){
- if (!move_around(c)) continue;
+ if (!move_around(c, fc)) continue;
check_bound();
do_delete(orig_x, orig_y);
step = 1;
@@ -758,7 +833,7 @@ void visual_box(FILE *fc){
set_video(VIDEO_REV);
draw_box(x,y,NOFIX);
while((c=fgetc(fc))!=EOF && c != 27 && c!= 'v' && c != '\n'){
- if (!move_around(c)) switch(c){
+ if (!move_around(c, fc)) switch(c){
case 'f':/* fill */
f = get_key(fc, "fill char: "); /** FALLTHROUG…
case 'x':/* erase */
@@ -842,7 +917,7 @@ void commands(FILE *fc){
char c;
while((c=fgetc(fc))!=EOF){
- if (!change_style(c) && !move_around(c)){
+ if (!change_style(c) && !move_around(c, fc)){
switch(c){
case 'i':
state = TEXT;
@@ -855,9 +930,11 @@ void commands(FILE *fc){
state = BOX;
get_box(fc);
break;
+ case 'A': autoend=1;
case 'a':
state = ARROW;
get_arrow(fc);
+ autoend = 0;
break;
case 'W':
force_new = 1;/** FALLTHROUGH **/
@@ -897,17 +974,38 @@ void commands(FILE *fc){
}
+void usage(){
+ fprintf(stderr, "Usage: %s [-s] [-h] [file ...]\n", argv0);
+ exit(1);
+}
+
int main(int argc, char *argv[]){
+ FILE *fc;
ARGBEGIN {
case 's':
silent = 1;
break;
+ case 'h': /* FALLTHROUGH */
+ default:
+ usage();
} ARGEND;
init();
-
+ while (argc){
+ fc = fopen(argv[0], "r");
+ if (fc == NULL){
+ fprintf(stderr, "Error opening file %s\n", argv[0]);
+ }
+ else {
+ commands(fc);
+ fclose(fc);
+ redraw();
+ }
+ argv++;
+ argc--;
+ }
commands(stdin);
cleanup(0);
return 0;
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.