URI: 
       draw.c - gramscii - A simple editor for ASCII box-and-arrow charts
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       draw.c (14191B)
       ---
            1 #define _POSIX_C_SOURCE 200112L
            2 
            3 #include <stdlib.h>
            4 #include <string.h>
            5 
            6 #include "gramscii.h"
            7 #include "config.h"
            8 
            9 /** Extern declarations **/
           10 
           11 extern int WIDTH, HEIGHT;
           12 extern lineset_t screen; /* what is visualised */
           13 extern lineset_t cutbuf; /* cut/paste buffer */
           14 extern lineset_t *undo;  /* undo list */
           15 
           16 extern int undo_cur;/* undo position */
           17 extern int undo_lst;/* last valid undo position */
           18 
           19 
           20 extern int mode;/* mode */
           21 extern int dir;/* line direction */
           22 extern int step;/* current step */
           23 extern int x;
           24 extern int y;
           25 extern char corner;
           26 extern char modified; /* set to 1 if screen modified since last save */ 
           27 
           28 /* line and arrow markers */
           29 extern int cur_hl, cur_vl, cur_corn, cur_start, cur_end;
           30 extern char line_h;
           31 extern char line_v;
           32 extern char mark_st;
           33 extern char mark_end;
           34 
           35 /* number of available markers for each type */
           36 extern int hlines_sz;
           37 extern int vlines_sz;
           38 extern int corners_sz;
           39 extern int stmarks_sz;
           40 extern int endmarks_sz;
           41 
           42 
           43 extern char autoend; /* set to 1 in auto-arrow mode */
           44 
           45 /* Used by draw_arrow to identify the bounding box */
           46 extern int a_miny;
           47 extern int a_maxy;
           48 
           49 /*** drawing-related functions ***/
           50 
           51 /*** Lines and markers ***/
           52 
           53 void toggle_hline(){
           54 
           55         cur_hl = (cur_hl + 1) % hlines_sz;
           56         line_h = hlines[cur_hl];
           57 
           58 }
           59 
           60 void toggle_corner(){
           61 
           62         cur_corn = (cur_corn + 1 ) % corners_sz;
           63         corner = corners[cur_corn];
           64 
           65 }
           66 
           67 void toggle_vline(){
           68 
           69         cur_vl = (cur_vl + 1) % vlines_sz;
           70         line_v = vlines[cur_vl];
           71 
           72 }
           73 
           74 void toggle_st_mark(){
           75 
           76         cur_start = (cur_start + 1 ) % stmarks_sz;
           77         mark_st = st_marks[cur_start];
           78 }
           79 
           80 void toggle_end_mark(){
           81 
           82         cur_end = (cur_end+ 1 ) % endmarks_sz;
           83         mark_end = end_marks[cur_end];
           84 }
           85 
           86 int change_style(char c){
           87         switch(c){
           88                 case '-':
           89                         toggle_hline();
           90                         break;
           91                 case '|':
           92                         toggle_vline();
           93                         break;
           94                 case '+':
           95                         toggle_corner();
           96                         break;
           97                 case '<':
           98                         toggle_st_mark();
           99                         break;
          100                 case '>':
          101                         toggle_end_mark();
          102                         break;
          103                 case '.':
          104                         reset_styles();
          105                         break;
          106                 default: 
          107                         return 0;
          108         }
          109         return c;
          110 }
          111 
          112 
          113 
          114 
          115 /*****  text, box, arrows  *****/
          116 
          117 void get_text(FILE *fc){
          118         char c;
          119         int orig_x = x;
          120 
          121         redraw();
          122         copy_lines_to_ring(y, y, PRV_STATE);
          123         while((c=fgetc(fc))!=EOF && c != 27){
          124                 if(c=='\n'){
          125                         set_cur(BG);
          126                         copy_lines_to_ring(y,y, NEW_STATE);
          127                         y += 1;
          128                         copy_lines_to_ring(y, y, PRV_STATE);
          129                         x = orig_x;
          130                 }
          131                 else {
          132                         set_cur(c);
          133                         update_current();
          134                         modified = 1;
          135                         x += 1;
          136                         if (x >= WIDTH)
          137                                 x = orig_x;
          138                 }
          139                 check_bound(&x, &y);
          140                 status_bar();
          141                 show_cursor();
          142         }
          143         if (modified)
          144                 copy_lines_to_ring(y, y, NEW_STATE);
          145         mode=MOVE;
          146 }
          147 
          148 void draw_box(int x1, int y1, int fix){
          149 
          150         int xmin, ymin, xmax, ymax;
          151         int i;
          152         void (*f)(int, int, char);
          153 
          154 
          155         xmin = MIN(x, x1);
          156         xmax = MAX(x, x1);
          157         ymin = MIN(y, y1);
          158         ymax = MAX(y, y1);
          159 
          160         if (fix == FIX){
          161                 f = set_xy;
          162                 copy_lines_to_ring(ymin, ymax, PRV_STATE);
          163         }
          164         else
          165                 f = draw_xy;
          166 
          167         for(i=xmin+1; i<=xmax; i++){
          168                 f(i, ymin, line_h);
          169                 f(i, ymax, line_h);
          170         }
          171         for(i=ymin+1; i<=ymax; i++){
          172                 f(xmin, i, line_v);
          173                 f(xmax, i, line_v);
          174         }
          175         f(xmin, ymin, corner);
          176         f(xmin, ymax, corner);
          177         f(xmax, ymin, corner);
          178         f(xmax, ymax, corner);
          179         if (fix == FIX)
          180                 copy_lines_to_ring(ymin, ymax, NEW_STATE);
          181         show_cursor();
          182 }
          183 
          184 void draw_parallelogram(int x1, int y1, char st, char fix){
          185         int xmin, ymin, xmax, ymax;
          186         int dy, minoff, maxoff, xoff, xincr;
          187         int i;
          188         char lean;
          189         void (*f)(int, int, char);
          190 
          191 
          192         xmin = MIN(x, x1);
          193         xmax = MAX(x, x1);
          194         ymin = MIN(y, y1);
          195         ymax = MAX(y, y1);
          196         dy = ymax - ymin;
          197         
          198         if (fix == FIX){
          199                 f = set_xy;
          200                 copy_lines_to_ring(ymin, ymax, PRV_STATE);
          201         }
          202         else
          203                 f = draw_xy;
          204         if (st == BOX_PARR){
          205                 minoff = dy;
          206                 maxoff = 0;
          207                 lean = '/';
          208                 xincr = -1;
          209         }
          210         else {
          211                 minoff = 0;
          212                 maxoff = dy;
          213                 lean = '\\';
          214                 xincr = +1;
          215         }
          216         for(i=xmin+1; i<=xmax-dy; i++){
          217                 f(i+minoff, ymin, line_h);
          218                 f(i+maxoff, ymax, line_h);
          219         }
          220         
          221         for(i=ymin+1, xoff=minoff; i<=ymax; i++, xoff += xincr){
          222                 f(xmin+(xoff+xincr), i, lean);
          223                 if (minoff)
          224                         f(xmax - (minoff - xoff - xincr), i, lean);
          225                 else 
          226                         f(xmax - (maxoff - xoff - xincr), i, lean);
          227         }
          228         f(xmin+minoff, ymin, corner);
          229         f(xmin+maxoff, ymax, corner);
          230         f(xmax-maxoff, ymin, corner);
          231         f(xmax-minoff, ymax, corner);
          232         if (fix == FIX)
          233                 copy_lines_to_ring(ymin, ymax, NEW_STATE);
          234         show_cursor();
          235 
          236 }
          237 
          238 char flip_par_lean(char st){
          239         if (st == BOX_PARR)
          240                 return BOX_PARL;
          241         else if (st == BOX_PARL)
          242                 return BOX_PARR;
          243         return st;
          244 }
          245 
          246 void draw_trapezium(int x1, int y1, char st, char fix){
          247         int xmin, ymin, xmax, ymax;
          248         int dx, dy, ylong, yshort, xoff;
          249         int xincr;
          250         int i;
          251         void (*f)(int, int, char);
          252         char left_c, right_c;
          253 
          254         xmin = MIN(x, x1);
          255         xmax = MAX(x, x1);
          256         ymin = MIN(y, y1);
          257         ymax = MAX(y, y1);
          258         dx = (xmax - xmin);
          259         dy = ymax - ymin;
          260         /* dy = MAX(dx2, dy); */
          261 #ifdef DEBUG
          262         fprintf(stderr, "dy: %d dx: %d\n", dy, dx);
          263 #endif        
          264         if (fix == FIX){
          265                 f = set_xy;
          266                 copy_lines_to_ring(ymin, ymax, PRV_STATE);
          267         }
          268         else
          269                 f = draw_xy;
          270 
          271         /* This is valid only for "upper" trapezoids */
          272         if (STYLE_IS(st, BOX_TRAP_U)){
          273 #ifdef DEBUG
          274                 fprintf(stderr, "This is an 'upward' trapezium\n");
          275 #endif
          276                 ylong = ymax;
          277                 yshort = ymin;
          278                 xoff = dy;
          279                 xincr = -1;
          280                 left_c = '/';
          281                 right_c = '\\';
          282         }
          283         else if (STYLE_IS(st, BOX_TRAP_D)){
          284 #ifdef DEBUG
          285                 fprintf(stderr, "This is a 'downward' trapezium\n");
          286 #endif
          287                 ylong = ymin;
          288                 yshort = ymax;
          289                 xoff = dy;
          290                 xincr = +1;
          291                 right_c = '/';
          292                 left_c = '\\';
          293         }
          294         /* Long side */
          295         for(i=xmin+1; i<=xmax; i++){
          296                 f(i, ylong, line_h);
          297         }
          298         
          299         if (STYLE_IS(st, BOX_TRAP_L)){
          300                 /* short side */
          301                 left_c = '/';
          302                 right_c = line_v;
          303                 for(i=xmin+xoff;i<xmax; i++){
          304                         f(i, yshort, line_h);
          305                 }
          306                 xoff = dy;
          307                 if (STYLE_IS(st, BOX_TRAP_D)){
          308                         xoff = 0;
          309                         left_c = '\\';
          310                 }
          311                 for(i=ymin; i<ymax; i++, xoff += xincr){
          312                         f(xmin+xoff, i, left_c);
          313                         f(xmax, i, right_c);
          314                 }
          315                 f(xmin+dy, yshort, corner);
          316                 f(xmax, yshort, corner);
          317         }
          318         else if (STYLE_IS(st, BOX_TRAP_R)){
          319                 right_c = '\\';
          320                 left_c = line_v;
          321                 for(i=xmin; i<xmax-xoff; i++){
          322                         f(i, yshort, line_h);
          323                 }
          324                 xoff = dy-1;
          325                 if (STYLE_IS(st, BOX_TRAP_D)){
          326                         xoff = 1;
          327                         right_c = '/';
          328                 }
          329                 for(i=ymin+1; i<ymax; i++, xoff += xincr){
          330                         f(xmin, i, left_c);
          331                         f(xmax-xoff, i, right_c);
          332                 }
          333                 f(xmin, yshort, corner);
          334                 f(xmax-dy, yshort, corner);
          335         }
          336         else if (STYLE_IS(st, BOX_TRAP_C)){
          337                 xoff = dy;
          338                 for (i=xmin+xoff; i<=xmax-xoff; i++){
          339                         f(i, yshort, line_h);
          340                 }
          341                 xoff = dy - 1;
          342                 if (STYLE_IS(st, BOX_TRAP_D))
          343                         xoff = 1;
          344                 for(i=ymin+1; i<ymax; i++, xoff += xincr){
          345                         f(xmin + xoff, i, left_c);
          346                         f(xmax - xoff, i, right_c);
          347                 }
          348                 f(xmin+dy, yshort, corner);
          349                 f(xmax-dy, yshort, corner);
          350         }
          351         
          352 
          353         f(xmin, ylong, corner);
          354         f(xmax, ylong, corner);
          355 
          356         
          357         if (fix == FIX)
          358                 copy_lines_to_ring(ymin, ymax, NEW_STATE);
          359         show_cursor();
          360 
          361 }
          362 
          363 /* 
          364  * draw the current box, being it an actual box, a parallelogram, or a 
          365  *  trapezium
          366  */
          367 void update_box(int x1, int y1, char st, char fix){
          368 
          369         if (st == BOX_RECT)
          370                 draw_box(x1, y1, fix);
          371         else if (st & BOX_PAR)
          372                 draw_parallelogram(x1, y1, st, fix);
          373         else if (st & BOX_TRAP)
          374                 draw_trapezium(x1, y1, st, fix);
          375         status_bar();
          376         show_cursor();
          377 }
          378 
          379 char toggle_trap_type(char st){
          380         if (st & BOX_TRAP){
          381                 if (st != BOX_TRAP_DR)
          382                         st += 1;
          383                 else 
          384                         st = BOX_TRAP_UR;
          385         }
          386         if (st == BOX_TRAP_D) 
          387                 st += 1;
          388         return st;
          389 }
          390 
          391 int box_end(char c, char st){
          392         if (c == '\n' || 
          393             c == 27   ||
          394             ((st == BOX_RECT) &&  c == 'b') ||
          395             ((st & BOX_PAR)   &&  c == 'z') ||
          396             ((st & BOX_TRAP)  &&  c == 't'))
          397                 return 1;
          398         return 0; 
          399 }
          400 
          401 /* draw boxes, parallelograms, and trapezia */
          402 void get_box(FILE *fc, char st){
          403         char c;
          404         int orig_x=x, orig_y=y;
          405         redraw();
          406         step = 1;
          407 #ifdef DEBUG
          408         fprintf(stderr, "box style: %d\n", st);
          409 #endif
          410         draw_box(x,y,NOFIX);
          411         while((c=fgetc(fc))!=EOF && !box_end(c, st)){
          412                 if (c == 'Z' && (st & BOX_PAR)){
          413                         st = flip_par_lean(st);
          414                         redraw();
          415 #ifdef DEBUG
          416                         fprintf(stderr, "new parallelogram style: %d\n", st);
          417 #endif
          418                         update_box(orig_x, orig_y, st, NOFIX);
          419                         continue;
          420                 }
          421                 else if (c == 'T' && (st & BOX_TRAP)){
          422                         st = toggle_trap_type(st);
          423 #ifdef DEBUG
          424                         fprintf(stderr, "new trapezium style: %d\n", st);
          425 #endif
          426                         redraw();
          427                         update_box(orig_x, orig_y, st, NOFIX);
          428                         continue;
          429                 }
          430                 if (change_style(c)){
          431                         update_box(orig_x, orig_y, st, NOFIX);
          432                         continue;
          433                 }
          434                 if (!move_around(c, fc, 1)) 
          435                         continue;
          436                 check_bound(&x, &y);
          437                 redraw();
          438                 step = 1;
          439                 update_box(orig_x, orig_y, st, NOFIX);
          440         }
          441         if (((st == BOX_RECT ) && (c == 'b' || c == '\n')) ||
          442            ( (st &  BOX_PAR  ) && (c == 'z' || c == '\n')) ||
          443            ( (st &  BOX_TRAP ) && (c == 't' || c == '\n'))){
          444                 update_box(orig_x, orig_y, st, FIX);
          445                 modified = 1;
          446         }
          447         redraw();
          448         mode = MOVE;
          449 }
          450 
          451 void draw_arrow(int xl, int yl, short *a, int a_len, int fix){
          452 
          453         int i, j, cur_dir;
          454         char line;
          455         void (*f)(int, int, char);
          456 
          457         a_miny = a_maxy = yl;
          458         if (fix == FIX)
          459                 f = set_xy;
          460         else
          461                 f = draw_xy;
          462 
          463         f(xl, yl, mark_st);
          464         if (!a_len){
          465                 show_cursor();
          466                 return;
          467         }
          468         cur_dir=DIR_N;
          469         for (i=0; i<a_len; i+=2){
          470                 if (i>0) {
          471                         /* If we are switching between horizontal and vertical, put a "corner" */
          472                         if (((cur_dir & DIR_HOR) && (a[i] & DIR_VER)) ||
          473                             ((cur_dir & DIR_VER) && (a[i] & DIR_HOR))){
          474                                 f(xl, yl, corner);
          475                                 show_cursor();
          476                         }
          477                 }
          478                 for(j=0; j<a[i+1]; j++){
          479                         line = (a[i] & DIR_L) || (a[i] & DIR_R) ? line_h : line_v;
          480                         xl += progr_x(a[i]);
          481                         yl += progr_y(a[i]);
          482                         check_bound(&xl, &yl);
          483                         if (yl < a_miny) a_miny = yl;
          484                         if (yl > a_maxy) a_maxy = yl;
          485                         f(xl, yl, line);
          486                 }
          487                 /* f(x,y,mark_end);*/
          488                 cur_dir = a[i];
          489         }
          490         if (autoend){
          491                 if (cur_dir != DIR_N)
          492                         f(xl,yl, get_mark(cur_dir));
          493         }
          494         else 
          495                 f(xl,yl,mark_end);
          496         show_cursor();
          497 }
          498 
          499 void get_arrow(FILE *fc){
          500 
          501         char c;
          502         int orig_x=x, orig_y=y, arrow_len;
          503         static short  *arrow = NULL;
          504         short *tmp = NULL;
          505         static int arrow_sz;
          506 
          507         if (!arrow){
          508                 arrow_sz = 100;
          509                 arrow = malloc(arrow_sz * sizeof(short));
          510                 if (arrow == NULL){
          511                         fprintf(stderr, "Unable to allocate arrow");
          512                         cleanup(1);
          513                 }
          514         }
          515         arrow_len = 0;
          516         dir = DIR_N;
          517 
          518         redraw();
          519         step = 1;
          520         draw_arrow(x,y, arrow, 0, NOFIX);
          521         while((c=fgetc(fc))!=EOF && c != 27 && c!= 'a' && c != '\n'){
          522                 if (change_style(c))
          523                         goto update_arrow;
          524                 if (!move_around(c, fc, 0))
          525                         continue;
          526                 check_bound(&x, &y);
          527                 /* FIXME: if we are out of bound, do nothing? */
          528                 if (arrow_len == arrow_sz){
          529                         arrow_sz *=2;
          530                         tmp = realloc(arrow, arrow_sz * sizeof(short));
          531                         if (tmp == NULL){
          532                                 fprintf(stderr, "Unable to reallocate arrow");
          533                                 cleanup(1);
          534                         }
          535                         arrow = tmp;
          536                 }
          537                 if (dir != DIR_N){
          538                         arrow[arrow_len++] = dir;
          539                         arrow[arrow_len++] = step;
          540                 }
          541                  redraw();
          542                 step = 1;
          543 update_arrow:
          544                 draw_arrow(orig_x, orig_y, arrow, arrow_len, NOFIX);
          545                 status_bar();
          546                 show_cursor();
          547         }
          548         if (c == 'a' || c == '\n'){
          549                 copy_lines_to_ring(a_miny, a_maxy, PRV_STATE);
          550                 draw_arrow(orig_x, orig_y, arrow, arrow_len, FIX);
          551                 copy_lines_to_ring(a_miny, a_maxy, NEW_STATE);
          552                 modified = 1;
          553         }
          554         redraw();
          555         mode = MOVE;
          556 }
          557 
          558 
          559 void do_erase(int x1, int y1){
          560         int i;
          561         switch(dir){
          562                 case DIR_R:
          563                         for(i=x1; i<=x; i++) set_xy(i,y,BG);
          564                         break;
          565                 case DIR_L:
          566                         for(i=x1; i>=x; i--) set_xy(i,y,BG);
          567                         break;
          568                 case DIR_U:
          569                         for(i=y1; i>=y; i--) set_xy(x,i,BG);
          570                         break;
          571                 case DIR_D:
          572                         for(i=y1; i<=y; i++) set_xy(x,i,BG);
          573                         break;
          574         }
          575 }
          576 
          577 
          578 void erase(FILE *fc){
          579         /*FIXME: add affected lines to undo */
          580         char c;
          581         int orig_x = x, orig_y = y;
          582         char first = 1, opened = 0;
          583         status_bar();
          584         show_cursor();
          585         while((c=fgetc(fc))!=EOF && c!=27 && c!= 'x' && c != '\n'){
          586                 if (!move_around(c, fc, 0)) continue;
          587                 check_bound(&x, &y);
          588                 if (first || 
          589                     (y != orig_y && ! opened) ||
          590                     (y == orig_y && x != orig_x && !opened) ){
          591                         copy_lines_to_ring(MIN(y, orig_y), MAX(y, orig_y), PRV_STATE);
          592                         first = 0;
          593                         opened = 1;
          594                 }
          595                 do_erase(orig_x, orig_y);
          596                 if (y != orig_y && opened){
          597                         copy_lines_to_ring(MIN(y, orig_y), MAX(y, orig_y), NEW_STATE);
          598                         opened = 0;
          599                 }
          600                 step = 1;
          601                 modified = 1;
          602                 orig_x = x;
          603                 orig_y = y;
          604                 redraw();
          605                 status_bar();
          606                 show_cursor();
          607         }
          608         if (opened)
          609                 copy_lines_to_ring(y, y, NEW_STATE);
          610         mode = MOVE;
          611 }
          612 
          613 
          614 
          615 
          616 
          617 /*** Visual ***/
          618 
          619 
          620 void visual_box(FILE *fc){
          621         int orig_x =x, orig_y = y;
          622         char c, f = BG;
          623 
          624         redraw();
          625         step = 1;
          626         set_video(VIDEO_REV);
          627         draw_box(x,y,NOFIX);
          628         while((c=fgetc(fc))!=EOF && c != 27 && c!= 'v' && c != '\n'){
          629                 if (!move_around(c, fc, 1)) switch(c){
          630                         case 'y': /* yank (copy) */
          631                                 yank_region(MIN(orig_x,x), MIN(orig_y,y), MAX(orig_x, x), MAX(orig_y, y));
          632                                 goto vis_exit;
          633                                 break;
          634                         case 'f':/* fill */
          635                                 f = get_key(fc, "fill char: "); /** FALLTHROUGH **/
          636                         case 'x':/* erase */
          637                                 if (c == 'x')
          638                                         yank_region(MIN(orig_x,x), MIN(orig_y,y), MAX(orig_x, x), MAX(orig_y, y));
          639                                 copy_lines_to_ring(MIN(orig_y, y), MAX(orig_y, y), PRV_STATE);
          640                                 erase_box(orig_x, orig_y, f);
          641                                 erase_blank_lines(MIN(y,orig_y), MAX(y, orig_y));
          642                                 copy_lines_to_ring(MIN(orig_y, y), MAX(orig_y, y), NEW_STATE);
          643                 
          644                                 modified = 1;
          645                                 goto vis_exit;
          646                                 break;
          647                         case 'C':/* crop-to-region */
          648                                 copy_lines_to_ring(0, HEIGHT-1, PRV_STATE);
          649                                 crop_to_rect(MIN(x, orig_x), MIN(y, orig_y), MAX(x, orig_x), MAX(y, orig_y));
          650                                 copy_lines_to_ring(0, HEIGHT-1, NEW_STATE);
          651                                 modified = 1;
          652                                 goto vis_exit;
          653                                 break;
          654                 } 
          655                 check_bound(&x, &y);
          656                 set_video(VIDEO_NRM);
          657                 redraw();
          658                 step = 1;
          659                 f = BG;
          660                 set_video(VIDEO_REV);
          661                 draw_box(orig_x, orig_y, NOFIX);
          662                 status_bar();
          663                 show_cursor();
          664         }
          665 vis_exit:
          666         set_video(VIDEO_NRM);
          667         redraw();
          668         mode = MOVE;
          669 }
          670 
          671 /*** yank/paste/undo ***/
          672 
          673 void paste(){
          674         int y2;
          675 
          676         y2 = y + cutbuf.num - 1;
          677         copy_lines_to_ring(y, y2, PRV_STATE);
          678         paste_region(x, y);
          679         copy_lines_to_ring(y, y2, NEW_STATE);
          680         redraw();
          681 }
          682 
          683 void put_lines(lineset_t *u){
          684         int i, n;
          685         
          686         for (i=0; i< u->num; i++){
          687                 n = u->l[i].n;
          688                 ensure_line_length(&(screen.l[i]), strlen(u->l[i].s));
          689                 strcpy(screen.l[n].s, u->l[i].s);
          690                 screen.l[n].lst = strlen(u->l[i].s)-1;
          691         }
          692 }
          693 
          694 
          695 void undo_change(){
          696         if (undo_cur >= 0){
          697                 if (undo_cur > undo_lst)
          698                         undo_cur = undo_lst;
          699                 put_lines(& (undo[undo_cur]));
          700                 undo_cur -= 2;
          701                 modified = 1;
          702         }
          703         redraw();
          704 }
          705 
          706 void redo_change(){
          707         if (undo_cur <= undo_lst-2){
          708                 if (undo_cur > 0)
          709                         put_lines(& (undo[undo_cur+1]));
          710                 undo_cur +=2;
          711                 put_lines(& (undo[undo_cur+1]));
          712                 modified = 1;
          713         }
          714         redraw();
          715 }
          716 
          717 
          718 /** Comments **/
          719 
          720 void get_comment(FILE *fc){
          721         char c;
          722         redraw();
          723         while((c = fgetc(fc)) != EOF && c != '\n');
          724         mode = MOVE;
          725 }
          726