Merge branch 'devel' into master - gramscii - A simple editor for ASCII box-and… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit 8b67bd6c5f4e175721b44d4733d1a5a6fc1a2561 | |
parent f68467d70a9f89a6d901302907ee97533f0167d4 | |
Author: KatolaZ <[email protected]> | |
Date: Fri, 26 Jul 2019 23:03:00 +0100 | |
Merge branch 'devel' into master | |
Diffstat: | |
M TODO | 7 +++---- | |
M gramscii.c | 97 ++++++++++++++++++++++-------… | |
2 files changed, 74 insertions(+), 30 deletions(-) | |
--- | |
diff --git a/TODO b/TODO | |
@@ -1,5 +1,4 @@ | |
+ optimize redraws (redraw only the modified rectangle) | |
-- change screen management (i.e., dynamic array of lines) | |
- add screen geometry option (-g 25x80?) | |
- read file at point | |
- read output of command (!) | |
@@ -10,7 +9,7 @@ | |
+ 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 | |
+- (?) remove extra blanks until EOL when saving to file | |
+ visual selection | |
- crop-to | |
- yank/put | |
@@ -20,8 +19,9 @@ | |
- manage special chars (DEL/CANC) during text insert | |
(also do not print unmanaged chars!) | |
- allow scrolling (both vertical and horizontal) | |
-- catch SIGWINCH and react appropriately (after scroll is | |
+- catch SIGWINCH and react appropriately (after scrolling is | |
enabled) | |
+* 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"?) | |
* auto-arrow 'A' (automatic end-char) | |
@@ -48,4 +48,3 @@ | |
* set different line styles (done for hl, vl, corner) | |
* add status bar | |
* implement box | |
- | |
diff --git a/gramscii.c b/gramscii.c | |
@@ -33,6 +33,13 @@ | |
#include "arg.h" | |
+typedef struct{ | |
+ int sz; | |
+ int lst; | |
+ char *s; | |
+} line_t; | |
+ | |
+ | |
#define MOVE 0x00 | |
#define BOX 0x01 | |
#define ARROW 0x02 | |
@@ -71,9 +78,10 @@ | |
#define MIN(x,y) (x) < (y) ? (x) : (y) | |
#define MAX(x,y) (x) > (y) ? (x) : (y) | |
-/** #define DEBUG 1 **/ | |
+#define DEBUG 1 | |
-char **screen; | |
+line_t *screen; | |
+int num_lines; | |
int WIDTH, HEIGHT; | |
int state; | |
@@ -113,7 +121,7 @@ struct termios t1, t2, t3; | |
void dump_lines(){ | |
int i; | |
for (i=0; i<HEIGHT; i++){ | |
- printf("%s\n", screen[i]); | |
+ printf("%s\n", screen[i].s); | |
} | |
} | |
@@ -128,6 +136,11 @@ void cleanup(int s){ | |
exit(0); | |
} | |
+void exit_cleanup(void){ | |
+ cleanup(0); | |
+} | |
+ | |
+ | |
/*** Status bar ***/ | |
char* state_str(){ | |
@@ -179,7 +192,7 @@ void status_bar(){ | |
else | |
printf(" *%s*", fname ); | |
#ifdef DEBUG | |
- printf(" '%d' ", screen[y][x]); | |
+ printf(" '%d' ", screen[y].s[x]); | |
#endif | |
printf("\033[0m"); | |
fflush(stdout); | |
@@ -193,6 +206,7 @@ char get_key(FILE *fc, char *msg){ | |
printf("%*s", WIDTH, ""); | |
printf("\033[%d;1f\033[7m", HEIGHT+1); | |
printf("%s", msg); | |
+ fflush(stdout); | |
printf("\033[0m"); | |
fflush(stdout); | |
return fgetc(fc); | |
@@ -232,13 +246,43 @@ void show_cursor(){ | |
fflush(stdout); | |
} | |
-void set_cur(char c){ | |
- screen[y][x] = c; | |
+ | |
+void set_xy(int _x, int _y, char c){ | |
+ line_t *tmp; | |
+ if (_y >= num_lines){ | |
+ tmp = realloc(screen, (_y + LONG_STEP)* sizeof(line_t)); | |
+ if (tmp == NULL){ | |
+ fprintf(stderr, "Unable to allocate memory for more li… | |
+ exit(1); | |
+ } | |
+ else while ( num_lines < _y + LONG_STEP){ | |
+ screen[num_lines].sz = WIDTH+1; | |
+ screen[num_lines].s = malloc((screen[num_lines].sz) * … | |
+ if (screen[num_lines].s == NULL){ | |
+ perror("allocating screen[num_lines].s"); | |
+ exit(1); | |
+ } | |
+ memset(screen[num_lines].s, BG, screen[num_lines].sz); | |
+ screen[num_lines].lst = 0; | |
+ screen[num_lines].s[screen[num_lines].lst+1]='\0'; | |
+ num_lines ++; | |
+ } | |
+ } | |
+ if (screen[_y].sz < _x + 2){ | |
+ screen[_y].sz = (_x +2) * 2; | |
+ screen[_y].s = realloc(screen[_y].s, screen[_y].sz * sizeof(ch… | |
+ } | |
+ while (screen[_y].lst<_x){ | |
+ screen[_y].lst ++; | |
+ screen[_y].s[screen[_y].lst] = BG; | |
+ } | |
+ screen[_y].s[_x] = c; | |
+ if (_x == screen[_y].lst) | |
+ screen[_y].s[_x+1] = '\0'; | |
} | |
-void set_xy(int x, int y, char c){ | |
- /* FIXME: check if x and y are valid!!!! */ | |
- screen[y][x] = c; | |
+void set_cur(char c){ | |
+ set_xy(x, y, c); | |
} | |
void draw_xy(int x, int y, char c){ | |
@@ -254,7 +298,7 @@ void update_current(){ | |
if (silent) | |
return; | |
printf("\033[%d'%df",y+1,x+1); | |
- putchar(screen[y][x]); | |
+ putchar(screen[y].s[x]); | |
fflush(stdout); | |
} | |
@@ -282,7 +326,7 @@ void erase_box(int x1, int y1, char c){ | |
void erase_screen(){ | |
int i; | |
for(i=0;i<HEIGHT; i++) | |
- erase_line(screen[i]); | |
+ erase_line(screen[i].s); | |
} | |
void check_bound(){ | |
@@ -311,7 +355,7 @@ void redraw(){ | |
return; | |
printf("\033[2J\033[1;1H"); | |
for (i=0;i<HEIGHT;i++){ | |
- fprintf(stdout,"%s\n",screen[i]); | |
+ fprintf(stdout,"%s\n",screen[i].s); | |
} | |
status_bar(); | |
show_cursor(); | |
@@ -774,7 +818,7 @@ void write_file(FILE *fc){ | |
return; | |
} | |
for (i=0; i<HEIGHT; i++){ | |
- fprintf(fout, "%s\n", screen[i]); | |
+ fprintf(fout, "%s\n", screen[i].s); | |
} | |
fclose(fout); | |
modified = 0; | |
@@ -787,7 +831,7 @@ void check_modified(FILE *fc){ | |
if (!is_yes(get_key(fc, "Unsaved changes. Write to file [y/n]?… | |
return; | |
} | |
- write_file(0); | |
+ write_file(fc); | |
} | |
} | |
@@ -800,10 +844,10 @@ void load_file(FILE *fc){ | |
get_string(fc, "Load file: ", newfname, 255); | |
if ((fin=fopen(newfname, "r")) != NULL){ | |
i = 0; | |
- while((fgets(screen[i], WIDTH+2, fin)) != NULL && i<HEIGHT) | |
- screen[i++][WIDTH-1]='\0'; | |
+ while((fgets(screen[i].s, WIDTH+2, fin)) != NULL && i<HEIGHT) | |
+ screen[i++].s[WIDTH-1]='\0'; | |
for(;i<HEIGHT; i++){ | |
- erase_line(screen[i]); | |
+ erase_line(screen[i].s); | |
} | |
fclose(fin); | |
} | |
@@ -872,30 +916,33 @@ void init_screen(){ | |
WIDTH=80; | |
HEIGHT=24; | |
} | |
- screen = malloc(HEIGHT * sizeof(char *)); | |
+ screen = malloc(HEIGHT * sizeof(line_t)); | |
+ num_lines = HEIGHT; | |
if (screen == NULL){ | |
perror("allocating screen"); | |
exit(1); | |
} | |
for (i=0; i<HEIGHT; i++){ | |
- screen[i] = malloc((WIDTH+1) * sizeof(char)); | |
- if (screen[i] == NULL){ | |
- perror("allocating screen[i]"); | |
+ screen[i].sz = WIDTH+1; | |
+ screen[i].s = malloc((screen[i].sz) * sizeof(char)); | |
+ if (screen[i].s == NULL){ | |
+ perror("allocating screen[i].s"); | |
exit(1); | |
} | |
- memset(screen[i], ' ', WIDTH * sizeof(char)); | |
- screen[i][WIDTH]='\0'; | |
+ memset(screen[i].s, BG, screen[i].sz); | |
+ screen[i].lst = 0; | |
+ screen[i].s[screen[i].lst+1]='\0'; | |
} | |
reset_styles(); | |
} | |
- | |
void init(){ | |
signal(SIGHUP, cleanup); | |
signal(SIGINT, cleanup); | |
signal(SIGTERM, cleanup); | |
signal(SIGQUIT, cleanup); | |
+ atexit(exit_cleanup); | |
tcgetattr(0, &t1); | |
t2 = t1; | |
@@ -960,7 +1007,6 @@ void commands(FILE *fc){ | |
case 'q': | |
check_modified(fc);/** FALLTHROUGH **/ | |
case 'Q': | |
- cleanup(0); | |
exit(0); | |
break; | |
} | |
@@ -1007,6 +1053,5 @@ int main(int argc, char *argv[]){ | |
argc--; | |
} | |
commands(stdin); | |
- cleanup(0); | |
return 0; | |
} |