iyank buffer and initial copy/cut/paste support - gramscii - A simple editor for ASCII box-and-arrow charts Err bitreich.org 70 1Log /scm/gramscii/log.gph bitreich.org 70 1Files /scm/gramscii/files.gph bitreich.org 70 1Refs /scm/gramscii/refs.gph bitreich.org 70 1Tags /scm/gramscii/tag bitreich.org 70 1README /scm/gramscii/file/README.md.gph bitreich.org 70 1LICENSE /scm/gramscii/file/COPYING.gph bitreich.org 70 i--- Err bitreich.org 70 1commit eebc645dee0d15871d6cc46f156d424cd916b191 /scm/gramscii/commit/eebc645dee0d15871d6cc46f156d424cd916b191.gph bitreich.org 70 1parent a99759398841d86928c7ad4d8248f907765cbeb2 /scm/gramscii/commit/a99759398841d86928c7ad4d8248f907765cbeb2.gph bitreich.org 70 hAuthor: KatolaZ URL:mailto:katolaz@freaknet.org bitreich.org 70 iDate: Tue, 30 Jul 2019 12:15:54 +0100 Err bitreich.org 70 i Err bitreich.org 70 iyank buffer and initial copy/cut/paste support Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 2 +- Err bitreich.org 70 i M TODO | 11 +++++++---- Err bitreich.org 70 i M draw.c | 11 +++++++++++ Err bitreich.org 70 i M files.c | 6 +++--- Err bitreich.org 70 i M gramscii.1 | 20 ++++++++++++++++++-- Err bitreich.org 70 i M gramscii.h | 36 ++++++++++++++++++++++++------- Err bitreich.org 70 i A lineset.c | 117 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i M main.c | 11 ++++------- Err bitreich.org 70 i M screen.c | 117 ++++++++++--------------------- Err bitreich.org 70 i Err bitreich.org 70 i9 files changed, 227 insertions(+), 104 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/gramscii/file/Makefile.gph bitreich.org 70 i@@ -3,7 +3,7 @@ Err bitreich.org 70 i Err bitreich.org 70 i include config.mk Err bitreich.org 70 i Err bitreich.org 70 i-SRC = main.c draw.c screen.c files.c Err bitreich.org 70 i+SRC = main.c draw.c screen.c files.c lineset.c Err bitreich.org 70 i INC = config.h gramscii.h Err bitreich.org 70 i Err bitreich.org 70 i all: options gramscii Err bitreich.org 70 1diff --git a/TODO b/TODO /scm/gramscii/file/TODO.gph bitreich.org 70 i@@ -6,8 +6,8 @@ Err bitreich.org 70 i - use [ENTER] to exit from text insert Err bitreich.org 70 i - maybe move "text" mode to "t" Err bitreich.org 70 i - implement ellipse Err bitreich.org 70 i-- filled box (B) Err bitreich.org 70 i-- manage fill character (as for other styles) Err bitreich.org 70 i+- (?) filled box (B) Err bitreich.org 70 i+- (?) manage filled box character (as for other styles) Err bitreich.org 70 i - implement comment (#: ignore until the end of the line) Err bitreich.org 70 i + parse control characters Err bitreich.org 70 i + parse arrows (text-mode will allow movements as well) Err bitreich.org 70 i@@ -15,15 +15,18 @@ Err bitreich.org 70 i - (?) remove extra blanks until EOL when saving to file Err bitreich.org 70 i + visual selection Err bitreich.org 70 i - crop-to Err bitreich.org 70 i- - yank/put Err bitreich.org 70 i+ * yank Err bitreich.org 70 i * fill Err bitreich.org 70 i- * delete Err bitreich.org 70 i+ * cut Err bitreich.org 70 i - undo (by storing lines changed across insert/remove operations) Err bitreich.org 70 i - manage special chars (DEL/CANC) during text insert Err bitreich.org 70 i (also do not print unmanaged chars!) Err bitreich.org 70 i - allow scrolling (both vertical and horizontal) Err bitreich.org 70 i - catch SIGWINCH and react appropriately (after scrolling is Err bitreich.org 70 i enabled) Err bitreich.org 70 i+* put yanked content (p) Err bitreich.org 70 i+* turn screen into a lineset Err bitreich.org 70 i+* change alloc/ensure functions to work on line_t* and lineset_t* Err bitreich.org 70 i * add crop command (C) Err bitreich.org 70 i * reorganise code Err bitreich.org 70 i * change screen management (i.e., dynamic array of lines) Err bitreich.org 70 1diff --git a/draw.c b/draw.c /scm/gramscii/file/draw.c.gph bitreich.org 70 i@@ -299,9 +299,15 @@ void visual_box(FILE *fc){ Err bitreich.org 70 i draw_box(x,y,NOFIX); Err bitreich.org 70 i while((c=fgetc(fc))!=EOF && c != 27 && c!= 'v' && c != '\n'){ Err bitreich.org 70 i if (!move_around(c, fc)) switch(c){ Err bitreich.org 70 i+ case 'y': /* yank (copy) */ Err bitreich.org 70 i+ yank_region(MIN(orig_x,x), MIN(orig_y,y), MAX(orig_x, x), MAX(orig_y, y)); Err bitreich.org 70 i+ goto vis_exit; Err bitreich.org 70 i+ break; Err bitreich.org 70 i case 'f':/* fill */ Err bitreich.org 70 i f = get_key(fc, "fill char: "); /** FALLTHROUGH **/ Err bitreich.org 70 i case 'x':/* erase */ Err bitreich.org 70 i+ if (c == 'x') Err bitreich.org 70 i+ yank_region(MIN(orig_x,x), MIN(orig_y,y), MAX(orig_x, x), MAX(orig_y, y)); Err bitreich.org 70 i erase_box(orig_x, orig_y, f); Err bitreich.org 70 i erase_blank_lines(MIN(y,orig_y), MAX(y, orig_y)); Err bitreich.org 70 i modified = 1; Err bitreich.org 70 i@@ -323,3 +329,8 @@ vis_exit: Err bitreich.org 70 i redraw(); Err bitreich.org 70 i mode = MOVE; Err bitreich.org 70 i } Err bitreich.org 70 i+ Err bitreich.org 70 i+void paste(){ Err bitreich.org 70 i+ paste_region(x, y); Err bitreich.org 70 i+ redraw(); Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/files.c b/files.c /scm/gramscii/file/files.c.gph bitreich.org 70 i@@ -24,7 +24,7 @@ void write_file(FILE *fc){ Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i for (i=0; i Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i-/** types **/ Err bitreich.org 70 i Err bitreich.org 70 i-typedef struct{ Err bitreich.org 70 i- int sz; Err bitreich.org 70 i- int lst; Err bitreich.org 70 i- char *s; Err bitreich.org 70 i-} line_t; Err bitreich.org 70 i Err bitreich.org 70 i /** constants **/ Err bitreich.org 70 i Err bitreich.org 70 i@@ -50,6 +44,20 @@ typedef struct{ Err bitreich.org 70 i #define VIDEO_NRM 0 Err bitreich.org 70 i #define VIDEO_REV 7 Err bitreich.org 70 i Err bitreich.org 70 i+/** types **/ Err bitreich.org 70 i+ Err bitreich.org 70 i+typedef struct{ Err bitreich.org 70 i+ int sz;/* allocated size*/ Err bitreich.org 70 i+ int n;/* line number */ Err bitreich.org 70 i+ int lst;/* last visible char (before the first \0) */ Err bitreich.org 70 i+ char *s; Err bitreich.org 70 i+} line_t; Err bitreich.org 70 i+ Err bitreich.org 70 i+typedef struct{ Err bitreich.org 70 i+ int sz;/* allocated size */ Err bitreich.org 70 i+ int num;/* number of lines stored */ Err bitreich.org 70 i+ line_t *l; Err bitreich.org 70 i+} lineset_t; Err bitreich.org 70 i Err bitreich.org 70 i /** MACROS **/ Err bitreich.org 70 i Err bitreich.org 70 i@@ -63,8 +71,9 @@ typedef struct{ Err bitreich.org 70 i Err bitreich.org 70 i /** global variables **/ Err bitreich.org 70 i Err bitreich.org 70 i-line_t *screen; Err bitreich.org 70 i-int num_lines; Err bitreich.org 70 i+lineset_t screen; Err bitreich.org 70 i+lineset_t cutbuf; Err bitreich.org 70 i+ Err bitreich.org 70 i int WIDTH, HEIGHT; Err bitreich.org 70 i Err bitreich.org 70 i int mode; Err bitreich.org 70 i@@ -96,6 +105,7 @@ char visual; Err bitreich.org 70 i char silent; Err bitreich.org 70 i char autoend; Err bitreich.org 70 i Err bitreich.org 70 i+ Err bitreich.org 70 i struct termios t1, t2, t3; Err bitreich.org 70 i Err bitreich.org 70 i /** screen-related functions **/ Err bitreich.org 70 i@@ -129,6 +139,7 @@ void get_box(FILE *fc); Err bitreich.org 70 i void get_arrow(FILE *fc); Err bitreich.org 70 i void erase(FILE *fc); Err bitreich.org 70 i void visual_box(FILE *fc); Err bitreich.org 70 i+void paste(); Err bitreich.org 70 i Err bitreich.org 70 i /** file-related functions **/ Err bitreich.org 70 i void write_file(FILE *fc); Err bitreich.org 70 i@@ -136,5 +147,14 @@ void check_modified(FILE *fc); Err bitreich.org 70 i void load_file(FILE *fc); Err bitreich.org 70 i void new_file(FILE *fc); Err bitreich.org 70 i Err bitreich.org 70 i+/** line-related functions **/ Err bitreich.org 70 i+ Err bitreich.org 70 i+void dump_lines(lineset_t ls, FILE *f); Err bitreich.org 70 i+void alloc_line(line_t *l); Err bitreich.org 70 i+void ensure_line_length(line_t *l, int len); Err bitreich.org 70 i+void ensure_num_lines(lineset_t *ls, int n); Err bitreich.org 70 i+void yank_region(int x1, int y1, int x2, int y2); Err bitreich.org 70 i+void paste_region(int x1, int y1); Err bitreich.org 70 i+ Err bitreich.org 70 i Err bitreich.org 70 i #endif Err bitreich.org 70 1diff --git a/lineset.c b/lineset.c /scm/gramscii/file/lineset.c.gph bitreich.org 70 i@@ -0,0 +1,117 @@ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include "gramscii.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+static int LONG_STEP; Err bitreich.org 70 i+ Err bitreich.org 70 i+/* line_t and lineset_t management */ Err bitreich.org 70 i+ Err bitreich.org 70 i+void ensure_line_length(line_t *l, int len){ Err bitreich.org 70 i+ char *tmp; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (l->sz < len + 1){ Err bitreich.org 70 i+ tmp = realloc(l->s, (len+1) * 2 * sizeof(char)); Err bitreich.org 70 i+ if (!tmp){ Err bitreich.org 70 i+ fprintf(stderr, "Unable to allocate string\n"); Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ l->s = tmp; Err bitreich.org 70 i+ l->sz = (len + 1) * 2; Err bitreich.org 70 i+ } Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+ Err bitreich.org 70 i+void alloc_line(line_t *l){ Err bitreich.org 70 i+ char *tmp; Err bitreich.org 70 i+ Err bitreich.org 70 i+ l->sz = WIDTH+1; Err bitreich.org 70 i+ tmp = malloc((l->sz) * sizeof(char)); Err bitreich.org 70 i+ if (tmp == NULL){ Err bitreich.org 70 i+ fprintf(stderr, "unable to allocate line\n"); Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ l->s = tmp; Err bitreich.org 70 i+ memset(l->s, BG, l->sz); Err bitreich.org 70 i+ l->lst = -1; Err bitreich.org 70 i+ l->s[0]='\0'; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void ensure_num_lines(lineset_t *ls, int n){ Err bitreich.org 70 i+ line_t *tmp; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (n > ls->sz){ Err bitreich.org 70 i+ if (ls->sz == 0) Err bitreich.org 70 i+ ls->l=NULL; Err bitreich.org 70 i+ tmp = realloc(ls->l, (n + LONG_STEP) * sizeof(line_t)); Err bitreich.org 70 i+ if (tmp == NULL){ Err bitreich.org 70 i+ fprintf(stderr, "Unable to allocate memory for more lines"); Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ else { Err bitreich.org 70 i+ ls->l = tmp; Err bitreich.org 70 i+ while ( ls->sz < n + LONG_STEP){ Err bitreich.org 70 i+ alloc_line(&(ls->l[ls->sz])); Err bitreich.org 70 i+ ls->sz ++; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void dump_lines(lineset_t ls, FILE *f){ Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ for (i=0; i Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i-#include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #include "gramscii.h" Err bitreich.org 70 i #include "config.h" Err bitreich.org 70 i@@ -62,7 +62,7 @@ void status_bar(){ Err bitreich.org 70 i else Err bitreich.org 70 i printf(" *%s*", fname ); Err bitreich.org 70 i #ifdef DEBUG Err bitreich.org 70 i- printf(" '%d' ", screen[y].s[x]); Err bitreich.org 70 i+ printf(" '%d' ", screen.l[y].s[x]); Err bitreich.org 70 i #endif Err bitreich.org 70 i printf("\033[0m"); Err bitreich.org 70 i fflush(stdout); Err bitreich.org 70 i@@ -109,52 +109,6 @@ int is_yes(char c){ Err bitreich.org 70 i Err bitreich.org 70 i /*** Screen management ***/ Err bitreich.org 70 i Err bitreich.org 70 i-void ensure_line_length(int i, int len){ Err bitreich.org 70 i- char *tmp; Err bitreich.org 70 i- Err bitreich.org 70 i- if (screen[i].sz < len + 1){ Err bitreich.org 70 i- tmp = realloc(screen[i].s, (len+1) * 2 * sizeof(char)); Err bitreich.org 70 i- if (!tmp){ Err bitreich.org 70 i- fprintf(stderr, "Unable to allocate string\n"); Err bitreich.org 70 i- exit(1); Err bitreich.org 70 i- } Err bitreich.org 70 i- screen[i].s = tmp; Err bitreich.org 70 i- screen[i].sz = (len + 1) * 2; Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i- Err bitreich.org 70 i-void alloc_line(int i){ Err bitreich.org 70 i- char *tmp; Err bitreich.org 70 i- Err bitreich.org 70 i- screen[i].sz = WIDTH+1; Err bitreich.org 70 i- tmp = malloc((screen[i].sz) * sizeof(char)); Err bitreich.org 70 i- if (tmp == NULL){ Err bitreich.org 70 i- fprintf(stderr, "unable to allocate line %d\n", i+1); Err bitreich.org 70 i- exit(1); Err bitreich.org 70 i- } Err bitreich.org 70 i- screen[i].s = tmp; Err bitreich.org 70 i- memset(screen[i].s, BG, screen[i].sz); Err bitreich.org 70 i- screen[i].lst = -1; Err bitreich.org 70 i- screen[i].s[0]='\0'; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void ensure_num_lines(int n){ Err bitreich.org 70 i- line_t *tmp; Err bitreich.org 70 i- Err bitreich.org 70 i- if (n > num_lines){ Err bitreich.org 70 i- tmp = realloc(screen, (n + LONG_STEP) * sizeof(line_t)); Err bitreich.org 70 i- if (tmp == NULL){ Err bitreich.org 70 i- fprintf(stderr, "Unable to allocate memory for more lines"); Err bitreich.org 70 i- exit(1); Err bitreich.org 70 i- } Err bitreich.org 70 i- else while ( num_lines < n + LONG_STEP){ Err bitreich.org 70 i- alloc_line(num_lines); Err bitreich.org 70 i- num_lines ++; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i Err bitreich.org 70 i void show_cursor(){ Err bitreich.org 70 i if (silent) Err bitreich.org 70 i@@ -165,15 +119,15 @@ void show_cursor(){ Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void set_xy(int _x, int _y, char c){ Err bitreich.org 70 i- ensure_num_lines(_y + 1); Err bitreich.org 70 i- ensure_line_length(_y, _x + 1); Err bitreich.org 70 i- while (screen[_y].lst<_x){ Err bitreich.org 70 i- screen[_y].lst ++; Err bitreich.org 70 i- screen[_y].s[screen[_y].lst] = BG; Err bitreich.org 70 i+ ensure_num_lines(&screen, _y + 1); Err bitreich.org 70 i+ ensure_line_length(&(screen.l[_y]), _x + 1); Err bitreich.org 70 i+ while (screen.l[_y].lst<_x){ Err bitreich.org 70 i+ screen.l[_y].lst ++; Err bitreich.org 70 i+ screen.l[_y].s[screen.l[_y].lst] = BG; Err bitreich.org 70 i } Err bitreich.org 70 i- screen[_y].s[_x] = c; Err bitreich.org 70 i- if (_x == screen[_y].lst) Err bitreich.org 70 i- screen[_y].s[_x+1] = '\0'; Err bitreich.org 70 i+ screen.l[_y].s[_x] = c; Err bitreich.org 70 i+ if (_x == screen.l[_y].lst) Err bitreich.org 70 i+ screen.l[_y].s[_x+1] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void set_cur(char c){ Err bitreich.org 70 i@@ -193,7 +147,7 @@ void update_current(){ Err bitreich.org 70 i if (silent) Err bitreich.org 70 i return; Err bitreich.org 70 i printf("\033[%d'%df",y+1,x+1); Err bitreich.org 70 i- putchar(screen[y].s[x]); Err bitreich.org 70 i+ putchar(screen.l[y].s[x]); Err bitreich.org 70 i fflush(stdout); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -206,20 +160,20 @@ void erase_blank_lines(int y1, int y2){ Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i for (; y1 <= y2; y1++){ Err bitreich.org 70 i- j = screen[y1].lst; Err bitreich.org 70 i- while (j>=0 && isblank(screen[y1].s[j])) Err bitreich.org 70 i+ j = screen.l[y1].lst; Err bitreich.org 70 i+ while (j>=0 && isblank(screen.l[y1].s[j])) Err bitreich.org 70 i j--; Err bitreich.org 70 i if (j<0){ Err bitreich.org 70 i- screen[y1].lst = -1; Err bitreich.org 70 i- screen[y1].s[0] = '\0'; Err bitreich.org 70 i+ screen.l[y1].lst = -1; Err bitreich.org 70 i+ screen.l[y1].s[0] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void erase_line(int i){ Err bitreich.org 70 i- screen[i].lst = -1; Err bitreich.org 70 i- screen[i].s[0] = '\0'; Err bitreich.org 70 i+ screen.l[i].lst = -1; Err bitreich.org 70 i+ screen.l[i].s[0] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void erase_box(int x1, int y1, char c){ Err bitreich.org 70 i@@ -268,7 +222,7 @@ void redraw(){ Err bitreich.org 70 i return; Err bitreich.org 70 i printf("\033[2J\033[1;1H"); Err bitreich.org 70 i for (i=0;i *x2) Err bitreich.org 70 i *x2 = j; Err bitreich.org 70 i@@ -483,13 +441,13 @@ void crop_to_rect(int x1, int y1, int x2, int y2){ Err bitreich.org 70 i int i; Err bitreich.org 70 i Err bitreich.org 70 i for (i=0; i<= y2-y1; i ++){ Err bitreich.org 70 i- ensure_line_length(i, screen[i+y1].lst); Err bitreich.org 70 i- sprintf(screen[i].s, "%s", screen[i+y1].s + x1); Err bitreich.org 70 i- screen[i].lst = screen[i+y1].lst - x1; Err bitreich.org 70 i+ ensure_line_length(&(screen.l[i]), screen.l[i+y1].lst); Err bitreich.org 70 i+ sprintf(screen.l[i].s, "%s", screen.l[i+y1].s + x1); Err bitreich.org 70 i+ screen.l[i].lst = screen.l[i+y1].lst - x1; Err bitreich.org 70 i } Err bitreich.org 70 i while (i<=y2){ Err bitreich.org 70 i- screen[i].lst = -1; Err bitreich.org 70 i- screen[i].s[0]= '\0'; Err bitreich.org 70 i+ screen.l[i].lst = -1; Err bitreich.org 70 i+ screen.l[i].s[0]= '\0'; Err bitreich.org 70 i i ++; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i@@ -505,3 +463,4 @@ void crop_to_nonblank(){ Err bitreich.org 70 i redraw(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+ Err bitreich.org 70 .