From c16e74036e791b2c1f9c19841fc75a60067aefec Mon Sep 17 00:00:00 2001 From: KatolaZ Date: Thu, 8 Aug 2019 08:39:04 +0100 Subject: fix bug with global movements in arrow mode --- TODO | 2 +- draw.c | 24 +++++++++++++----------- gramscii.c | 2 +- gramscii.h | 6 ++---- screen.c | 38 +++++++++++++++++++++++++++++--------- 5 files changed, 46 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index a406bfa..579ff78 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ + optimize redraws (redraw only the modified rectangle) -- fix bug with 'g' commands in arrow mode - fir bug in reading commands from files - add screen geometry option (-g 25x80?) - read file at point @@ -18,6 +17,7 @@ - allow scrolling (both vertical and horizontal) - catch SIGWINCH and react appropriately (after scrolling is enabled) +* fix bug with 'g' commands in arrow mode * undo (by storing lines changed across insert/remove operations) * re-organise undo-ring management * add undo for arrow mode diff --git a/draw.c b/draw.c index 1c383fa..8c30d56 100644 --- a/draw.c +++ b/draw.c @@ -148,7 +148,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, fc)) + if (!move_around(c, fc, 1)) continue; check_bound(&x, &y); redraw(); @@ -166,7 +166,7 @@ update_box: mode = MOVE; } -void draw_arrow(int xl, int yl, char *a, int a_len, int fix){ +void draw_arrow(int xl, int yl, short *a, int a_len, int fix){ int i, j, cur_dir; char line; @@ -218,12 +218,12 @@ void get_arrow(FILE *fc){ char c; int orig_x=x, orig_y=y, arrow_len; - static char *arrow = NULL; + static short *arrow = NULL; static int arrow_sz; if (!arrow){ arrow_sz = 100; - arrow = malloc(arrow_sz * sizeof(char)); + arrow = malloc(arrow_sz * sizeof(short)); } arrow_len = 0; dir = DIR_N; @@ -234,17 +234,19 @@ 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, fc)) + if (!move_around(c, fc, 0)) continue; check_bound(&x, &y); /* FIXME: if we are out of bound, do nothing? */ if (arrow_len == arrow_sz){ arrow_sz *=2; - arrow = realloc(arrow, arrow_sz * sizeof(char)); + arrow = realloc(arrow, arrow_sz * sizeof(short)); } - arrow[arrow_len++] = dir; - arrow[arrow_len++] = step; - redraw(); + if (dir != DIR_N){ + arrow[arrow_len++] = dir; + arrow[arrow_len++] = step; + } + redraw(); step = 1; update_arrow: draw_arrow(orig_x, orig_y, arrow, arrow_len, NOFIX); @@ -289,7 +291,7 @@ void erase(FILE *fc){ status_bar(); show_cursor(); while((c=fgetc(fc))!=EOF && c!=27 && c!= 'x' && c != '\n'){ - if (!move_around(c, fc)) continue; + if (!move_around(c, fc, 0)) continue; check_bound(&x, &y); if (first || (y != orig_y && ! opened) || @@ -329,7 +331,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, fc)) switch(c){ + if (!move_around(c, fc, 1)) switch(c){ case 'y': /* yank (copy) */ yank_region(MIN(orig_x,x), MIN(orig_y,y), MAX(orig_x, x), MAX(orig_y, y)); goto vis_exit; diff --git a/gramscii.c b/gramscii.c index 6b40009..6dee819 100644 --- a/gramscii.c +++ b/gramscii.c @@ -72,7 +72,7 @@ void commands(FILE *fc){ char c; while((c=fgetc(fc))!=EOF){ - if (!change_style(c) && !move_around(c, fc)){ + if (!change_style(c) && !move_around(c, fc, 1)){ switch(c){ case 'i': mode = TEXT; diff --git a/gramscii.h b/gramscii.h index 83d2719..2c09484 100644 --- a/gramscii.h +++ b/gramscii.h @@ -82,9 +82,7 @@ typedef struct{ #define progr_x(d) ((d) == DIR_L ? -1 : (d) == DIR_R ? 1 : 0) #define progr_y(d) ((d) == DIR_U ? -1 : (d) == DIR_D ? 1 : 0) -/* - * #define DEBUG 1 - */ +#define DEBUG 1 /** global variables **/ @@ -140,7 +138,7 @@ struct termios t1, t2, t3; /** screen-related functions **/ void reset_styles(); void redraw(); -int move_around(char c, FILE *fc); +int move_around(char c, FILE *fc, char global); void check_bound(int *x, int *y); void status_bar(); void show_cursor(); diff --git a/screen.c b/screen.c index 587abd7..3c69541 100644 --- a/screen.c +++ b/screen.c @@ -252,39 +252,53 @@ void go_to(int where){ show_cursor(); } -void handle_goto(){ +void handle_goto(char global){ char c; c=getchar(); switch(c){ case 'h': dir = DIR_L; + step = x; x = 0; break; case 'l': dir = DIR_R; + step = WIDTH - x -1; x = WIDTH - 1; break; case 'j': dir = DIR_D; + step = HEIGHT - y-1; y = HEIGHT - 1; break; case 'k': dir = DIR_U; + step = y; y = 0; break; case 'g': - dir = DIR_N; - go_to(HOME); + if (global){ + dir = DIR_N; + go_to(HOME); + } else step = 0; break; case 'G': - dir = DIR_N; - go_to(END); + if (global){ + dir = DIR_N; + go_to(END); + } else step = 0; break; case 'm': - dir = DIR_N; - go_to(MIDDLE); + if (global){ + dir = DIR_N; + go_to(MIDDLE); + } else step = 0; break; } + +#ifdef DEBUG + fprintf(stderr, "global move: dir: %d x: %d y: %d\n", dir, x, y); +#endif check_bound(&x, &y); show_cursor(); } @@ -324,7 +338,7 @@ int get_escape(FILE *fc){ } -int move_around(char c, FILE *fc){ +int move_around(char c, FILE *fc, char global){ if (isdigit(c)){ if (mult) @@ -365,7 +379,13 @@ int move_around(char c, FILE *fc){ x += step; break; case 'g': - handle_goto(); +#ifdef DEBUG + fprintf(stderr, "before global: step: %d x: %d y: %d\n", step, x, y); +#endif + handle_goto(global); +#ifdef DEBUG + fprintf(stderr, "after global: step: %d x: %d y: %d\n", step, x, y); +#endif break; default: return 0; -- cgit v1.2.3