Browse code

Control+Click in a printout goes in the editor window to the body of the function name under the mouse (just like control-clicking does in the editor window)

Dario Rodriguez authored on 30/09/2025 16:27:15
Showing 1 changed files
... ...
@@ -308,6 +308,7 @@ redata_t *re_getfunclisting(re_t *re);
308 308
 int re_funclistingxy2line(re_t *re,int mx,int my);
309 309
 int re_wheelaccel(re_t *re, int rawamount);
310 310
 int re_themeset(re_t *re, int ntheme);
311
+int re_gotofunctiondefinition(re_t *re, int line, int col);
311 312
 int re_socketinit(re_t *re, char *filename);
312 313
 void re_socketfree(re_t *re);
313 314
 int re_socketnewclient(re_t *re, int alreadyacceptedfd);
... ...
@@ -558,11 +559,18 @@ fprintf(stderr,"RENDER\n");
558 559
                                                         newposx=(newposx<0)?0:newposx;
559 560
                                                         newposy=my/printout->ui->fontheight;
560 561
                                                         if(redata_linecol2pos(re->data, printout->originline+newposy, printout->origincol+newposx,&tmppos,NULL)==0) {
561
-                                                                re->curline=printout->originline+newposy;
562
-                                                                re->curcol=printout->origincol+newposx;
563
-                                                                re->headerdirty=1;
564
-                                                                re->contentsdirty=1;
565
-                                                                re_fixorigin_center(re);                                                        }
562
+                                                                if((SDL_GetModState()&KMOD_CTRL)==0) {
563
+                                                                        /* go to this printout clicked-pos in the editor */
564
+                                                                        re->curline=printout->originline+newposy;
565
+                                                                        re->curcol=printout->origincol+newposx;
566
+                                                                        re->headerdirty=1;
567
+                                                                        re->contentsdirty=1;
568
+                                                                        re_fixorigin_center(re);
569
+                                                                } else {
570
+                                                                        /* control+click: search function definition (in the editor window, not in the printout) */
571
+                                                                        re_gotofunctiondefinition(re, printout->originline+newposy, printout->origincol+newposx);
572
+                                                                }
573
+                                                        }
566 574
                                                 }
567 575
                                                 break;
568 576
 
... ...
@@ -715,50 +723,12 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
715 723
                                                         redata_free(re->funclisting),re->funclisting=NULL;
716 724
                                                         re->contentsdirty=1;
717 725
                                                 } else if(event.type==SDL_MOUSEBUTTONUP && (SDL_GetModState()&KMOD_CTRL) && my>=re->y) {
718
-                                                        /* control+click: search function definition */
719 726
                                                         int newposx,newposy;
720
-                                                        long tmppos;
721 727
                                                         newposx=(mx-re->x-(re->showlinenumbers?(re->ui->fontwidth*7+re->ui->fontwidth/2):0))/re->ui->fontwidth;
722 728
                                                         newposx=(newposx<0)?0:newposx;
723 729
                                                         newposy=(my-re->y)/re->ui->fontheight;
724
-                                                        if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
725
-                                                                char searchbuf[1024]; /* magic number: max. size of string to search (truncated if bigger) */
726
-                                                                int usedsearchbuf;
727
-                                                                long curpos;
728
-                                                                redata_t *funclisting;
729
-                                                                /* extract word, generate funclisting, search word in funclisting */
730
-                                                                funclisting=NULL;
731
-                                                                if(re_extractword2buf(re, re->data, tmppos, searchbuf, sizeof(searchbuf), &usedsearchbuf)==0
732
-                                                                   && (funclisting=re_getfunclisting(re))!=NULL
733
-                                                                   && (curpos=redata_searchforward(funclisting,0,searchbuf,usedsearchbuf))!=-1) {
734
-                                                                        char linebuf[32],*cmdend;
735
-                                                                        int funcline,funccol;
736
-                                                                        if(redata_pos2linecol(funclisting,curpos,&funcline,&funccol)==0
737
-                                                                           && redata_line_getstartstrtrimmed(funclisting,funcline,linebuf,sizeof(linebuf)," ")==0) {
738
-                                                                                int oldline;
739
-                                                                                if((cmdend=strchr(linebuf,':'))!=NULL)
740
-                                                                                        *cmdend='\0';
741
-                                                                                re->command=COMMAND_GOTOLINE;
742
-                                                                                strncpy(re->commandbuf,linebuf,sizeof(re->commandbuf));
743
-                                                                                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
744
-                                                                                oldline=re->curline;
745
-                                                                                re_processcommand(re);
746
-                                                                                if(oldline!=re->curline) {
747
-                                                                                        /* position the cursor near the top of the window */
748
-                                                                                        re->originline=re->curline-3;
749
-                                                                                        re->originline=(re->originline<0)?0:re->originline;
750
-                                                                                }
751
-                                                                                /* position the cursor at the start of the line */
752
-                                                                                re->origincol=0;
753
-                                                                                re->curcol=0;
754
-                                                                                /* redraw */
755
-                                                                                re->contentsdirty=1;
756
-                                                                        }
757
-                                                                        redata_free(re->funclisting),re->funclisting=NULL;
758
-                                                                }
759
-                                                                if(funclisting!=NULL)
760
-                                                                        redata_free(funclisting),funclisting=NULL;
761
-                                                        }
730
+                                                        /* control+click: search function definition */
731
+                                                        re_gotofunctiondefinition(re, re->originline+newposy, re->origincol+newposx);
762 732
                                                 } else if(event.type==SDL_MOUSEMOTION && re->funclisting!=NULL) {
763 733
                                                         if(mx<re->ui->fontwidth*10) {
764 734
                                                                 /* scroll */
... ...
@@ -3148,6 +3118,53 @@ re_themeset(re_t *re, int ntheme)
3148 3118
         return(0);
3149 3119
 }
3150 3120
 
3121
+int
3122
+re_gotofunctiondefinition(re_t *re, int line, int col)
3123
+{
3124
+        long tmppos;
3125
+        if(re==NULL)
3126
+                return(-1);
3127
+        if(redata_linecol2pos(re->data, line, col,&tmppos,NULL)==0) {
3128
+                char searchbuf[1024]; /* magic number: max. size of string to search (truncated if bigger) */
3129
+                int usedsearchbuf;
3130
+                long curpos;
3131
+                redata_t *funclisting;
3132
+                /* extract word, generate funclisting, search word in funclisting */
3133
+                funclisting=NULL;
3134
+                if(re_extractword2buf(re, re->data, tmppos, searchbuf, sizeof(searchbuf), &usedsearchbuf)==0
3135
+                   && (funclisting=re_getfunclisting(re))!=NULL
3136
+                   && (curpos=redata_searchforward(funclisting,0,searchbuf,usedsearchbuf))!=-1) {
3137
+                        char linebuf[32],*cmdend;
3138
+                        int funcline,funccol;
3139
+                        if(redata_pos2linecol(funclisting,curpos,&funcline,&funccol)==0
3140
+                           && redata_line_getstartstrtrimmed(funclisting,funcline,linebuf,sizeof(linebuf)," ")==0) {
3141
+                                int oldline;
3142
+                                if((cmdend=strchr(linebuf,':'))!=NULL)
3143
+                                        *cmdend='\0';
3144
+                                re->command=COMMAND_GOTOLINE;
3145
+                                strncpy(re->commandbuf,linebuf,sizeof(re->commandbuf));
3146
+                                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
3147
+                                oldline=re->curline;
3148
+                                re_processcommand(re);
3149
+                                if(oldline!=re->curline) {
3150
+                                        /* position the cursor near the top of the window */
3151
+                                        re->originline=re->curline-3;
3152
+                                        re->originline=(re->originline<0)?0:re->originline;
3153
+                                }
3154
+                                /* position the cursor at the start of the line */
3155
+                                re->origincol=0;
3156
+                                re->curcol=0;
3157
+                                /* redraw */
3158
+                                re->contentsdirty=1;
3159
+                        }
3160
+                        redata_free(re->funclisting),re->funclisting=NULL;
3161
+                }
3162
+                if(funclisting!=NULL)
3163
+                        redata_free(funclisting),funclisting=NULL;
3164
+        }
3165
+        return(0);
3166
+}
3167
+
3151 3168
 int
3152 3169
 re_socketinit(re_t *re,char *filename)
3153 3170
 {
Browse code

Make Control+Shift+F1 use the manpage relevant to the current language

Dario Rodriguez authored on 24/09/2025 10:48:32
Showing 1 changed files
... ...
@@ -150,7 +150,8 @@ typedef enum typeprintout_t {
150 150
         printoutView=0,
151 151
         printoutCopy,
152 152
         printoutHelp,
153
-        printoutManpage
153
+        printoutManpage,
154
+        printoutManpageCurlang,
154 155
 } typeprintout_t;
155 156
 
156 157
 typedef struct printout_t {
... ...
@@ -540,7 +541,9 @@ fprintf(stderr,"RENDER\n");
540 541
                                         case SDL_MOUSEMOTION:
541 542
                                                 if(!(event.type==SDL_MOUSEMOTION && re->mouseselactive==0)
542 543
                                                   && printout->type!=printoutHelp
543
-                                                  && printout->type!=printoutManpage) {
544
+                                                  && printout->type!=printoutManpage
545
+                                                  && printout->type!=printoutManpageCurlang
546
+                                                ) {
544 547
                                                         int mx,my;
545 548
                                                         int newposx,newposy;
546 549
                                                         long tmppos;
... ...
@@ -1369,6 +1372,8 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1369 1372
                 re_addprint(re,printoutHelp);
1370 1373
         } else if(event->key.keysym.sym==SDLK_F1 && (SDL_GetModState()&KMOD_CTRL)!=0 && (SDL_GetModState()&(KMOD_SHIFT|KMOD_ALT))==0 ) {
1371 1374
                 re_addprint(re,printoutManpage);
1375
+        } else if(event->key.keysym.sym==SDLK_F1 && (SDL_GetModState()&KMOD_CTRL)!=0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (SDL_GetModState()&KMOD_ALT)==0) {
1376
+                re_addprint(re,printoutManpageCurlang);
1372 1377
         } else if(event->key.keysym.sym==SDLK_F2 || (event->key.keysym.sym==SDLK_s && (SDL_GetModState()&KMOD_CTRL)!=0)) {
1373 1378
                 char *errormsg=NULL;
1374 1379
                 if(redata_save(re->data,re->filename,&errormsg)!=-1)
... ...
@@ -2360,7 +2365,7 @@ Printout window\n\
2360 2365
                         redata_op_add(re->prints[i].data,0,helptext,sizeof(helptext)-1,NULL);
2361 2366
                         re->contentsdirty=1;
2362 2367
                 }
2363
-        } else if(typeprintout==printoutManpage) {
2368
+        } else if(typeprintout==printoutManpage || typeprintout==printoutManpageCurlang) {
2364 2369
                 char searchbuf[1024]; /* magic number: max. size of string to search (truncated if bigger) */
2365 2370
                 char title[256];
2366 2371
                 int lenprefix;
... ...
@@ -2368,7 +2373,11 @@ Printout window\n\
2368 2373
                 long tmppos;
2369 2374
                 int nread;
2370 2375
                 FILE *fp;
2371
-                strncpy(searchbuf,"man ",sizeof(searchbuf));
2376
+                protolang_t curlang;
2377
+                curlang=redata_prototypes_detectlang(re->data);
2378
+                strncpy(searchbuf,(typeprintout==printoutManpageCurlang && curlang==protolang_c)?"man 2 "
2379
+                                  :(typeprintout==printoutManpageCurlang && curlang==protolang_tcl)?"man 3tcl "
2380
+                                  :"man ",sizeof(searchbuf));
2372 2381
                 searchbuf[sizeof(searchbuf)-1]='\0';
2373 2382
                 lenprefix=strlen(searchbuf);
2374 2383
                 fp=NULL;
... ...
@@ -2699,6 +2708,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2699 2708
         flaglineno=(printout==NULL)?re->showlinenumbers:
2700 2709
                    (printout->type==printoutHelp)?0:
2701 2710
                    (printout->type==printoutManpage)?0:
2711
+                   (printout->type==printoutManpageCurlang)?0:
2702 2712
                    1;
2703 2713
         linenosize=linenowidth=0;
2704 2714
         if(printout==NULL && re->viewonly==1) {
... ...
@@ -2731,7 +2741,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2731 2741
         }
2732 2742
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
2733 2743
                 return(0); /* error obtaining position */
2734
-        bgcolor=(printout!=NULL && (printout->type==printoutHelp || printout->type==printoutManpage))
2744
+        bgcolor=(printout!=NULL && (printout->type==printoutHelp || printout->type==printoutManpage || printout->type==printoutManpageCurlang ))
2735 2745
                 ?COLOR_PRINTOUTSTRIPE(re)
2736 2746
                 :COLOR_BACKGROUND(re);
2737 2747
         reui_fill(ui,x0-linenowidth,y0,w,h,bgcolor);
... ...
@@ -2748,7 +2758,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2748 2758
         /* highlight current line (in printouts, highlight alternating lines) */
2749 2759
         if(printout==NULL) {
2750 2760
                 reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
2751
-        } else if(printout!=NULL && (printout->type==printoutHelp || printout->type==printoutManpage)) {
2761
+        } else if(printout!=NULL && (printout->type==printoutHelp || printout->type==printoutManpage || printout->type==printoutManpageCurlang)) {
2752 2762
                 ; /* help bgcolor already filled */
2753 2763
         } else {
2754 2764
                 for(y=y0+((printout->data==NULL)?1:(printout->originline%2))*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
Browse code

Make Control+5 go to the matching parenthesis or curly bracket

Dario Rodriguez authored on 15/07/2025 15:21:43
Showing 1 changed files
... ...
@@ -1,4 +1,4 @@
1
-	/*
1
+/*
2 2
  * recenteditor.c
3 3
  *
4 4
  * A programmers editor
... ...
@@ -1428,6 +1428,28 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1428 1428
                         re_themeset(re, 0);
1429 1429
                 if(re->quirk_duplicates)
1430 1430
                         re->ignorenkeys++;
1431
+        } else if(event->key.keysym.sym==SDLK_5 && (SDL_GetModState()&KMOD_CTRL)!=0) {
1432
+                char cursorchar[7];
1433
+                int usedcursorchar;
1434
+                long cursorpos;
1435
+                int matchingpos;
1436
+                char matchingchar;
1437
+                int mline,mcol;
1438
+                usedcursorchar=0;
1439
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)==0
1440
+                  && redata_getutf8char(re->data,cursorpos,cursorchar,sizeof(cursorchar),&usedcursorchar)==0
1441
+                  && usedcursorchar==1
1442
+                  && strchr("[]{}<>()",*cursorchar)!=NULL
1443
+                  && (matchingpos=re_getmatchingbracket(re,cursorpos,*cursorchar,&matchingchar))!=-1
1444
+                  && redata_pos2linecol(re->data,matchingpos,&mline,&mcol)!=-1
1445
+                ) {
1446
+                        re->command=COMMAND_GOTOLINE;
1447
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"%i:%i",mline+1,mcol+1);
1448
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1449
+                        re_processcommand(re);
1450
+                }
1451
+                if(re->quirk_duplicates)
1452
+                        re->ignorenkeys++;
1431 1453
         } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
1432 1454
                 long frompos,topos;
1433 1455
                 int coldone;
... ...
@@ -2293,6 +2315,7 @@ Recenteditor help\n\
2293 2315
  Home/End           - Go to the start/end of the line\n\
2294 2316
  Control+'0'        - Set default font size\n\
2295 2317
  Shift+Ctrl+'0'     - Set default color permutation\n\
2318
+ Control+'5'        - Go to the matching parenthesis or curly brace\n\
2296 2319
  Control+C          - Copy selection to clipboard. Will deselect selection.\n\
2297 2320
  Control+K+Command  - Block command, see below\n\
2298 2321
  Control+L          - Search next (requires a previous search with Control+Q+F)\n\
Browse code

Show manpage of word under cursor with Control+F1 (opens a printout)

Dario Rodriguez authored on 22/01/2024 21:46:48
Showing 1 changed files
... ...
@@ -1,4 +1,4 @@
1
-/*
1
+	/*
2 2
  * recenteditor.c
3 3
  *
4 4
  * A programmers editor
... ...
@@ -298,6 +298,7 @@ int re_clipget(re_t *re);
298 298
 int re_addprint(re_t *re, typeprintout_t typeprintout);
299 299
 int re_delprint(re_t *re, int nprint);
300 300
 int re_rtrim(re_t *re, long curpos, int *trimmed);
301
+int re_extractword2buf(re_t *re, redata_t *data, long pos, char *buf, int sizebuf, int *usedbuf);
301 302
 long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
302 303
 int re_drawheader_editing(re_t *re);
303 304
 int re_drawheader_command(re_t *re);
... ...
@@ -537,7 +538,9 @@ fprintf(stderr,"RENDER\n");
537 538
                                         case SDL_MOUSEBUTTONDOWN:
538 539
                                         case SDL_MOUSEBUTTONUP:
539 540
                                         case SDL_MOUSEMOTION:
540
-                                                if(!(event.type==SDL_MOUSEMOTION && re->mouseselactive==0)) {
541
+                                                if(!(event.type==SDL_MOUSEMOTION && re->mouseselactive==0)
542
+                                                  && printout->type!=printoutHelp
543
+                                                  && printout->type!=printoutManpage) {
541 544
                                                         int mx,my;
542 545
                                                         int newposx,newposy;
543 546
                                                         long tmppos;
... ...
@@ -718,32 +721,11 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
718 721
                                                         if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
719 722
                                                                 char searchbuf[1024]; /* magic number: max. size of string to search (truncated if bigger) */
720 723
                                                                 int usedsearchbuf;
721
-                                                                char utfchar[5];
722
-                                                                int usedutfchar;
723
-                                                                long startpos,curpos,endpos;
724
-                                                                int c;
724
+                                                                long curpos;
725 725
                                                                 redata_t *funclisting;
726
-                                                                /* search start of word */
727
-                                                                for(curpos=startpos=tmppos;redata_getprevutf8char(re->data,curpos,utfchar,sizeof(utfchar),&usedutfchar)==0;startpos=curpos) {
728
-                                                                        curpos-=usedutfchar;
729
-                                                                        if(usedutfchar==1) {
730
-                                                                                c=utfchar[0];
731
-                                                                                if(!((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'))
732
-                                                                                        break;
733
-                                                                        }
734
-                                                                }
735
-                                                                /* search end of word */
736
-                                                                for(curpos=endpos=tmppos;redata_getutf8char(re->data,curpos,utfchar,sizeof(utfchar),&usedutfchar)==0;endpos=curpos) {
737
-                                                                        curpos+=usedutfchar;
738
-                                                                        if(usedutfchar==1) {
739
-                                                                                c=utfchar[0];
740
-                                                                                if(!((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'))
741
-                                                                                        break;
742
-                                                                        }
743
-                                                                }
744 726
                                                                 /* extract word, generate funclisting, search word in funclisting */
745 727
                                                                 funclisting=NULL;
746
-                                                                if(redata_getsubstr(re->data,startpos,endpos,searchbuf,sizeof(searchbuf),&usedsearchbuf)==0
728
+                                                                if(re_extractword2buf(re, re->data, tmppos, searchbuf, sizeof(searchbuf), &usedsearchbuf)==0
747 729
                                                                    && (funclisting=re_getfunclisting(re))!=NULL
748 730
                                                                    && (curpos=redata_searchforward(funclisting,0,searchbuf,usedsearchbuf))!=-1) {
749 731
                                                                         char linebuf[32],*cmdend;
... ...
@@ -1385,6 +1367,8 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1385 1367
                 re->headerdirty=1;
1386 1368
         } else if(event->key.keysym.sym==SDLK_F1 && (SDL_GetModState()&(KMOD_CTRL|KMOD_SHIFT|KMOD_ALT))==0) {
1387 1369
                 re_addprint(re,printoutHelp);
1370
+        } else if(event->key.keysym.sym==SDLK_F1 && (SDL_GetModState()&KMOD_CTRL)!=0 && (SDL_GetModState()&(KMOD_SHIFT|KMOD_ALT))==0 ) {
1371
+                re_addprint(re,printoutManpage);
1388 1372
         } else if(event->key.keysym.sym==SDLK_F2 || (event->key.keysym.sym==SDLK_s && (SDL_GetModState()&KMOD_CTRL)!=0)) {
1389 1373
                 char *errormsg=NULL;
1390 1374
                 if(redata_save(re->data,re->filename,&errormsg)!=-1)
... ...
@@ -2255,12 +2239,11 @@ re_addprint(re_t *re, typeprintout_t typeprintout)
2255 2239
         }
2256 2240
         if(i>=re->sizeprints)
2257 2241
                 return(-1); /* INTERNAL ERROR */
2258
-        /* setup window */
2259
-        if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL)
2260
-                return(-1); /* couldn't init window */
2261 2242
         if(typeprintout==printoutHelp
2262
-          || typeprintout==printoutManpage
2263 2243
           || typeprintout==printoutCopy) {
2244
+                /* setup window */
2245
+                if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL)
2246
+                        return(-1); /* couldn't init window */
2264 2247
                 /* inmutable printout */
2265 2248
                 if((re->prints[i].data=redata_init(redata_highlighter_register,NULL))==NULL) {
2266 2249
                         reui_free(re->prints[i].ui),re->prints[i].ui=NULL;
... ...
@@ -2293,7 +2276,7 @@ Recenteditor help\n\
2293 2276
 \n\
2294 2277
  F1           - Open a printout with this help\n\
2295 2278
  Shift+F1     - (TODO) Update hints with functions definitions of all open editors\n\
2296
- Control+F1   - (TODO) Open manpage of word under the cursor in a printout\n\
2279
+ Control+F1   - Open manpage of word under the cursor in a printout\n\
2297 2280
  F2           - Save\n\
2298 2281
 \n\
2299 2282
  Cursor keys        - Move cursor\n\
... ...
@@ -2310,7 +2293,7 @@ Recenteditor help\n\
2310 2293
  Home/End           - Go to the start/end of the line\n\
2311 2294
  Control+'0'        - Set default font size\n\
2312 2295
  Shift+Ctrl+'0'     - Set default color permutation\n\
2313
- Control+C          - Copy selection to clipboard. Will deselect current selection.\n\
2296
+ Control+C          - Copy selection to clipboard. Will deselect selection.\n\
2314 2297
  Control+K+Command  - Block command, see below\n\
2315 2298
  Control+L          - Search next (requires a previous search with Control+Q+F)\n\
2316 2299
  Control+N          - Show/hide line numbers\n\
... ...
@@ -2335,7 +2318,7 @@ Editing commands (Control+Q+Command)\n\
2335 2318
 Block commands (Control+K+Command)\n\
2336 2319
 ----------------------------------\n\
2337 2320
 \n\
2338
- Control+K+Q - Close editor (exit program -- don\'t ask, it is a legacy key combo)\n\
2321
+ Control+K+Q - Close editor (exit program -- don\'t ask, legacy key combo)\n\
2339 2322
  Control+K+H - Show/hide selection\n\
2340 2323
  Control+K+B - Set start of selection to cursor position\n\
2341 2324
  Control+K+K - Set end of selection to cursor position\n\
... ...
@@ -2354,8 +2337,55 @@ Printout window\n\
2354 2337
                         redata_op_add(re->prints[i].data,0,helptext,sizeof(helptext)-1,NULL);
2355 2338
                         re->contentsdirty=1;
2356 2339
                 }
2340
+        } else if(typeprintout==printoutManpage) {
2341
+                char searchbuf[1024]; /* magic number: max. size of string to search (truncated if bigger) */
2342
+                char title[256];
2343
+                int lenprefix;
2344
+                int usedsearchbuf;
2345
+                long tmppos;
2346
+                int nread;
2347
+                FILE *fp;
2348
+                strncpy(searchbuf,"man ",sizeof(searchbuf));
2349
+                searchbuf[sizeof(searchbuf)-1]='\0';
2350
+                lenprefix=strlen(searchbuf);
2351
+                fp=NULL;
2352
+                if(redata_linecol2pos(re->data, re->curline, re->curcol,&tmppos,NULL)==0
2353
+                  && re_extractword2buf(re, re->data, tmppos, searchbuf+lenprefix, sizeof(searchbuf)-lenprefix, &usedsearchbuf)==0
2354
+                  && strncpy(title,searchbuf,sizeof(title))!=NULL
2355
+                  && (title[sizeof(title)-1]='\0')=='\0'
2356
+                  && (fp=popen(searchbuf,"r"))!=NULL
2357
+                  && (nread=fread(searchbuf,1,sizeof(searchbuf),fp))>0
2358
+                ) {
2359
+                        if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL
2360
+                          || (re->prints[i].data=redata_init(redata_highlighter_register,NULL))==NULL) {
2361
+                                if(re->prints[i].ui!=NULL)
2362
+                                        reui_free(re->prints[i].ui),re->prints[i].ui=NULL;
2363
+                                return(-1); /* couldn't init data store */
2364
+                        }
2365
+                        re->usedprints++;
2366
+                        reui_title(re->prints[i].ui,title);
2367
+                        redata_op_add(re->prints[i].data,redata_getused(re->prints[i].data),searchbuf,nread,NULL);
2368
+                        while((nread=fread(searchbuf,1,sizeof(searchbuf),fp))>0) {
2369
+                                redata_op_add(re->prints[i].data,redata_getused(re->prints[i].data),searchbuf,nread,NULL);
2370
+                        }
2371
+                        pclose(fp),fp=NULL;
2372
+                        re->contentsdirty=1;
2373
+                } else {
2374
+                        if(fp!=NULL)
2375
+                                pclose(fp),fp=NULL;
2376
+                        re_delprint(re,i);
2377
+                        re->command=COMMAND_WARNING;
2378
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"Couldn't show manpage.");
2379
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
2380
+                        re->headerdirty=1;
2381
+                        return(0);
2382
+                }
2357 2383
         } else {
2358 2384
                 char mytitle[256];
2385
+                /* setup window */
2386
+                if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL)
2387
+                        return(-1); /* couldn't init window */
2388
+                /* setup title */
2359 2389
                 snprintf(mytitle,sizeof(mytitle),"view %s",re->filename);
2360 2390
                 mytitle[sizeof(mytitle)-1]='\0';
2361 2391
                 reui_title(re->prints[i].ui,mytitle);
... ...
@@ -2408,6 +2438,39 @@ re_rtrim(re_t *re, long curpos, int *trimmed)
2408 2438
         return(0);
2409 2439
 }
2410 2440
 
2441
+int
2442
+re_extractword2buf(re_t *re, redata_t *data, long pos, char *buf, int sizebuf, int *usedbuf)
2443
+{
2444
+        char utfchar[5];
2445
+        int usedutfchar;
2446
+        long startpos,curpos,endpos;
2447
+        int c;
2448
+        if(re==NULL || data==NULL || pos<0)
2449
+                return(-1); /* sanity check failed */
2450
+        /* search start of word */
2451
+        for(curpos=startpos=pos;redata_getprevutf8char(re->data,curpos,utfchar,sizeof(utfchar),&usedutfchar)==0;startpos=curpos) {
2452
+                curpos-=usedutfchar;
2453
+                if(usedutfchar==1) {
2454
+                        c=utfchar[0];
2455
+                        if(!((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'))
2456
+                                break;
2457
+                }
2458
+        }
2459
+        /* search end of word */
2460
+        for(curpos=endpos=pos;redata_getutf8char(re->data,curpos,utfchar,sizeof(utfchar),&usedutfchar)==0;endpos=curpos) {
2461
+                curpos+=usedutfchar;
2462
+                if(usedutfchar==1) {
2463
+                        c=utfchar[0];
2464
+                        if(!((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'))
2465
+                                break;
2466
+                }
2467
+        }
2468
+        if(redata_getsubstr(re->data,startpos,endpos,buf,sizebuf-1,usedbuf)!=0)
2469
+                return(-1);
2470
+        buf[*usedbuf]='\0';
2471
+        return(0);
2472
+}
2473
+
2411 2474
 long
2412 2475
 re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar)
2413 2476
 {
... ...
@@ -2612,6 +2675,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2612 2675
         showonlyn=0;
2613 2676
         flaglineno=(printout==NULL)?re->showlinenumbers:
2614 2677
                    (printout->type==printoutHelp)?0:
2678
+                   (printout->type==printoutManpage)?0:
2615 2679
                    1;
2616 2680
         linenosize=linenowidth=0;
2617 2681
         if(printout==NULL && re->viewonly==1) {
Browse code

Make F1 open a help screen. Put title in printouts

Dario Rodriguez authored on 20/01/2024 15:17:33
Showing 1 changed files
... ...
@@ -146,9 +146,17 @@
146 146
 #define COLOR_SELNORMAL(re) re->theme.color_selnormal
147 147
 #define COLOR_CURLINE(re) re->theme.color_curline
148 148
 
149
+typedef enum typeprintout_t {
150
+        printoutView=0,
151
+        printoutCopy,
152
+        printoutHelp,
153
+        printoutManpage
154
+} typeprintout_t;
155
+
149 156
 typedef struct printout_t {
150 157
         reui_t *ui;
151 158
         redata_t *data;
159
+        typeprintout_t type;
152 160
         int originline;
153 161
         int origincol;
154 162
         int showonlyn;
... ...
@@ -287,7 +295,7 @@ int re_selectbuf_resize(re_t *re,long size);
287 295
 int re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces);
288 296
 int re_selectbuf_replace(re_t *re,char *newdata);
289 297
 int re_clipget(re_t *re);
290
-int re_addprint(re_t *re);
298
+int re_addprint(re_t *re, typeprintout_t typeprintout);
291 299
 int re_delprint(re_t *re, int nprint);
292 300
 int re_rtrim(re_t *re, long curpos, int *trimmed);
293 301
 long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
... ...
@@ -1375,6 +1383,8 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1375 1383
                 re->command="";
1376 1384
                 re->command_first_key='q';
1377 1385
                 re->headerdirty=1;
1386
+        } else if(event->key.keysym.sym==SDLK_F1 && (SDL_GetModState()&(KMOD_CTRL|KMOD_SHIFT|KMOD_ALT))==0) {
1387
+                re_addprint(re,printoutHelp);
1378 1388
         } else if(event->key.keysym.sym==SDLK_F2 || (event->key.keysym.sym==SDLK_s && (SDL_GetModState()&KMOD_CTRL)!=0)) {
1379 1389
                 char *errormsg=NULL;
1380 1390
                 if(redata_save(re->data,re->filename,&errormsg)!=-1)
... ...
@@ -1482,7 +1492,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1482 1492
                 if(re->quirk_duplicates)
1483 1493
                         re->ignorenkeys++;
1484 1494
         } else if(/*re->selactive &&*/ event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
1485
-                re_addprint(re);
1495
+                re_addprint(re,printoutView);
1486 1496
         } else if(event->key.keysym.sym==SDLK_n && (SDL_GetModState()&KMOD_CTRL)!=0) {
1487 1497
                 re->showlinenumbers=1-re->showlinenumbers;
1488 1498
                 re_setuidata(re);
... ...
@@ -2225,7 +2235,7 @@ re_clipget(re_t *re)
2225 2235
 
2226 2236
 
2227 2237
 int
2228
-re_addprint(re_t *re)
2238
+re_addprint(re_t *re, typeprintout_t typeprintout)
2229 2239
 {
2230 2240
         int i;
2231 2241
         if(re==NULL)
... ...
@@ -2248,39 +2258,115 @@ re_addprint(re_t *re)
2248 2258
         /* setup window */
2249 2259
         if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL)
2250 2260
                 return(-1); /* couldn't init window */
2251
-#if 0
2252
-/* option A: printouts are immutable */
2253
-        if((re->prints[i].data=redata_init(redata_highlighter_register,NULL))==NULL) {
2254
-                reui_free(re->prints[i].ui),re->prints[i].ui=NULL;
2255
-                return(-1); /* couldn't init data store */
2256
-        }
2257
-        re->usedprints++;
2258
-        /* copy contents (and set clipboard contents and unselect)*/
2259
-        if(re->selactive) {
2260
-                long frompos,topos;
2261
-                int coldone;
2262
-                if(redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
2263
-                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
2264
-                        re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
2265
-                        redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
2266
-                        SDL_SetClipboardText(re->selectbuf);
2267
-                        re_sel_toggle(re);
2261
+        if(typeprintout==printoutHelp
2262
+          || typeprintout==printoutManpage
2263
+          || typeprintout==printoutCopy) {
2264
+                /* inmutable printout */
2265
+                if((re->prints[i].data=redata_init(redata_highlighter_register,NULL))==NULL) {
2266
+                        reui_free(re->prints[i].ui),re->prints[i].ui=NULL;
2267
+                        return(-1); /* couldn't init data store */
2268
+                }
2269
+                re->usedprints++;
2270
+                if(typeprintout==printoutCopy) {
2271
+                        /* copy contents (and set clipboard contents and unselect)*/
2272
+                        if(re->selactive) {
2273
+                                long frompos,topos;
2274
+                                int coldone;
2275
+                                if(redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
2276
+                                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
2277
+                                        re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
2278
+                                        redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
2279
+                                        SDL_SetClipboardText(re->selectbuf);
2280
+                                        re_sel_toggle(re);
2281
+                                        re->contentsdirty=1;
2282
+                                }
2283
+                        } else {
2284
+                                re_selectbuf_fill(re,0,redata_getused(re->data),0);
2285
+                                redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
2286
+                                SDL_SetClipboardText(re->selectbuf);
2287
+                                re->contentsdirty=1;
2288
+                        }
2289
+                } else if(typeprintout==printoutHelp) {
2290
+                        static char helptext[]={"\
2291
+Recenteditor help\n\
2292
+=================\n\
2293
+\n\
2294
+ F1           - Open a printout with this help\n\
2295
+ Shift+F1     - (TODO) Update hints with functions definitions of all open editors\n\
2296
+ Control+F1   - (TODO) Open manpage of word under the cursor in a printout\n\
2297
+ F2           - Save\n\
2298
+\n\
2299
+ Cursor keys        - Move cursor\n\
2300
+ PageUp/PageDn      - Scroll one page up/down\n\
2301
+ Shift+Cursor       - Select\n\
2302
+ Mousewheel         - Scroll\n\
2303
+ Mouse click        - Change cursor position\n\
2304
+                      Click and hold on status bar to open function list\n\
2305
+ Control+Click      - Search function body of function name under the mouse\n\
2306
+ Tab key            - Insert 8 spaces\n\
2307
+ Control+Tab key    - Insert TAB character\n\
2308
+ Alt+Left/Right     - Change indentation of selection\n\
2309
+ Control+PgUp/PgDn  - Go to the beginning/end of the document\n\
2310
+ Home/End           - Go to the start/end of the line\n\
2311
+ Control+'0'        - Set default font size\n\
2312
+ Shift+Ctrl+'0'     - Set default color permutation\n\
2313
+ Control+C          - Copy selection to clipboard. Will deselect current selection.\n\
2314
+ Control+K+Command  - Block command, see below\n\
2315
+ Control+L          - Search next (requires a previous search with Control+Q+F)\n\
2316
+ Control+N          - Show/hide line numbers\n\
2317
+ Control+P          - Open printout window with current file or selection\n\
2318
+ Control+Q+Command  - Editing command, see below\n\
2319
+ Control+S          - Save\n\
2320
+ Control+X          - Cut selection into clipboard\n\
2321
+ Control+V          - Paste clipboard into current cursor position\n\
2322
+ Control+Z          - Undo\n\
2323
+ Control+'+'/'-'    - Iterates between font sizes\n\
2324
+ Shift+Ctrl+'+'/'-' - Iterates between color permutations\n\
2325
+\n\
2326
+\n\
2327
+Editing commands (Control+Q+Command)\n\
2328
+------------------------------------\n\
2329
+\n\
2330
+ Control+Q+L - Go to line number\n\
2331
+ Control+Q+F - Find\n\
2332
+ Control+Q+A - Search and replace\n\
2333
+\n\
2334
+\n\
2335
+Block commands (Control+K+Command)\n\
2336
+----------------------------------\n\
2337
+\n\
2338
+ Control+K+Q - Close editor (exit program -- don\'t ask, it is a legacy key combo)\n\
2339
+ Control+K+H - Show/hide selection\n\
2340
+ Control+K+B - Set start of selection to cursor position\n\
2341
+ Control+K+K - Set end of selection to cursor position\n\
2342
+ Control+K+Y - Delete selection\n\
2343
+ Control+K+C - Copy selection to current cursor position (doesn\'t use clipboard)\n\
2344
+ Control+K+V - Move selection to current cursor position (doesn\'t use clipboard)\n\
2345
+\n\
2346
+\n\
2347
+Printout window\n\
2348
+---------------\n\
2349
+\n\
2350
+ Cursor/PageUp/PageDown - Scroll printout\n\
2351
+ Mousewheel             - Scroll printout\n\
2352
+"};
2353
+                        reui_title(re->prints[i].ui,"help");
2354
+                        redata_op_add(re->prints[i].data,0,helptext,sizeof(helptext)-1,NULL);
2268 2355
                         re->contentsdirty=1;
2269 2356
                 }
2270 2357
         } else {
2271
-                re_selectbuf_fill(re,0,redata_getused(re->data),0);
2272
-                redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
2273
-                SDL_SetClipboardText(re->selectbuf);
2274
-                re->contentsdirty=1;
2275
-        }
2276
-#else
2277
-/* option B: printouts are a window into a fixed place of the file */
2278
-        re->prints[i].data=NULL;
2279
-        re->prints[i].originline=(re->selactive)?re->sellinefrom:0;
2280
-        re->prints[i].origincol=0;
2281
-        re->prints[i].showonlyn=0 /* (re->selactive)?re->sellineto-re->sellinefrom+1:0 */ ;
2282
-        re->usedprints++;
2283
-#endif
2358
+                char mytitle[256];
2359
+                snprintf(mytitle,sizeof(mytitle),"view %s",re->filename);
2360
+                mytitle[sizeof(mytitle)-1]='\0';
2361
+                reui_title(re->prints[i].ui,mytitle);
2362
+                /* printout is a window into a fixed place of the file */
2363
+                re->prints[i].data=NULL;
2364
+                re->prints[i].originline=(re->selactive)?re->sellinefrom:0;
2365
+                re->prints[i].origincol=0;
2366
+                re->prints[i].showonlyn=0 /* (re->selactive)?re->sellineto-re->sellinefrom+1:0 */ ;
2367
+                re->usedprints++;
2368
+        }
2369
+        re->prints[i].type=typeprintout;
2284 2370
         re->prints[i].dirty=1;
2285 2371
         return(0);
2286 2372
 }
... ...
@@ -2485,6 +2571,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2485 2571
 {
2486 2572
         reui_t *ui;
2487 2573
         redata_t *data;
2574
+        char *bgcolor;
2488 2575
         int x0,y0,w,h;
2489 2576
         int originline,origincol;
2490 2577
         int curline,curcol;
... ...
@@ -2523,7 +2610,9 @@ re_drawcontents(re_t *re, printout_t *printout)
2523 2610
         maxcol=re->maxcol;
2524 2611
         maxrow=re->maxrow;
2525 2612
         showonlyn=0;
2526
-        flaglineno=(printout==NULL)?re->showlinenumbers:0;
2613
+        flaglineno=(printout==NULL)?re->showlinenumbers:
2614
+                   (printout->type==printoutHelp)?0:
2615
+                   1;
2527 2616
         linenosize=linenowidth=0;
2528 2617
         if(printout==NULL && re->viewonly==1) {
2529 2618
                 memset(&fakeprintout,0,sizeof(printout_t));
... ...
@@ -2544,7 +2633,6 @@ re_drawcontents(re_t *re, printout_t *printout)
2544 2633
                 maxcol=w/ui->fontwidth-1;
2545 2634
                 maxrow=h/ui->fontheight-1;
2546 2635
                 showonlyn=printout->showonlyn;
2547
-                flaglineno=1;
2548 2636
         }
2549 2637
         if(flaglineno) {
2550 2638
                 linenosize=6;
... ...
@@ -2556,7 +2644,10 @@ re_drawcontents(re_t *re, printout_t *printout)
2556 2644
         }
2557 2645
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
2558 2646
                 return(0); /* error obtaining position */
2559
-        reui_fill(ui,x0-linenowidth,y0,w,h,COLOR_BACKGROUND(re));
2647
+        bgcolor=(printout!=NULL && (printout->type==printoutHelp || printout->type==printoutManpage))
2648
+                ?COLOR_PRINTOUTSTRIPE(re)
2649
+                :COLOR_BACKGROUND(re);
2650
+        reui_fill(ui,x0-linenowidth,y0,w,h,bgcolor);
2560 2651
         row=curline-originline;
2561 2652
         pos=cursorpos;
2562 2653
         /* get position/row/col of character at top left of screen */
... ...
@@ -2570,6 +2661,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2570 2661
         /* highlight current line (in printouts, highlight alternating lines) */
2571 2662
         if(printout==NULL) {
2572 2663
                 reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
2664
+        } else if(printout!=NULL && (printout->type==printoutHelp || printout->type==printoutManpage)) {
2665
+                ; /* help bgcolor already filled */
2573 2666
         } else {
2574 2667
                 for(y=y0+((printout->data==NULL)?1:(printout->originline%2))*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
2575 2668
                         reui_fill(ui,x0-linenowidth,y,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
Browse code

Implement unix domain socket command 'quit'.

Dario Rodriguez authored on 02/01/2024 21:06:23
Showing 1 changed files
... ...
@@ -3353,6 +3353,13 @@ fprintf(stderr,"Changing selected id because of command from client \"%s\" (%i).
3353 3353
                 re_socketout(re, nclient, "\n");
3354 3354
         } else if(line[0]=='\0' ) {
3355 3355
                 ; /* ignore the end-of-message (should only receive them on forwarding clients) */
3356
+        } else if(strcmp(line,"quit")==0) {
3357
+                /* close socket */
3358
+#if 0
3359
+fprintf(stderr,"Closing socket because of command from client \"%s\" (%i).\n",line,nclient);
3360
+#endif
3361
+                close(re->comms.clients[nclient]->fd),re->comms.clients[nclient]->fd=-1;
3362
+                return(0);
3356 3363
         } else {
3357 3364
 #if 1
3358 3365
 fprintf(stderr,"Ignoring unknown command from client \"%s\" (%i).\n",line,nclient);
Browse code

Implement unix domain socket command 'select'.

Dario Rodriguez authored on 02/01/2024 19:50:58
Showing 1 changed files
... ...
@@ -198,6 +198,7 @@ typedef struct commclient_t {
198 198
 typedef struct comms_t {
199 199
         int serverfd;
200 200
         char id[MAXFILENAMESIZE];
201
+        char selectedid[MAXFILENAMESIZE];
201 202
         char socketfilename[SOCKETFILENAMESIZE];
202 203
         int sizeclients;
203 204
         int usedclients;
... ...
@@ -3278,15 +3279,17 @@ fprintf(stderr,"Received from client \"%s\" (%i).\n",line,nclient);
3278 3279
 #if 0
3279 3280
 fprintf(stderr,"Changing line because of command from client \"%s\" (%i).\n",line,nclient);
3280 3281
 #endif
3281
-                re->command=COMMAND_GOTOLINE;
3282
-                strncpy(re->commandbuf,ptr,sizeof(re->commandbuf));
3283
-                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
3284
-                oldline=re->curline;
3285
-                re_processcommand(re);
3286
-                if(oldline!=re->curline) {
3287
-                        /* position the cursor near the top of the window */
3288
-                        re->originline=re->curline-3;
3289
-                        re->originline=(re->originline<0)?0:re->originline;
3282
+                if(re->comms.selectedid[0]=='\0' || strcmp(re->comms.id,re->comms.selectedid)==0) {
3283
+                        re->command=COMMAND_GOTOLINE;
3284
+                        strncpy(re->commandbuf,ptr,sizeof(re->commandbuf));
3285
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
3286
+                        oldline=re->curline;
3287
+                        re_processcommand(re);
3288
+                        if(oldline!=re->curline) {
3289
+                                /* position the cursor near the top of the window */
3290
+                                re->originline=re->curline-3;
3291
+                                re->originline=(re->originline<0)?0:re->originline;
3292
+                        }
3290 3293
                 }
3291 3294
                 /* send end-of-results */
3292 3295
                 re_socketout(re, nclient, "\n");
... ...
@@ -3298,12 +3301,14 @@ fprintf(stderr,"Changing line because of command from client \"%s\" (%i).\n",lin
3298 3301
 #endif
3299 3302
                         if(re->comms.clients[i]==NULL || re->comms.clients[i]->fd==-1 || re->comms.clients[i]->remoteid[0]=='\0')
3300 3303
                                 continue;
3301
-                        avail=re->comms.clients[i]->sizebufout-re->comms.clients[i]->usedbufout;
3302
-                        if((strlen(line)+1)>avail) {
3303
-                                fprintf(stderr,"Couldn't forward command to client because the output buffer is full (avail:%li, req:%li)\n",(long)avail,(long)(strlen(line)+1));
3304
-                                continue;
3304
+                        if(re->comms.selectedid[0]=='\0' || strcmp(re->comms.clients[i]->remoteid,re->comms.selectedid)==0) {
3305
+                                avail=re->comms.clients[i]->sizebufout-re->comms.clients[i]->usedbufout;
3306
+                                if((strlen(line)+1)>avail) {
3307
+                                        fprintf(stderr,"Couldn't forward command to client because the output buffer is full (avail:%li, req:%li)\n",(long)avail,(long)(strlen(line)+1));
3308
+                                        continue;
3309
+                                }
3310
+                                re_socketout(re, i, "%s\n",line);
3305 3311
                         }
3306
-                        re_socketout(re, i, "%s\n",line);
3307 3312
                 }
3308 3313
         } else if(memcmp(line,"id ",3)==0) {
3309 3314
                 ptr=line+3;
... ...
@@ -3328,6 +3333,24 @@ fprintf(stderr,"Listing ids because of command from client \"%s\" (%i).\n",line,
3328 3333
                 }
3329 3334
                 /* send end-of-results */
3330 3335
                 re_socketout(re, nclient, "\n");
3336
+        } else if(strcmp(line,"select")==0) {
3337
+                /* reset select id */
3338
+#if 0
3339
+fprintf(stderr,"Resetting selected id because of command from client \"%s\" (%i).\n",line,nclient);
3340
+#endif
3341
+                re->comms.selectedid[0]='\0';
3342
+                /* send end-of-results */
3343
+                re_socketout(re, nclient, "\n");
3344
+        } else if(memcmp(line,"select ",7)==0) {
3345
+                ptr=line+7;
3346
+                /* select id */
3347
+#if 0
3348
+fprintf(stderr,"Changing selected id because of command from client \"%s\" (%i).\n",line,nclient);
3349
+#endif
3350
+                strncpy(re->comms.selectedid,ptr,sizeof(re->comms.selectedid));
3351
+                re->comms.selectedid[sizeof(re->comms.selectedid)-1]='\0';
3352
+                /* send end-of-results */
3353
+                re_socketout(re, nclient, "\n");
3331 3354
         } else if(line[0]=='\0' ) {
3332 3355
                 ; /* ignore the end-of-message (should only receive them on forwarding clients) */
3333 3356
         } else {
Browse code

Implement unix domain socket command 'list'.

Dario Rodriguez authored on 02/01/2024 19:41:47
Showing 1 changed files
... ...
@@ -3315,6 +3315,19 @@ fprintf(stderr,"Storing client id because of command from client \"%s\" (%i).\n"
3315 3315
                 client->remoteid[sizeof(client->remoteid)-1]='\0';
3316 3316
                 /* send end-of-results */
3317 3317
                 re_socketout(re, nclient, "\n");
3318
+        } else if(strcmp(line,"list")==0) {
3319
+                /* list ids */
3320
+#if 0
3321
+fprintf(stderr,"Listing ids because of command from client \"%s\" (%i).\n",line,nclient);
3322
+#endif
3323
+                re_socketout(re, nclient, "%s\n",re->comms.id);
3324
+                for(i=0;i<re->comms.sizeclients;i++) {
3325
+                        if(re->comms.clients[i]==NULL || re->comms.clients[i]->fd==-1 || re->comms.clients[i]->remoteid[0]=='\0')
3326
+                                continue;
3327
+                        re_socketout(re, nclient, "%s\n",re->comms.clients[i]->remoteid);
3328
+                }
3329
+                /* send end-of-results */
3330
+                re_socketout(re, nclient, "\n");
3318 3331
         } else if(line[0]=='\0' ) {
3319 3332
                 ; /* ignore the end-of-message (should only receive them on forwarding clients) */
3320 3333
         } else {
Browse code

Implement unix domain socket command 'id'. Implement unix domain socket data forwarding when there are several recenteditors editing the same filename and make clients try to start a server when the server closes the connection.

Dario Rodriguez authored on 02/01/2024 19:31:21
Showing 1 changed files
... ...
@@ -23,6 +23,7 @@
23 23
 #include <sys/select.h>
24 24
 #include <stdarg.h>
25 25
 #include <sys/stat.h>
26
+#include <limits.h>
26 27
 
27 28
 #include "re_data.h"
28 29
 #include "re_plugin_unsaved.h"
... ...
@@ -43,6 +44,7 @@
43 44
 #define COMMBUFSIZE 16384
44 45
 #define COMMCLIENTSBLOCKSIZE 32
45 46
 #define SOCKETFILENAMESIZE 1024
47
+#define MAXFILENAMESIZE PATH_MAX+1
46 48
 #define LISTENBACKLOG 5
47 49
 
48 50
 #define VIEWONLYPROGNAME "review"
... ...
@@ -181,6 +183,8 @@ typedef struct theme_t {
181 183
 
182 184
 typedef struct commclient_t {
183 185
         int fd;
186
+        int flag_connectedtoserver;
187
+        char remoteid[MAXFILENAMESIZE];
184 188
         int sizebufin;
185 189
         int usedbufin;
186 190
         int gotbufin;
... ...
@@ -193,6 +197,7 @@ typedef struct commclient_t {
193 197
 
194 198
 typedef struct comms_t {
195 199
         int serverfd;
200
+        char id[MAXFILENAMESIZE];
196 201
         char socketfilename[SOCKETFILENAMESIZE];
197 202
         int sizeclients;
198 203
         int usedclients;
... ...
@@ -294,7 +299,7 @@ int re_wheelaccel(re_t *re, int rawamount);
294 299
 int re_themeset(re_t *re, int ntheme);
295 300
 int re_socketinit(re_t *re, char *filename);
296 301
 void re_socketfree(re_t *re);
297
-int re_socketnewclient(re_t *re);
302
+int re_socketnewclient(re_t *re, int alreadyacceptedfd);
298 303
 int re_socketstep(re_t *re);
299 304
 int re_socketin(re_t *re, int nclient, char *line);
300 305
 #ifndef __GNUC__
... ...
@@ -2982,6 +2987,13 @@ re_socketinit(re_t *re,char *filename)
2982 2987
                 }
2983 2988
                 re->comms.usedclients=0;
2984 2989
         }
2990
+        /* fill the id */
2991
+        if(realpath(filename,re->comms.id)==NULL) {
2992
+                /* if the path cannot be resolved, copy the filename */
2993
+                strncpy(re->comms.id,filename,sizeof(re->comms.id));
2994
+                re->comms.id[sizeof(re->comms.id)-1]='\0';
2995
+        }
2996
+        re->comms.id[sizeof(re->comms.id)-1]='\0';
2985 2997
         /* prepare the new filepath for the socket */
2986 2998
         if((passwd=getpwuid(getuid()))==NULL || (username=passwd->pw_name)==NULL) {
2987 2999
                 fprintf(stderr,"WARNING: Couldn't get username\n");
... ...
@@ -3000,16 +3012,39 @@ re_socketinit(re_t *re,char *filename)
3000 3012
                 return(-1);
3001 3013
         }
3002 3014
         /* detect if there is a stale socket */
3003
-        if((oldfd=open(comms->socketfilename, O_WRONLY|O_APPEND))!=-1) {
3015
+        if((errstr="create")==NULL
3016
+          || (oldfd=socket(AF_UNIX,SOCK_STREAM,0))==-1
3017
+          || (errstr="assing")==NULL /* this one never fails, just for completion */
3018
+          || (memset(&addr,0,sizeof(struct sockaddr_un)))==NULL
3019
+          || (addr.sun_family=AF_UNIX)!=AF_UNIX
3020
+          || strncpy(addr.sun_path,comms->socketfilename,sizeof(addr.sun_path))==NULL
3021
+          || (errstr="connect")==NULL
3022
+          || connect(oldfd,(struct sockaddr *)&addr,sizeof(addr))==-1
3023
+        ) {
3024
+#if 0
3025
+fprintf(stderr,"Check for other server result: %s fail.\n",errstr);
3026
+#endif
3027
+                close(oldfd),oldfd=-1; /* OK: the re is no server as couldn't connect */
3028
+        } else {
3004 3029
                 fd_set writeset;
3005 3030
                 struct timeval tv;
3006 3031
                 FD_ZERO(&writeset);
3007 3032
                 FD_SET(oldfd,&writeset);
3008 3033
                 tv.tv_sec=tv.tv_usec=0;
3009 3034
                 if(select(oldfd+1,NULL,&writeset,NULL,&tv)>0) {
3035
+                        int nclient;
3010 3036
                         comms->socketfilename[0]='\0';
3011
-                        fprintf(stderr,"WARNING: There is a process using the communication socket for the file\n");
3012
-#warning TODO: if the unix domain socket is in use, connect to it and warn that I''m also able to service that filename, so (1) it forwards the petitions, and (2) be waware of when the other process quits to retake control of the unix domain socket
3037
+                        nclient=re_socketnewclient(re,oldfd),oldfd=-1;
3038
+                        if(nclient!=-1) {
3039
+                                re_socketout(re,nclient,"id %s\n",comms->id);
3040
+                                comms->clients[nclient]->flag_connectedtoserver=1;
3041
+#if 0
3042
+fprintf(stderr,"nclient:%i id:\"%s\".\n",nclient,comms->id);
3043
+fprintf(stderr,"Connected to server.\n");
3044
+#endif
3045
+                                return(0);
3046
+                        }
3047
+                        fprintf(stderr,"WARNING: There is a process using the communication socket for the file and couldn't connect to it.\n");
3013 3048
                         return(-1);
3014 3049
                 }
3015 3050
                 close(oldfd),oldfd=-1;
... ...
@@ -3033,7 +3068,7 @@ re_socketinit(re_t *re,char *filename)
3033 3068
                 fprintf(stderr,"WARNING: Couldn't %s unix domain socket\n",errstr);
3034 3069
                 return(-1);
3035 3070
         }
3036
-#if 1
3071
+#if 0
3037 3072
 fprintf(stderr,"Server registered.\n");
3038 3073
 #endif
3039 3074
         return(0);
... ...
@@ -3066,7 +3101,7 @@ re_socketfree(re_t *re)
3066 3101
 }
3067 3102
 
3068 3103
 int
3069
-re_socketnewclient(re_t *re)
3104
+re_socketnewclient(re_t *re, int alreadyacceptedfd)
3070 3105
 {
3071 3106
         int i;
3072 3107
         int fd;
... ...
@@ -3076,7 +3111,10 @@ re_socketnewclient(re_t *re)
3076 3111
         addrlen=sizeof(addr);
3077 3112
         if(re==NULL)
3078 3113
                 return(-1); /* sanity check failed */
3079
-        fd=accept(re->comms.serverfd,&addr,&addrlen);
3114
+        if(alreadyacceptedfd==-1)
3115
+                fd=accept(re->comms.serverfd,&addr,&addrlen);
3116
+        else
3117
+                fd=alreadyacceptedfd;
3080 3118
         if(re->comms.usedclients==re->comms.sizeclients) {
3081 3119
                 commclient_t **newclients;
3082 3120
                 if((newclients=realloc(re->comms.clients,sizeof(commclient_t *)*(re->comms.sizeclients+COMMCLIENTSBLOCKSIZE)))==NULL) {
... ...
@@ -3112,8 +3150,7 @@ re_socketnewclient(re_t *re)
3112 3150
         client->usedbufin=client->gotbufin=0;
3113 3151
         client->usedbufout=client->gotbufout=0;
3114 3152
         re->comms.usedclients++;
3115
-        re_socketout(re, i, "OK\n");
3116
-#if 1
3153
+#if 0
3117 3154
 fprintf(stderr,"New client registered (%i).\n",i);
3118 3155
 #endif
3119 3156
         return(i);
... ...
@@ -3130,13 +3167,16 @@ int re_socketstep(re_t *re)
3130 3167
         int avail,queued;
3131 3168
         int nread,nwritten;
3132 3169
         char *ptr,*next,*end;
3133
-        if(re==NULL || re->comms.serverfd==-1)
3170
+        if(re==NULL)
3134 3171
                 return(-1); /* sanity check error */
3135 3172
         comms=&(re->comms);
3136 3173
         FD_ZERO(&readset);
3137 3174
         FD_ZERO(&writeset);
3138
-        maxfd=comms->serverfd;
3139
-        FD_SET(comms->serverfd,&readset);
3175
+        maxfd=0;
3176
+        if(comms->serverfd!=-1) {
3177
+                maxfd=comms->serverfd;
3178
+                FD_SET(comms->serverfd,&readset);
3179
+        }
3140 3180
         for(i=0;i<comms->sizeclients;i++) {
3141 3181
                 if((client=comms->clients[i])==NULL || client->fd==-1)
3142 3182
                         continue;
... ...
@@ -3158,8 +3198,8 @@ int re_socketstep(re_t *re)
3158 3198
         if(select(maxfd+1,&readset,&writeset,NULL,&tv)<=0)
3159 3199
                 return(0); /* nothing to do */
3160 3200
         /* server */
3161
-        if(FD_ISSET(comms->serverfd,&readset))
3162
-                re_socketnewclient(re);
3201
+        if(comms->serverfd!=-1 && FD_ISSET(comms->serverfd,&readset))
3202
+                re_socketnewclient(re,-1);
3163 3203
         /* clients */
3164 3204
         for(i=0;i<comms->sizeclients;i++) {
3165 3205
                 if((client=comms->clients[i])==NULL || client->fd==-1)
... ...
@@ -3167,16 +3207,20 @@ int re_socketstep(re_t *re)
3167 3207
                 if(FD_ISSET(client->fd,&readset)) {
3168 3208
                         if((queued=sock_queued(client->fd))<=0) {
3169 3209
                                 /* remote has closed the connection */
3170
-#if 1
3210
+#if 0
3171 3211
 fprintf(stderr,"Unregistering client, remote has closed the connection (%i).\n",i);
3172 3212
 #endif
3173 3213
                                 close(client->fd),client->fd=-1;
3214
+                                if(client->flag_connectedtoserver) {
3215
+                                        client->flag_connectedtoserver=0;
3216
+                                        re_socketinit(re,re->filename);
3217
+                                }
3174 3218
                                 continue;
3175 3219
                         }
3176 3220
                         avail=(client->sizebufin-client->usedbufin);
3177 3221
                         queued=(queued>avail)?avail:queued;
3178 3222
                         if((nread=read(client->fd,client->bufin+client->usedbufin,queued))>0) {
3179
-#if 1
3223
+#if 0
3180 3224
 fprintf(stderr,"Read from client %li bytes (%i).\n",(long)nread,i);
3181 3225
 #endif
3182 3226
                                 client->usedbufin+=nread;
... ...
@@ -3203,7 +3247,7 @@ fprintf(stderr,"Read from client %li bytes (%i).\n",(long)nread,i);
3203 3247
                         queued=client->usedbufout-client->gotbufout;
3204 3248
                         if((nwritten=write(client->fd,client->bufout+client->gotbufout,client->usedbufout-client->gotbufout))>0)
3205 3249
                                 client->gotbufout+=nwritten;
3206
-#if 1
3250
+#if 0
3207 3251
 fprintf(stderr,"Write to client %li bytes (%i).\n",(long)nwritten,i);
3208 3252
 #endif
3209 3253
                 }
... ...
@@ -3217,14 +3261,23 @@ re_socketin(re_t *re, int nclient, char *line)
3217 3261
         /* note that the '\n' delimiter has been already removed */
3218 3262
         /* Commands can be sent from the command line using socat as in: */
3219 3263
         /* "socat - UNIX-CONNECT:/tmp/.re_${USER}/filename.ext" */
3264
+        commclient_t *client;
3220 3265
         char *ptr;
3221
-#if 1
3266
+        int i;
3267
+        if(re==NULL || nclient<0 || nclient>=re->comms.sizeclients || re->comms.clients[nclient]==NULL || line==NULL)
3268
+                return(-1); /* sanity check failed */
3269
+        client=re->comms.clients[nclient];
3270
+#if 0
3222 3271
 fprintf(stderr,"Received from client \"%s\" (%i).\n",line,nclient);
3223 3272
 #endif
3224 3273
         if(memcmp(line,"goto ",5)==0) {
3225 3274
                 int oldline;
3275
+                int avail;
3226 3276
                 ptr=line+5;
3227 3277
                 /* change line */
3278
+#if 0
3279
+fprintf(stderr,"Changing line because of command from client \"%s\" (%i).\n",line,nclient);
3280
+#endif
3228 3281
                 re->command=COMMAND_GOTOLINE;
3229 3282
                 strncpy(re->commandbuf,ptr,sizeof(re->commandbuf));
3230 3283
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
... ...
@@ -3237,6 +3290,33 @@ fprintf(stderr,"Received from client \"%s\" (%i).\n",line,nclient);
3237 3290
                 }
3238 3291
                 /* send end-of-results */
3239 3292
                 re_socketout(re, nclient, "\n");
3293
+                /* forward command to all identified clients except the one who sent teh command */
3294
+                for(i=0;i<re->comms.sizeclients;i++) {
3295
+#if 0
3296
+                        if(re->comms.clients[i]!=NULL)
3297
+                                fprintf(stderr,"Client[%i] id:\"%s\"\n",i,re->comms.clients[i]->remoteid);
3298
+#endif
3299
+                        if(re->comms.clients[i]==NULL || re->comms.clients[i]->fd==-1 || re->comms.clients[i]->remoteid[0]=='\0')
3300
+                                continue;
3301
+                        avail=re->comms.clients[i]->sizebufout-re->comms.clients[i]->usedbufout;
3302
+                        if((strlen(line)+1)>avail) {
3303
+                                fprintf(stderr,"Couldn't forward command to client because the output buffer is full (avail:%li, req:%li)\n",(long)avail,(long)(strlen(line)+1));
3304
+                                continue;
3305
+                        }
3306
+                        re_socketout(re, i, "%s\n",line);
3307
+                }
3308
+        } else if(memcmp(line,"id ",3)==0) {
3309
+                ptr=line+3;
3310
+                /* change id */
3311
+#if 0
3312
+fprintf(stderr,"Storing client id because of command from client \"%s\" (%i).\n",line,nclient);
3313
+#endif
3314
+                strncpy(client->remoteid,ptr,sizeof(client->remoteid));
3315
+                client->remoteid[sizeof(client->remoteid)-1]='\0';
3316
+                /* send end-of-results */
3317
+                re_socketout(re, nclient, "\n");
3318
+        } else if(line[0]=='\0' ) {
3319
+                ; /* ignore the end-of-message (should only receive them on forwarding clients) */
3240 3320
         } else {
3241 3321
 #if 1
3242 3322
 fprintf(stderr,"Ignoring unknown command from client \"%s\" (%i).\n",line,nclient);
Browse code

Implement unix domain socket command 'goto' to change current line:col

Dario Rodriguez authored on 02/01/2024 17:16:08
Showing 1 changed files
... ...
@@ -3009,6 +3009,7 @@ re_socketinit(re_t *re,char *filename)
3009 3009
                 if(select(oldfd+1,NULL,&writeset,NULL,&tv)>0) {
3010 3010
                         comms->socketfilename[0]='\0';
3011 3011
                         fprintf(stderr,"WARNING: There is a process using the communication socket for the file\n");
3012
+#warning TODO: if the unix domain socket is in use, connect to it and warn that I''m also able to service that filename, so (1) it forwards the petitions, and (2) be waware of when the other process quits to retake control of the unix domain socket
3012 3013
                         return(-1);
3013 3014
                 }
3014 3015
                 close(oldfd),oldfd=-1;
... ...
@@ -3214,12 +3215,33 @@ int
3214 3215
 re_socketin(re_t *re, int nclient, char *line)
3215 3216
 {
3216 3217
         /* note that the '\n' delimiter has been already removed */
3217
-#warning TODO
3218
-#warning Test with "socat - UNIX-CONNECT:/tmp/.re_${USER}/filename.ext"
3218
+        /* Commands can be sent from the command line using socat as in: */
3219
+        /* "socat - UNIX-CONNECT:/tmp/.re_${USER}/filename.ext" */
3220
+        char *ptr;
3219 3221
 #if 1
3220
-
3221 3222
 fprintf(stderr,"Received from client \"%s\" (%i).\n",line,nclient);
3222 3223
 #endif
3224
+        if(memcmp(line,"goto ",5)==0) {
3225
+                int oldline;
3226
+                ptr=line+5;
3227
+                /* change line */
3228
+                re->command=COMMAND_GOTOLINE;
3229
+                strncpy(re->commandbuf,ptr,sizeof(re->commandbuf));
3230
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
3231
+                oldline=re->curline;
3232
+                re_processcommand(re);
3233
+                if(oldline!=re->curline) {
3234
+                        /* position the cursor near the top of the window */
3235
+                        re->originline=re->curline-3;
3236
+                        re->originline=(re->originline<0)?0:re->originline;
3237
+                }
3238
+                /* send end-of-results */
3239
+                re_socketout(re, nclient, "\n");
3240
+        } else {
3241
+#if 1
3242
+fprintf(stderr,"Ignoring unknown command from client \"%s\" (%i).\n",line,nclient);
3243
+#endif
3244
+        }
3223 3245
         return(0);
3224 3246
 }
3225 3247
 
Browse code

Go to line now accepts an optional column with the syntax line:column

Dario Rodriguez authored on 02/01/2024 17:14:35
Showing 1 changed files
... ...
@@ -1698,16 +1698,23 @@ re_processcommand(re_t *re)
1698 1698
                 }
1699 1699
                 re->headerdirty=1;
1700 1700
         } else if(strcmp(re->command,COMMAND_GOTOLINE)==0) {
1701
-                int line;
1701
+                int line,col;
1702 1702
                 long pos;
1703
-                if(re->commandbuf[0]=='+')
1703
+                col=re->curcol;
1704
+                if(re->commandbuf[0]=='+') {
1704 1705
                         line=re->curline+atoi(re->commandbuf+1);
1705
-                else if(re->commandbuf[0]=='-')
1706
+                } else if(re->commandbuf[0]=='-') {
1706 1707
                         line=re->curline-atoi(re->commandbuf+1);
1707
-                else
1708
+                } else {
1709
+                        char *ptr;
1708 1710
                         line=atoi(re->commandbuf)-1;
1711
+                        for(ptr=re->commandbuf;*ptr>='0' && *ptr<='9';ptr++)
1712
+                                ;
1713
+                        if(*ptr==':')
1714
+                                col=atoi(ptr+1)-1,col=(col<0)?0:col;
1715
+                }
1709 1716
                 line=(line<0)?0:line;
1710
-                if(redata_linecol2pos(re->data,line,re->curcol,&pos,NULL)==-1) {
1717
+                if(redata_linecol2pos(re->data,line,col,&pos,NULL)==-1) {
1711 1718
                         re->command=COMMAND_WARNING;
1712 1719
                         snprintf(re->commandbuf,sizeof(re->commandbuf),"Unknown line");
1713 1720
                         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
... ...
@@ -1715,6 +1722,7 @@ re_processcommand(re_t *re)
1715 1722
                         return(-1);
1716 1723
                 }
1717 1724
                 re->curline=line;
1725
+                re->curcol=col;
1718 1726
                 /* position the line in the center of viewport */
1719 1727
                 re->originline=line-(re->maxrow/2);
1720 1728
                 re->originline=(re->originline<0)?0:re->originline;
Browse code

Add an unix domain socket to be able to integrate with other tools

Dario Rodriguez authored on 01/01/2024 22:02:37
Showing 1 changed files
... ...
@@ -15,6 +15,14 @@
15 15
 #include <signal.h>
16 16
 #include <time.h>
17 17
 #include <sys/time.h>
18
+#include <sys/socket.h>  /* unix domain socket support */
19
+#include <sys/un.h> /* unix domain socket support */
20
+#include <sys/types.h> /* getpwuid() */
21
+#include <pwd.h> /* getpwuid() */
22
+#include <fcntl.h>
23
+#include <sys/select.h>
24
+#include <stdarg.h>
25
+#include <sys/stat.h>
18 26
 
19 27
 #include "re_data.h"
20 28
 #include "re_plugin_unsaved.h"
... ...
@@ -31,7 +39,11 @@
31 39
 #define COMMANDBUFSIZE 1024
32 40
 #define DEFAULTFONTHEIGHT 14
33 41
 #define SELECTBUFBLOCK 16384
34
-#define SIZEBLOCKPRINTS 32
42
+#define PRINTSBLOCKSIZE 32
43
+#define COMMBUFSIZE 16384
44
+#define COMMCLIENTSBLOCKSIZE 32
45
+#define SOCKETFILENAMESIZE 1024
46
+#define LISTENBACKLOG 5
35 47
 
36 48
 #define VIEWONLYPROGNAME "review"
37 49
 
... ...
@@ -167,6 +179,26 @@ typedef struct theme_t {
167 179
         char color_curline[5];
168 180
 } theme_t;
169 181
 
182
+typedef struct commclient_t {
183
+        int fd;
184
+        int sizebufin;
185
+        int usedbufin;
186
+        int gotbufin;
187
+        char bufin[COMMBUFSIZE];
188
+        int sizebufout;
189
+        int usedbufout;
190
+        int gotbufout;
191
+        char bufout[COMMBUFSIZE];
192
+} commclient_t;
193
+
194
+typedef struct comms_t {
195
+        int serverfd;
196
+        char socketfilename[SOCKETFILENAMESIZE];
197
+        int sizeclients;
198
+        int usedclients;
199
+        commclient_t **clients;
200
+} comms_t;
201
+
170 202
 typedef struct re_t {
171 203
         redata_t *data;
172 204
         reui_t *ui;
... ...
@@ -210,6 +242,7 @@ typedef struct re_t {
210 242
         int originlinefunclisting;
211 243
         int curlinefunclisting;
212 244
         struct timeval lastwheel;
245
+        comms_t comms;
213 246
 } re_t;
214 247
 
215 248
 volatile int flag_sigint;
... ...
@@ -259,7 +292,16 @@ redata_t *re_getfunclisting(re_t *re);
259 292
 int re_funclistingxy2line(re_t *re,int mx,int my);
260 293
 int re_wheelaccel(re_t *re, int rawamount);
261 294
 int re_themeset(re_t *re, int ntheme);
262
-
295
+int re_socketinit(re_t *re, char *filename);
296
+void re_socketfree(re_t *re);
297
+int re_socketnewclient(re_t *re);
298
+int re_socketstep(re_t *re);
299
+int re_socketin(re_t *re, int nclient, char *line);
300
+#ifndef __GNUC__
301
+int re_socketout(re_t *re, int nclient, char *format, ...);
302
+#else
303
+        int re_socketout(re_t *re, int nclient, char *format, ...) __attribute__((format(printf,3,4)));
304
+#endif
263 305
 
264 306
 int
265 307
 main(int argc, char *argv[])
... ...
@@ -341,6 +383,9 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
341 383
                                         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
342 384
                                         redata_needssaving_reset(re->data);
343 385
                                 }
386
+                                if(re_socketinit(re,re->filename)!=0) {
387
+                                        fprintf(stderr,"WARNING: Couldn't init communication socket; there will be no integration with other tools\n");
388
+                                }
344 389
                         }
345 390
                 }
346 391
                 /* workaround for some nvidia linux drivers, that show old data on partial updates */
... ...
@@ -396,6 +441,7 @@ fprintf(stderr,"RENDER\n");
396 441
                                 reui_present(re->prints[i].ui);
397 442
                 }
398 443
                 sselect_wait(ssel,(flag_had_events)?10:100);
444
+                re_socketstep(re);
399 445
                 flag_had_events=(flag_had_events>0)?flag_had_events-1:0;
400 446
                 SDL_PumpEvents();
401 447
                 while(SDL_PeepEvents(&event,1,SDL_GETEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT)>0) {
... ...
@@ -874,6 +920,7 @@ re_free(re_t *re)
874 920
                 redata_free(re->data),re->data=NULL;
875 921
         if(re->selectbuf!=NULL)
876 922
                 free(re->selectbuf),re->selectbuf=NULL,re->usedselectbuf=re->sizeselectbuf=0;
923
+        re_socketfree(re);
877 924
         free(re),re=NULL;
878 925
         return;
879 926
 }
... ...
@@ -2172,11 +2219,11 @@ re_addprint(re_t *re)
2172 2219
         /* ensure space for the new printout */
2173 2220
         if(re->usedprints==re->sizeprints) {
2174 2221
                 printout_t *newprints;
2175
-                if((newprints=realloc(re->prints,sizeof(printout_t)*(re->sizeprints+SIZEBLOCKPRINTS)))==NULL)
2222
+                if((newprints=realloc(re->prints,sizeof(printout_t)*(re->sizeprints+PRINTSBLOCKSIZE)))==NULL)
2176 2223
                         return(-1); /* insuf. mem. */
2177 2224
                 re->prints=newprints;
2178
-                memset(re->prints+re->sizeprints,0,sizeof(printout_t)*SIZEBLOCKPRINTS);
2179
-                re->sizeprints+=SIZEBLOCKPRINTS;
2225
+                memset(re->prints+re->sizeprints,0,sizeof(printout_t)*PRINTSBLOCKSIZE);
2226
+                re->sizeprints+=PRINTSBLOCKSIZE;
2180 2227
         }
2181 2228
         for(i=0;i<re->sizeprints;i++) {
2182 2229
                 if(re->prints[i].ui==NULL)
... ...
@@ -2897,3 +2944,297 @@ re_themeset(re_t *re, int ntheme)
2897 2944
         return(0);
2898 2945
 }
2899 2946
 
2947
+int
2948
+re_socketinit(re_t *re,char *filename)
2949
+{
2950
+        int i;
2951
+        comms_t *comms;
2952
+        commclient_t *client;
2953
+        struct sockaddr_un addr;
2954
+        char *ptr;
2955
+        struct passwd *passwd;
2956
+        char *username;
2957
+        int oldfd;
2958
+        char *errstr;
2959
+        if(re==NULL)
2960
+                return(-1);
2961
+        comms=&(re->comms);
2962
+        /* close all current comms */
2963
+        if(comms->serverfd!=-1) {
2964
+                close(comms->serverfd),comms->serverfd=-1;
2965
+                if(comms->socketfilename[0]!='\0')
2966
+                        unlink(comms->socketfilename),comms->socketfilename[0]='\0';
2967
+        }
2968
+        if(re->comms.clients!=NULL) {
2969
+                for(i=0;i<re->comms.sizeclients;i++) {
2970
+                        if((client=re->comms.clients[i])==NULL)
2971
+                                continue;
2972
+                        if(client->fd!=-1)
2973
+                                close(client->fd),client->fd=-1;
2974
+                }
2975
+                re->comms.usedclients=0;
2976
+        }
2977
+        /* prepare the new filepath for the socket */
2978
+        if((passwd=getpwuid(getuid()))==NULL || (username=passwd->pw_name)==NULL) {
2979
+                fprintf(stderr,"WARNING: Couldn't get username\n");
2980
+                return(-1);
2981
+        }
2982
+        ptr=strrchr(filename,'/');
2983
+        ptr=(ptr!=NULL)?ptr+1:filename;
2984
+        snprintf(comms->socketfilename,sizeof(comms->socketfilename),"/tmp/.re_%s",username);
2985
+        comms->socketfilename[sizeof(comms->socketfilename)-1]='\0';
2986
+        mkdir(comms->socketfilename,0700);
2987
+        snprintf(comms->socketfilename,sizeof(comms->socketfilename),"/tmp/.re_%s/%s",username,ptr);
2988
+        comms->socketfilename[sizeof(comms->socketfilename)-1]='\0';
2989
+        if(strlen(comms->socketfilename)>=(sizeof(addr.sun_path))) {
2990
+                comms->socketfilename[0]='\0';
2991
+                fprintf(stderr,"WARNING: Socket path filename too long\n");
2992
+                return(-1);
2993
+        }
2994
+        /* detect if there is a stale socket */
2995
+        if((oldfd=open(comms->socketfilename, O_WRONLY|O_APPEND))!=-1) {
2996
+                fd_set writeset;
2997
+                struct timeval tv;
2998
+                FD_ZERO(&writeset);
2999
+                FD_SET(oldfd,&writeset);
3000
+                tv.tv_sec=tv.tv_usec=0;
3001
+                if(select(oldfd+1,NULL,&writeset,NULL,&tv)>0) {
3002
+                        comms->socketfilename[0]='\0';
3003
+                        fprintf(stderr,"WARNING: There is a process using the communication socket for the file\n");
3004
+                        return(-1);
3005
+                }
3006
+                close(oldfd),oldfd=-1;
3007
+        }
3008
+        unlink(comms->socketfilename);
3009
+        /* create and bind socket */
3010
+        if((errstr="create")==NULL
3011
+          || (comms->serverfd=socket(AF_UNIX,SOCK_STREAM,0))==-1
3012
+          || (errstr="assing")==NULL /* this one never fails, just for completion */
3013
+          || (memset(&addr,0,sizeof(struct sockaddr_un)))==NULL
3014
+          || (addr.sun_family=AF_UNIX)!=AF_UNIX
3015
+          || strncpy(addr.sun_path,comms->socketfilename,sizeof(addr.sun_path))==NULL
3016
+          || (errstr="bind")==NULL
3017
+          || bind(comms->serverfd,(struct sockaddr *)&addr,sizeof(addr))==-1
3018
+          || (errstr="listen")==NULL
3019
+          || listen(comms->serverfd,LISTENBACKLOG)==-1
3020
+          ) {
3021
+                comms->socketfilename[0]='\0';
3022
+                if(comms->serverfd!=-1)
3023
+                        close(comms->serverfd),comms->serverfd=-1;
3024
+                fprintf(stderr,"WARNING: Couldn't %s unix domain socket\n",errstr);
3025
+                return(-1);
3026
+        }
3027
+#if 1
3028
+fprintf(stderr,"Server registered.\n");
3029
+#endif
3030
+        return(0);
3031
+}
3032
+
3033
+void
3034
+re_socketfree(re_t *re)
3035
+{
3036
+        int i;
3037
+        commclient_t *client;
3038
+        if(re==NULL)
3039
+                return; /* nothing to do */
3040
+        if(re->comms.serverfd!=-1)
3041
+                close(re->comms.serverfd),re->comms.serverfd=-1;
3042
+        if(re->comms.socketfilename[0]!='\0')
3043
+                unlink(re->comms.socketfilename),re->comms.socketfilename[0]='\0';
3044
+        if(re->comms.clients!=NULL) {
3045
+                for(i=0;i<re->comms.sizeclients;i++) {
3046
+                        if((client=re->comms.clients[i])==NULL)
3047
+                                continue;
3048
+                        if(client->fd!=-1)
3049
+                                close(client->fd),client->fd=-1;
3050
+                        free(client),client=NULL;
3051
+                        re->comms.clients[i]=NULL;
3052
+                }
3053
+                re->comms.usedclients=re->comms.sizeclients=0;
3054
+                free(re->comms.clients),re->comms.clients=NULL;
3055
+        }
3056
+        return;
3057
+}
3058
+
3059
+int
3060
+re_socketnewclient(re_t *re)
3061
+{
3062
+        int i;
3063
+        int fd;
3064
+        commclient_t *client;
3065
+        struct sockaddr addr;
3066
+        socklen_t addrlen;
3067
+        addrlen=sizeof(addr);
3068
+        if(re==NULL)
3069
+                return(-1); /* sanity check failed */
3070
+        fd=accept(re->comms.serverfd,&addr,&addrlen);
3071
+        if(re->comms.usedclients==re->comms.sizeclients) {
3072
+                commclient_t **newclients;
3073
+                if((newclients=realloc(re->comms.clients,sizeof(commclient_t *)*(re->comms.sizeclients+COMMCLIENTSBLOCKSIZE)))==NULL) {
3074
+                        close(fd),fd=-1;
3075
+                        return(-1); /* insuf. mem. */
3076
+                }
3077
+                re->comms.clients=newclients;
3078
+                memset(re->comms.clients+re->comms.sizeclients,0,sizeof(commclient_t *)*COMMCLIENTSBLOCKSIZE);
3079
+                re->comms.sizeclients+=COMMCLIENTSBLOCKSIZE;
3080
+        }
3081
+        for(i=0;i<re->comms.sizeclients;i++) {
3082
+                if(re->comms.clients[i]==NULL || re->comms.clients[i]->fd==-1)
3083
+                        break;
3084
+        }
3085
+        if(i>=re->comms.sizeclients) {
3086
+                close(fd),fd=-1;
3087
+                re->comms.usedclients=re->comms.sizeclients;
3088
+                return(-1); /* INTERNAL ERROR */
3089
+        }
3090
+        client=re->comms.clients[i];
3091
+        if(client==NULL) {
3092
+                if((client=malloc(sizeof(commclient_t)))==NULL) {
3093
+                        close(fd),fd=-1;
3094
+                        return(-1); /* INTERNAL ERROR */
3095
+                }
3096
+                re->comms.clients[i]=client;
3097
+                memset(client,0,sizeof(commclient_t));
3098
+                client->fd=-1;
3099
+                client->sizebufin=sizeof(client->bufin);
3100
+                client->sizebufout=sizeof(client->bufout);
3101
+        }
3102
+        client->fd=fd;
3103
+        client->usedbufin=client->gotbufin=0;
3104
+        client->usedbufout=client->gotbufout=0;
3105
+        re->comms.usedclients++;
3106
+        re_socketout(re, i, "OK\n");
3107
+#if 1
3108
+fprintf(stderr,"New client registered (%i).\n",i);
3109
+#endif
3110
+        return(i);
3111
+}
3112
+
3113
+int re_socketstep(re_t *re)
3114
+{
3115
+        int maxfd;
3116
+        fd_set readset,writeset;
3117
+        struct timeval tv;
3118
+        int i;
3119
+        comms_t *comms;
3120
+        commclient_t *client;
3121
+        int avail,queued;
3122
+        int nread,nwritten;
3123
+        char *ptr,*next,*end;
3124
+        if(re==NULL || re->comms.serverfd==-1)
3125
+                return(-1); /* sanity check error */
3126
+        comms=&(re->comms);
3127
+        FD_ZERO(&readset);
3128
+        FD_ZERO(&writeset);
3129
+        maxfd=comms->serverfd;
3130
+        FD_SET(comms->serverfd,&readset);
3131
+        for(i=0;i<comms->sizeclients;i++) {
3132
+                if((client=comms->clients[i])==NULL || client->fd==-1)
3133
+                        continue;
3134
+                if(client->gotbufin>0) {
3135
+                        memmove(client->bufin,client->bufin+client->gotbufin,client->usedbufin-client->gotbufin);
3136
+                        client->usedbufin-=client->gotbufin;
3137
+                        client->gotbufin=0;
3138
+                }
3139
+                if((client->sizebufin-client->usedbufin)>0) {
3140
+                        FD_SET(client->fd,&readset);
3141
+                        maxfd=(maxfd<client->fd)?client->fd:maxfd;
3142
+                }
3143
+                if((client->usedbufout-client->gotbufout)>0) {
3144
+                        FD_SET(client->fd,&writeset);
3145
+                        maxfd=(maxfd<client->fd)?client->fd:maxfd;
3146
+                }
3147
+        }
3148
+        tv.tv_sec=tv.tv_usec=0;
3149
+        if(select(maxfd+1,&readset,&writeset,NULL,&tv)<=0)
3150
+                return(0); /* nothing to do */
3151
+        /* server */
3152
+        if(FD_ISSET(comms->serverfd,&readset))
3153
+                re_socketnewclient(re);
3154
+        /* clients */
3155
+        for(i=0;i<comms->sizeclients;i++) {
3156
+                if((client=comms->clients[i])==NULL || client->fd==-1)
3157
+                        continue;
3158
+                if(FD_ISSET(client->fd,&readset)) {
3159
+                        if((queued=sock_queued(client->fd))<=0) {
3160
+                                /* remote has closed the connection */
3161
+#if 1
3162
+fprintf(stderr,"Unregistering client, remote has closed the connection (%i).\n",i);
3163
+#endif
3164
+                                close(client->fd),client->fd=-1;
3165
+                                continue;
3166
+                        }
3167
+                        avail=(client->sizebufin-client->usedbufin);
3168
+                        queued=(queued>avail)?avail:queued;
3169
+                        if((nread=read(client->fd,client->bufin+client->usedbufin,queued))>0) {
3170
+#if 1
3171
+fprintf(stderr,"Read from client %li bytes (%i).\n",(long)nread,i);
3172
+#endif
3173
+                                client->usedbufin+=nread;
3174
+                                for(ptr=client->bufin+client->gotbufin
3175
+                                   ,end=client->bufin+client->usedbufin
3176
+                                   ,next=memchr(ptr,'\n',end-ptr)
3177
+                                   ,next=(next==NULL)?end:next
3178
+                                  ;client->fd!=-1 && next<end
3179
+                                  ;ptr=(next!=end)?next+1:end
3180
+                                   ,next=memchr(ptr,'\n',end-ptr)
3181
+                                   ,next=(next==NULL)?end:next
3182
+                                  ) {
3183
+                                        *next='\0';
3184
+                                        if(next>ptr && next[-1]=='\r')
3185
+                                                next[-1]='\0';
3186
+                                        re_socketin(re,i,ptr);
3187
+                                }
3188
+                                client->gotbufin=ptr-client->bufin;
3189
+                                if(client->fd==-1)
3190
+                                        continue; /* in case the socket has been closed inside re_socketin() */
3191
+                        }
3192
+                }
3193
+                if(FD_ISSET(client->fd,&writeset)) {
3194
+                        queued=client->usedbufout-client->gotbufout;
3195
+                        if((nwritten=write(client->fd,client->bufout+client->gotbufout,client->usedbufout-client->gotbufout))>0)
3196
+                                client->gotbufout+=nwritten;
3197
+#if 1
3198
+fprintf(stderr,"Write to client %li bytes (%i).\n",(long)nwritten,i);
3199
+#endif
3200
+                }
3201
+        }
3202
+        return(0);
3203
+}
3204
+
3205
+int
3206
+re_socketin(re_t *re, int nclient, char *line)
3207
+{
3208
+        /* note that the '\n' delimiter has been already removed */
3209
+#warning TODO
3210
+#warning Test with "socat - UNIX-CONNECT:/tmp/.re_${USER}/filename.ext"
3211
+#if 1
3212
+
3213
+fprintf(stderr,"Received from client \"%s\" (%i).\n",line,nclient);
3214
+#endif
3215
+        return(0);
3216
+}
3217
+
3218
+int
3219
+re_socketout(re_t *re, int nclient, char *format, ...)
3220
+{
3221
+        /* note that the caller has to output the '\n' delimiter to mark the end of the line */
3222
+        commclient_t *client;
3223
+        va_list mylist;
3224
+        int avail;
3225
+        int res;
3226
+        if(re==NULL || nclient<0 || nclient>=re->comms.sizeclients || re->comms.clients[nclient]==NULL || re->comms.clients[nclient]->fd==-1)
3227
+                return(-1); /* sanity check error */
3228
+        client=re->comms.clients[nclient];
3229
+        memmove(client->bufout,client->bufout+client->gotbufout,client->usedbufout-client->gotbufout);
3230
+        client->usedbufout-=client->gotbufout;
3231
+        client->gotbufout=0;
3232
+        avail=client->sizebufout-client->usedbufout;
3233
+        va_start(mylist,format);
3234
+        res=vsnprintf(client->bufout+client->usedbufout,avail,format,mylist);
3235
+        va_end(mylist);
3236
+        if(res<0 || res>=avail)
3237
+                return(-1); /* doesn't fit or another error */
3238
+        client->usedbufout+=res;
3239
+        return(0);
3240
+}
Browse code

Add alternative dark theme, but left it disabled under a pair of #ifdef's (search for 'forest')

Dario Rodriguez authored on 01/01/2024 11:40:55
Showing 1 changed files
... ...
@@ -46,6 +46,7 @@
46 46
 #define COMMAND_QUESTION "(?)"
47 47
 #define COMMAND_EXIT "Exit"
48 48
 
49
+#if 1
49 50
 /* "forest" theme */
50 51
 #define DEFAULT_COLOR_BACKGROUND "\xdf\xdf\xdf\xff"
51 52
 #define DEFAULT_COLOR_PRINTOUTSTRIPE "\xef\xef\xef\xff"
... ...
@@ -76,6 +77,38 @@
76 77
 
77 78
 #define DEFAULT_COLOR_SELNORMAL "\xde\xcf\x7f\xff"
78 79
 #define DEFAULT_COLOR_CURLINE "\xf0\xea\xc9\xff"
80
+#else
81
+/* "alternative" theme */
82
+#define DEFAULT_COLOR_BACKGROUND "\x1a\x1f\x35\xff"
83
+#define DEFAULT_COLOR_PRINTOUTSTRIPE "\x0d\x11\x1e\xff"
84
+
85
+#define DEFAULT_COLOR_CURSORBG "\xff\xff\xff\xff"
86
+#define DEFAULT_COLOR_CURSORFG "\x0d\x11\x1e\xff"
87
+
88
+#define DEFAULT_COLOR_TEXT "\xf2\xf0\xec\xff"
89
+
90
+#define DEFAULT_COLOR_MATCHBG "\xff\xff\xff\xaf"
91
+#define DEFAULT_COLOR_MATCHFG "\xff\x00\x00\x80"
92
+
93
+#define DEFAULT_COLOR_STATUSBG "\x14\x3a\xaf\xff"
94
+#define DEFAULT_COLOR_STATUSFG "\xe6\xdc\x5d\xff"
95
+#define DEFAULT_COLOR_STATUSFGLIGHT "\x6f\x73\xa3\xff"
96
+
97
+#define DEFAULT_COLOR_QUERYBG "\xad\x92\x5e\xff"
98
+#define DEFAULT_COLOR_QUERYFG "\xd0\xef\x4f\xff"
99
+#define DEFAULT_COLOR_QUERYBGOLD "\x83\x75\x59\xff"
100
+#define DEFAULT_COLOR_QUERYFGOLD "\xb1\xc5\x5e\xff"
101
+
102
+#define DEFAULT_COLOR_WARNINGBG "\xba\x07\x07\xff"
103
+#define DEFAULT_COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
104
+
105
+#define DEFAULT_COLOR_INFOBG "\x4e\x8a\x4e\xff"
106
+#define DEFAULT_COLOR_INFOFG "\xee\xee\x46\xff"
107
+#define DEFAULT_COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
108
+
109
+#define DEFAULT_COLOR_SELNORMAL "\x4f\x48\x2b\xff"
110
+#define DEFAULT_COLOR_CURLINE "\x6e\x64\x3c\xff"
111
+#endif
79 112
 
80 113
 #define COLOR_BACKGROUND(re) re->theme.color_background
81 114
 #define COLOR_PRINTOUTSTRIPE(re) re->theme.color_printoutstripe
Browse code

Theme support

Dario Rodriguez authored on 25/09/2023 14:29:12
Showing 1 changed files
... ...
@@ -47,21 +47,57 @@
47 47
 #define COMMAND_EXIT "Exit"
48 48
 
49 49
 /* "forest" theme */
50
-#define COLOR_STATUSBG "\x14\x3a\xaf\xff"
51
-#define COLOR_STATUSFG "\xe6\xdc\x5d\xff"
52
-#define COLOR_STATUSFGLIGHT "\x6f\x73\xa3\xff"
53
-
54
-#define COLOR_QUERYBG "\xad\x92\x5e\xff"
55
-#define COLOR_QUERYFG "\xd0\xef\x4f\xff"
56
-#define COLOR_QUERYBGOLD "\x83\x75\x59\xff"
57
-#define COLOR_QUERYFGOLD "\xb1\xc5\x5e\xff"
58
-
59
-#define COLOR_WARNINGBG "\xba\x07\x07\xff"
60
-#define COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
61
-
62
-#define COLOR_INFOBG "\x4e\x8a\x4e\xff"
63
-#define COLOR_INFOFG "\xee\xee\x46\xff"
64
-#define COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
50
+#define DEFAULT_COLOR_BACKGROUND "\xdf\xdf\xdf\xff"
51
+#define DEFAULT_COLOR_PRINTOUTSTRIPE "\xef\xef\xef\xff"
52
+
53
+#define DEFAULT_COLOR_CURSORBG "\x00\x00\x00\xff"
54
+#define DEFAULT_COLOR_CURSORFG "\xff\xff\xff\xff"
55
+
56
+#define DEFAULT_COLOR_TEXT "\x00\x00\x00\xff"
57
+
58
+#define DEFAULT_COLOR_MATCHBG "\xff\xff\xff\xaf"
59
+#define DEFAULT_COLOR_MATCHFG "\xff\x00\x00\x80"
60
+
61
+#define DEFAULT_COLOR_STATUSBG "\x14\x3a\xaf\xff"
62
+#define DEFAULT_COLOR_STATUSFG "\xe6\xdc\x5d\xff"
63
+#define DEFAULT_COLOR_STATUSFGLIGHT "\x6f\x73\xa3\xff"
64
+
65
+#define DEFAULT_COLOR_QUERYBG "\xad\x92\x5e\xff"
66
+#define DEFAULT_COLOR_QUERYFG "\xd0\xef\x4f\xff"
67
+#define DEFAULT_COLOR_QUERYBGOLD "\x83\x75\x59\xff"
68
+#define DEFAULT_COLOR_QUERYFGOLD "\xb1\xc5\x5e\xff"
69
+
70
+#define DEFAULT_COLOR_WARNINGBG "\xba\x07\x07\xff"
71
+#define DEFAULT_COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
72
+
73
+#define DEFAULT_COLOR_INFOBG "\x4e\x8a\x4e\xff"
74
+#define DEFAULT_COLOR_INFOFG "\xee\xee\x46\xff"
75
+#define DEFAULT_COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
76
+
77
+#define DEFAULT_COLOR_SELNORMAL "\xde\xcf\x7f\xff"
78
+#define DEFAULT_COLOR_CURLINE "\xf0\xea\xc9\xff"
79
+
80
+#define COLOR_BACKGROUND(re) re->theme.color_background
81
+#define COLOR_PRINTOUTSTRIPE(re) re->theme.color_printoutstripe
82
+#define COLOR_CURSORBG(re) re->theme.color_cursorbg
83
+#define COLOR_CURSORFG(re) re->theme.color_cursorfg
84
+#define COLOR_TEXT(re) re->theme.color_text
85
+#define COLOR_MATCHBG(re) re->theme.color_matchbg
86
+#define COLOR_MATCHFG(re) re->theme.color_matchfg
87
+#define COLOR_STATUSBG(re) re->theme.color_statusbg
88
+#define COLOR_STATUSFG(re) re->theme.color_statusfg
89
+#define COLOR_STATUSFGLIGHT(re) re->theme.color_statusfglight
90
+#define COLOR_QUERYBG(re) re->theme.color_querybg
91
+#define COLOR_QUERYFG(re) re->theme.color_queryfg
92
+#define COLOR_QUERYBGOLD(re) re->theme.color_querybgold
93
+#define COLOR_QUERYFGOLD(re) re->theme.color_queryfgold
94
+#define COLOR_WARNINGBG(re) re->theme.color_warningbg
95
+#define COLOR_WARNINGFG(re) re->theme.color_warningfg
96
+#define COLOR_INFOBG(re) re->theme.color_infobg
97
+#define COLOR_INFOFG(re) re->theme.color_infofg
98
+#define COLOR_INFOFGLIGHT(re) re->theme.color_infofglight
99
+#define COLOR_SELNORMAL(re) re->theme.color_selnormal
100
+#define COLOR_CURLINE(re) re->theme.color_curline
65 101
 
66 102
 typedef struct printout_t {
67 103
         reui_t *ui;
... ...
@@ -73,9 +109,35 @@ typedef struct printout_t {
73 109
         int dirty;
74 110
 } printout_t;
75 111
 
112
+typedef struct theme_t {
113
+        int ntheme;
114
+        char color_background[5];
115
+        char color_printoutstripe[5];
116
+        char color_cursorbg[5];
117
+        char color_cursorfg[5];
118
+        char color_text[5];
119
+        char color_matchbg[5];
120
+        char color_matchfg[5];
121
+        char color_statusbg[5];
122
+        char color_statusfg[5];
123
+        char color_statusfglight[5];
124
+        char color_querybg[5];
125
+        char color_queryfg[5];
126
+        char color_querybgold[5];
127
+        char color_queryfgold[5];
128
+        char color_warningbg[5];
129
+        char color_warningfg[5];
130
+        char color_infobg[5];
131
+        char color_infofg[5];
132
+        char color_infofglight[5];
133
+        char color_selnormal[5];
134
+        char color_curline[5];
135
+} theme_t;
136
+
76 137
 typedef struct re_t {
77 138
         redata_t *data;
78 139
         reui_t *ui;
140
+        theme_t theme;
79 141
         int viewonly;
80 142
         int quirk_duplicates;
81 143
         int flag_newfile;
... ...
@@ -126,7 +188,6 @@ static void sighandler_sigint(int num);
126 188
 static void sighandler_sigpipe(int num);
127 189
 static int mystricmp(const char *s1, const char *s2);
128 190
 
129
-
130 191
 re_t *re_init(int viewonly);
131 192
 void re_free(re_t *re);
132 193
 int re_setuidata(re_t *re);
... ...
@@ -164,6 +225,7 @@ int re_drawcontents(re_t *re, printout_t *printout);
164 225
 redata_t *re_getfunclisting(re_t *re);
165 226
 int re_funclistingxy2line(re_t *re,int mx,int my);
166 227
 int re_wheelaccel(re_t *re, int rawamount);
228
+int re_themeset(re_t *re, int ntheme);
167 229
 
168 230
 
169 231
 int
... ...
@@ -755,6 +817,7 @@ re_init(int viewonly)
755 817
         re->viewonly=(viewonly!=0)?1:0;
756 818
         SDL_GetVersion(&linked_version);
757 819
         re->quirk_duplicates=(linked_version.major==2 && linked_version.minor==0 && linked_version.patch==9)?1:0;
820
+        re_themeset(re,0);
758 821
         return(re);
759 822
 }
760 823
 
... ...
@@ -1265,14 +1328,24 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1265 1328
                 re->headerdirty=1;
1266 1329
                 re->contentsdirty=1;
1267 1330
         } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1268
-#warning XXX TODO: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation)
1269
-                re_changefontsize(re, 1);
1331
+                /* NOTE: Control+'+'/'-' iterates between the font sizes (Control+'0' resets to the default font size) */
1332
+                /* NOTE: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation) */
1333
+                if((SDL_GetModState()&KMOD_SHIFT)==0)
1334
+                        re_changefontsize(re, 1);
1335
+                else
1336
+                        re_themeset(re, re->theme.ntheme+1);
1270 1337
                 re->ignorenkeys++;
1271 1338
         } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1272
-                re_changefontsize(re, -1);
1339
+                if((SDL_GetModState()&KMOD_SHIFT)==0)
1340
+                        re_changefontsize(re, -1);
1341
+                else
1342
+                        re_themeset(re, re->theme.ntheme-1);
1273 1343
                 re->ignorenkeys++;
1274 1344
         } else if(event->key.keysym.sym==SDLK_0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
1275
-                re_changefontsize(re, 0);
1345
+                if((SDL_GetModState()&KMOD_SHIFT)==0)
1346
+                        re_changefontsize(re, 0);
1347
+                else
1348
+                        re_themeset(re, 0);
1276 1349
                 if(re->quirk_duplicates)
1277 1350
                         re->ignorenkeys++;
1278 1351
         } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
... ...
@@ -2233,7 +2306,7 @@ re_drawheader_editing(re_t *re)
2233 2306
                 return(-1);
2234 2307
         if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
2235 2308
                 return(0); /* error obtaining position */
2236
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needssaving(re->data)?COLOR_STATUSBG:COLOR_INFOBG);
2309
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needssaving(re->data)?COLOR_STATUSBG(re):COLOR_INFOBG(re));
2237 2310
         /* for the user, lines start at 0 (internally they start at 0) */
2238 2311
         memset(spaces,' ',sizeof(spaces));
2239 2312
         spaces[sizeof(spaces)-1]='\0';
... ...
@@ -2248,10 +2321,10 @@ re_drawheader_editing(re_t *re)
2248 2321
         lenfilename=strlen(re->filename);
2249 2322
         filename=((lenfilename)>(sizeof(spaces)-1))?(re->filename+lenfilename-sizeof(spaces)-1):re->filename;
2250 2323
         spacesfilename=spaces+sizeof(spaces)-1-strlen(filename);
2251
-        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFGLIGHT:COLOR_INFOFGLIGHT
2324
+        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFGLIGHT(re):COLOR_INFOFGLIGHT(re)
2252 2325
            ,"File:%s%s Line:%s Col:%s Pos:%s Size:%s"
2253 2326
           ,spacesfilename,redata_needssaving(re->data)?"*":" ",spaceslinebuf,spacescolbuf,spacesposbuf,spacessizebuf);
2254
-        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFG:COLOR_INFOFG
2327
+        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFG(re):COLOR_INFOFG(re)
2255 2328
            ,"     %s%s      %s     %s     %s      %s"
2256 2329
           ,filename," ",linebuf,colbuf,posbuf,sizebuf);
2257 2330
         re->headerdirty=0;
... ...
@@ -2267,21 +2340,21 @@ re_drawheader_command(re_t *re)
2267 2340
         if(re->command==NULL)
2268 2341
                 return(-1);
2269 2342
         if(re->command[0]=='\0') {
2270
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
2271
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"Command:");
2343
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG(re));
2344
+                reui_printf(re->ui,0,0,COLOR_QUERYFG(re),"Command:");
2272 2345
         } else if(strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_CONFIRMEXIT)==0) {
2273
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG);
2274
-                reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf);
2346
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG(re));
2347
+                reui_printf(re->ui,0,0,COLOR_WARNINGFG(re),"%s %s",re->command,re->commandbuf);
2275 2348
         } else if(strcmp(re->command,COMMAND_INFO)==0) {
2276
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_INFOBG);
2277
-                reui_printf(re->ui,0,0,COLOR_INFOFG,"%s %s",re->command,re->commandbuf);
2349
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_INFOBG(re));
2350
+                reui_printf(re->ui,0,0,COLOR_INFOFG(re),"%s %s",re->command,re->commandbuf);
2278 2351
         } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
2279 2352
                 question_t *q;
2280
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
2353
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG(re));
2281 2354
 #warning XXX TODO: suppont arbitrary number of options, highlight current option
2282 2355
                 q=re->question;
2283 2356
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
2284
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s %s: %s %s%s%s%s%s%s%s%s: %s"
2357
+                reui_printf(re->ui,0,0,COLOR_QUERYFG(re),"%s %s: %s %s%s%s%s%s%s%s%s: %s"
2285 2358
                    ,re->command
2286 2359
                    ,(q->titleshort!=NULL)?q->titleshort:q->title
2287 2360
                    ,(q->bodyshort!=NULL)?q->bodyshort:q->body
... ...
@@ -2293,18 +2366,18 @@ re_drawheader_command(re_t *re)
2293 2366
         } else {
2294 2367
                 int commandlen;
2295 2368
                 int commandbuflen;
2296
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
2369
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG(re));
2297 2370
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
2298 2371
                 commandlen=redata_generic_utf8len(re->command,strlen(re->command));
2299
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s",re->command);
2372
+                reui_printf(re->ui,0,0,COLOR_QUERYFG(re),"%s",re->command);
2300 2373
                 commandbuflen=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf));
2301 2374
                 if(!(re->is_oldcommandbuf) || re->commandbuf[0]=='\0') {
2302
-                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG,"%s",re->commandbuf);
2375
+                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG(re),"%s",re->commandbuf);
2303 2376
                         /* draw something that to indicate the end of the commandbuf (useful if commandbuf ends in spaces) */
2304
-                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1+commandbuflen)+1,re->ui->fontheight/2,1,re->ui->fontheight/2,COLOR_QUERYFG);
2377
+                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1+commandbuflen)+1,re->ui->fontheight/2,1,re->ui->fontheight/2,COLOR_QUERYFG(re));
2305 2378
                 } else {
2306
-                        reui_fillrounded(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD);
2307
-                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD,"%s",re->commandbuf);
2379
+                        reui_fillrounded(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD(re));
2380
+                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD(re),"%s",re->commandbuf);
2308 2381
                 }
2309 2382
         }
2310 2383
         re->headerdirty=0;
... ...
@@ -2329,8 +2402,6 @@ re_drawcontents(re_t *re, printout_t *printout)
2329 2402
         printout_t fakeprintout;
2330 2403
         hcolor_t *colors,fakecolor;
2331 2404
         int ncolors;
2332
-        const char selcolornormal[]={"\xde\xcf\x7f\xff"};
2333
-        const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
2334 2405
         long realstart,realend;
2335 2406
         linecolor_t *linecolors,fakelinecolors;
2336 2407
         int nlinecolors;
... ...
@@ -2391,7 +2462,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2391 2462
         }
2392 2463
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
2393 2464
                 return(0); /* error obtaining position */
2394
-        reui_fill(ui,x0-linenowidth,y0,w,h,"\xdf\xdf\xdf\xff");
2465
+        reui_fill(ui,x0-linenowidth,y0,w,h,COLOR_BACKGROUND(re));
2395 2466
         row=curline-originline;
2396 2467
         pos=cursorpos;
2397 2468
         /* get position/row/col of character at top left of screen */
... ...
@@ -2404,17 +2475,17 @@ re_drawcontents(re_t *re, printout_t *printout)
2404 2475
         }
2405 2476
         /* highlight current line (in printouts, highlight alternating lines) */
2406 2477
         if(printout==NULL) {
2407
-                reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
2478
+                reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
2408 2479
         } else {
2409 2480
                 for(y=y0+((printout->data==NULL)?1:(printout->originline%2))*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
2410
-                        reui_fill(ui,x0-linenowidth,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
2481
+                        reui_fill(ui,x0-linenowidth,y,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
2411 2482
         }
2412 2483
         /* highlight the selection */
2413 2484
         if(printout==NULL && re->selactive) {
2414 2485
                 const char *selcolor;
2415 2486
                 tmprow=row;
2416 2487
                 for(y=y0;y<(y0+h);y+=ui->fontheight,row++) {
2417
-                        selcolor=(row==(curline-originline))?selcolorcurline:selcolornormal;
2488
+                        selcolor=(row==(curline-originline))?COLOR_CURLINE(re):COLOR_SELNORMAL(re);
2418 2489
                         if((originline+row)==re->sellinefrom && (originline+row)==re->sellineto) {
2419 2490
                                 reui_fill(ui,x0+(re->selcolfrom-origincol)*ui->fontwidth,y0+row*ui->fontheight,(re->selcolto-re->selcolfrom)*ui->fontwidth,ui->fontheight+1,selcolor);
2420 2491
                         } else if((originline+row)==re->sellinefrom) {
... ...
@@ -2437,7 +2508,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2437 2508
         if((colors=redata_highlighter_getcolors(data,&ncolors))==NULL) {
2438 2509
                 colors=&fakecolor;
2439 2510
                 ncolors=1;
2440
-                memcpy(fakecolor.rgba,"\x00\x00\x00\xff",5);
2511
+                memcpy(fakecolor.rgba,COLOR_TEXT(re),5);
2441 2512
         }
2442 2513
         drawn_cursor=0;
2443 2514
         matchingpos=-1;
... ...
@@ -2462,7 +2533,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2462 2533
                 }
2463 2534
                 curlinecolor=0;
2464 2535
                 usedlenlinecolor=0;
2465
-                lastcolor="\x00\x00\x00\xff";                      
2536
+                lastcolor=COLOR_TEXT(re);
2466 2537
                 in_error=0;
2467 2538
                 if(flaglineno && origincol==0) {
2468 2539
                         int i,n;
... ...
@@ -2546,22 +2617,22 @@ re_drawcontents(re_t *re, printout_t *printout)
2546 2617
                                 char cursorchar[7];
2547 2618
                                 int usedcursorchar;
2548 2619
                                 /* draw cursor */
2549
-                                reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
2620
+                                reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,COLOR_CURSORBG(re));
2550 2621
                                 drawn_cursor=1;
2551 2622
                                 usedcursorchar=0;
2552 2623
                                 redata_getutf8char(re->data,cursorpos,cursorchar,sizeof(cursorchar),&usedcursorchar);
2553 2624
                                 /* tab chars are drawn as an almost filled block, other chars are written as-is */
2554 2625
                                 if(usedcursorchar==1 && *cursorchar=='\t')
2555
-                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol)+1,y+1,ui->fontwidth-2,ui->fontheight+1-2,"\xff\xff\xff\xff");
2626
+                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol)+1,y+1,ui->fontwidth-2,ui->fontheight+1-2,COLOR_CURSORFG(re));
2556 2627
                                 else
2557
-                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",cursorchar,usedcursorchar);
2628
+                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,COLOR_CURSORFG(re),cursorchar,usedcursorchar);
2558 2629
                                 /* get matching braces/parens/anglebracket/curlybraces for highlighting */
2559 2630
                                 if(usedcursorchar==1 && strchr("[]{}<>()",*cursorchar)!=NULL)
2560 2631
                                         matchingpos=re_getmatchingbracket(re,cursorpos,*cursorchar,&matchingchar);
2561 2632
                         }
2562 2633
                 }
2563 2634
                 if(printout==NULL && row==(curline-originline) && !drawn_cursor)
2564
-                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
2635
+                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,COLOR_CURSORBG(re));
2565 2636
                 if(in_error)
2566 2637
                         break;
2567 2638
                 pos=realend+1;
... ...
@@ -2569,8 +2640,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2569 2640
         /* highlight matching parens/brace/... if applicable */
2570 2641
         if(printout==NULL && matchingpos!=-1 && redata_pos2linecol(data,matchingpos,&mline,&mcol)!=-1) {
2571 2642
                 int x,y;
2572
-                char *fg="\xff\x00\x00\x80";
2573
-                char *bg="\xff\xff\xff\xaf";
2643
+                char *fg=COLOR_MATCHFG(re);
2644
+                char *bg=COLOR_MATCHBG(re);
2574 2645
                 x=x0+(mcol-origincol)*ui->fontwidth+(ui->fontwidth/2);
2575 2646
                 x=(x<x0)?x0:(x>=(x0+w))?(x0+w-1):x;
2576 2647
                 y=y0+(mline-originline)*ui->fontheight+(ui->fontheight/2);
... ...
@@ -2605,7 +2676,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2605 2676
                 for(total=redata_line_total(re->funclisting),i=re->originlinefunclisting,ypos=y0;i<total && ypos<re->h;i++,ypos+=(ui->fontheight/((linebuf[0]=='\0')?2:1))) {
2606 2677
                         fg="\xff\xff\xff\xff";
2607 2678
                         if(i==re->curlinefunclisting) {
2608
-                                reui_fill(ui,x0-linenowidth+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,"\xdf\xdf\xdf\xff");
2679
+                                reui_fill(ui,x0-linenowidth+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,COLOR_BACKGROUND(re));
2609 2680
                                 fg="\x00\x00\x00\xff";
2610 2681
                         }
2611 2682
                         if(redata_line_getstartstr(re->funclisting,i,linebuf,sizeof(linebuf))!=0)
... ...
@@ -2726,12 +2797,70 @@ re_wheelaccel(re_t *re, int rawamount)
2726 2797
         return(wheelamount);
2727 2798
 }
2728 2799
 
2800
+void
2801
+util_applypermutation(int *template3,char *colors,int invert)
2802
+{
2803
+        unsigned char c[3];
2804
+        if(template3==NULL || colors==NULL || template3[0]<0 || template3[0]>2 || template3[1]<0 || template3[1]>2 || template3[2]<0 || template3[2]>2)
2805
+                return; /* sanity check error */
2806
+        if(invert==0) {
2807
+                c[0]=((unsigned char *)colors)[0];
2808
+                c[1]=((unsigned char *)colors)[1];
2809
+                c[2]=((unsigned char *)colors)[2];
2810
+        } else {
2811
+                c[0]=255-((unsigned char *)colors)[0];
2812
+                c[1]=255-((unsigned char *)colors)[1];
2813
+                c[2]=255-((unsigned char *)colors)[2];
2814
+        }
2815
+        ((unsigned char *)colors)[0]=c[template3[0]];
2816
+        ((unsigned char *)colors)[1]=c[template3[1]];
2817
+        ((unsigned char *)colors)[2]=c[template3[2]];
2818
+        return;
2819
+}
2729 2820
 
2730
-
2731
-
2732
-
2733
-
2734
-
2735
-
2736
-
2821
+int
2822
+re_themeset(re_t *re, int ntheme)
2823
+{
2824
+        int permutations[6][3]={{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,1,0},{2,0,1}};
2825
+        int *permutationtemplate;
2826
+        int invert;
2827
+        if(re==NULL)
2828
+                return(-1);
2829
+        /* num. themes: 3*2*1*2=12 (permutations of 3 colors plus inverted colors)*/
2830
+        ntheme=(ntheme<0)?12-((-ntheme)%12):ntheme;
2831
+        ntheme%=12;
2832
+        re->theme.ntheme=ntheme;
2833
+        /* compute invert and the number of permutation */
2834
+        invert=(ntheme>=6)?1:0;
2835
+        ntheme%=6;
2836
+        permutationtemplate=permutations[ntheme];
2837
+        /* reset colors and permutate them */
2838
+        strncpy(re->theme.color_background,DEFAULT_COLOR_BACKGROUND,sizeof(re->theme.color_background)),re->theme.color_background[sizeof(re->theme.color_background)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_background,invert);
2839
+        strncpy(re->theme.color_printoutstripe,DEFAULT_COLOR_PRINTOUTSTRIPE,sizeof(re->theme.color_printoutstripe)),re->theme.color_printoutstripe[sizeof(re->theme.color_printoutstripe)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_printoutstripe,invert);
2840
+        strncpy(re->theme.color_cursorbg,DEFAULT_COLOR_CURSORBG,sizeof(re->theme.color_cursorbg)),re->theme.color_cursorbg[sizeof(re->theme.color_cursorbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_cursorbg,invert);
2841
+        strncpy(re->theme.color_cursorfg,DEFAULT_COLOR_CURSORFG,sizeof(re->theme.color_cursorfg)),re->theme.color_cursorfg[sizeof(re->theme.color_cursorfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_cursorfg,invert);
2842
+        strncpy(re->theme.color_text,DEFAULT_COLOR_TEXT,sizeof(re->theme.color_text)),re->theme.color_text[sizeof(re->theme.color_text)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_text,invert);
2843
+        strncpy(re->theme.color_matchbg,DEFAULT_COLOR_MATCHBG,sizeof(re->theme.color_matchbg)),re->theme.color_matchbg[sizeof(re->theme.color_matchbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_matchbg,invert);
2844
+        strncpy(re->theme.color_matchfg,DEFAULT_COLOR_MATCHFG,sizeof(re->theme.color_matchfg)),re->theme.color_matchfg[sizeof(re->theme.color_matchfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_matchfg,invert);
2845
+        strncpy(re->theme.color_statusbg,DEFAULT_COLOR_STATUSBG,sizeof(re->theme.color_statusbg)),re->theme.color_statusbg[sizeof(re->theme.color_statusbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_statusbg,invert);
2846
+        strncpy(re->theme.color_statusfg,DEFAULT_COLOR_STATUSFG,sizeof(re->theme.color_statusfg)),re->theme.color_statusfg[sizeof(re->theme.color_statusfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_statusfg,invert);
2847
+        strncpy(re->theme.color_statusfglight,DEFAULT_COLOR_STATUSFGLIGHT,sizeof(re->theme.color_statusfglight)),re->theme.color_statusfglight[sizeof(re->theme.color_statusfglight)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_statusfglight,invert);
2848
+        strncpy(re->theme.color_querybg,DEFAULT_COLOR_QUERYBG,sizeof(re->theme.color_querybg)),re->theme.color_querybg[sizeof(re->theme.color_querybg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_querybg,invert);
2849
+        strncpy(re->theme.color_queryfg,DEFAULT_COLOR_QUERYFG,sizeof(re->theme.color_queryfg)),re->theme.color_queryfg[sizeof(re->theme.color_queryfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_queryfg,invert);
2850
+        strncpy(re->theme.color_querybgold,DEFAULT_COLOR_QUERYBGOLD,sizeof(re->theme.color_querybgold)),re->theme.color_querybgold[sizeof(re->theme.color_querybgold)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_querybgold,invert);
2851
+        strncpy(re->theme.color_queryfgold,DEFAULT_COLOR_QUERYFGOLD,sizeof(re->theme.color_queryfgold)),re->theme.color_queryfgold[sizeof(re->theme.color_queryfgold)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_queryfgold,invert);
2852
+        strncpy(re->theme.color_warningbg,DEFAULT_COLOR_WARNINGBG,sizeof(re->theme.color_warningbg)),re->theme.color_warningbg[sizeof(re->theme.color_warningbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_warningbg,invert);
2853
+        strncpy(re->theme.color_warningfg,DEFAULT_COLOR_WARNINGFG,sizeof(re->theme.color_warningfg)),re->theme.color_warningfg[sizeof(re->theme.color_warningfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_warningfg,invert);
2854
+        strncpy(re->theme.color_infobg,DEFAULT_COLOR_INFOBG,sizeof(re->theme.color_infobg)),re->theme.color_infobg[sizeof(re->theme.color_infobg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_infobg,invert);
2855
+        strncpy(re->theme.color_infofg,DEFAULT_COLOR_INFOFG,sizeof(re->theme.color_infofg)),re->theme.color_infofg[sizeof(re->theme.color_infofg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_infofg,invert);
2856
+        strncpy(re->theme.color_infofglight,DEFAULT_COLOR_INFOFGLIGHT,sizeof(re->theme.color_infofglight)),re->theme.color_infofglight[sizeof(re->theme.color_infofglight)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_infofglight,invert);
2857
+        strncpy(re->theme.color_selnormal,DEFAULT_COLOR_SELNORMAL,sizeof(re->theme.color_selnormal)),re->theme.color_selnormal[sizeof(re->theme.color_selnormal)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_selnormal,invert);
2858
+        strncpy(re->theme.color_curline,DEFAULT_COLOR_CURLINE,sizeof(re->theme.color_curline)),re->theme.color_curline[sizeof(re->theme.color_curline)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_curline,invert);
2859
+        /* set theme in highlighter */
2860
+        redata_highlighter_settheme(re->data,ntheme,invert);
2861
+        /* force redraw */
2862
+        re->contentsdirty=1;
2863
+        re->headerdirty=1;
2864
+        return(0);
2865
+}
2737 2866
 
Browse code

Don't ask for exit confirmation on new files (was triggered because of the inserted \n at end-of-file)

Dario Rodriguez authored on 14/04/2023 18:45:47
Showing 1 changed files
... ...
@@ -244,6 +244,7 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
244 244
                                         re->command=COMMAND_WARNING;
245 245
                                         snprintf(re->commandbuf,sizeof(re->commandbuf),"Added missing \\n at end of file");
246 246
                                         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
247
+                                        redata_needssaving_reset(re->data);
247 248
                                 }
248 249
                         }
249 250
                 }
... ...
@@ -410,7 +411,7 @@ fprintf(stderr,"RENDER\n");
410 411
                         /* process main window events */
411 412
                         switch(event.type) {
412 413
                                 case SDL_QUIT:
413
-                                        if(redata_needs_saving(re->data)) {
414
+                                        if(redata_needssaving(re->data)) {
414 415
                                                 re->command=COMMAND_CONFIRMEXIT;
415 416
                                                 re->commandbuf[0]='\0';
416 417
                                                 re->headerdirty=1;
... ...
@@ -1358,7 +1359,7 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
1358 1359
                 re->is_oldcommandbuf=1;
1359 1360
                 re->headerdirty=1;
1360 1361
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
1361
-                if(redata_needs_saving(re->data)) {
1362
+                if(redata_needssaving(re->data)) {
1362 1363
                         re->command=COMMAND_CONFIRMEXIT;
1363 1364
                         re->commandbuf[0]='\0';
1364 1365
                 } else {
... ...
@@ -1990,7 +1991,6 @@ re_sel_lincolisend(re_t *re, int line, int col)
1990 1991
         return(0);
1991 1992
 }
1992 1993
 
1993
-
1994 1994
 int
1995 1995
 re_selectbuf_resize(re_t *re,long size)
1996 1996
 {
... ...
@@ -2233,7 +2233,7 @@ re_drawheader_editing(re_t *re)
2233 2233
                 return(-1);
2234 2234
         if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
2235 2235
                 return(0); /* error obtaining position */
2236
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needs_saving(re->data)?COLOR_STATUSBG:COLOR_INFOBG);
2236
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needssaving(re->data)?COLOR_STATUSBG:COLOR_INFOBG);
2237 2237
         /* for the user, lines start at 0 (internally they start at 0) */
2238 2238
         memset(spaces,' ',sizeof(spaces));
2239 2239
         spaces[sizeof(spaces)-1]='\0';
... ...
@@ -2248,10 +2248,10 @@ re_drawheader_editing(re_t *re)
2248 2248
         lenfilename=strlen(re->filename);
2249 2249
         filename=((lenfilename)>(sizeof(spaces)-1))?(re->filename+lenfilename-sizeof(spaces)-1):re->filename;
2250 2250
         spacesfilename=spaces+sizeof(spaces)-1-strlen(filename);
2251
-        reui_printf(re->ui,0,0,redata_needs_saving(re->data)?COLOR_STATUSFGLIGHT:COLOR_INFOFGLIGHT
2251
+        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFGLIGHT:COLOR_INFOFGLIGHT
2252 2252
            ,"File:%s%s Line:%s Col:%s Pos:%s Size:%s"
2253
-          ,spacesfilename,redata_needs_saving(re->data)?"*":" ",spaceslinebuf,spacescolbuf,spacesposbuf,spacessizebuf);
2254
-        reui_printf(re->ui,0,0,redata_needs_saving(re->data)?COLOR_STATUSFG:COLOR_INFOFG
2253
+          ,spacesfilename,redata_needssaving(re->data)?"*":" ",spaceslinebuf,spacescolbuf,spacesposbuf,spacessizebuf);
2254
+        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFG:COLOR_INFOFG
2255 2255
            ,"     %s%s      %s     %s     %s      %s"
2256 2256
           ,filename," ",linebuf,colbuf,posbuf,sizebuf);
2257 2257
         re->headerdirty=0;
Browse code

bugfix: inserting tabs didn't work when compiling for 32bits

Dario Rodriguez authored on 14/04/2023 18:43:47
Showing 1 changed files
... ...
@@ -956,7 +956,7 @@ re_processkey_editing(re_t *re, SDL_Event *event)
956 956
                 strncpy(event->text.text,"\n",sizeof(event->text.text));
957 957
                 event->text.text[sizeof(event->text.text)-1]='\0';
958 958
         } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_TAB) {
959
-                static char spaces[8]={"        "};
959
+                static char spaces[9]={"        "};
960 960
                 memset(&fakeevent,0,sizeof(SDL_Event));
961 961
                 event=&fakeevent;
962 962
                 event->type=SDL_TEXTINPUT;
Browse code

Code cleanup to avoid some warnings

Dario Rodriguez authored on 01/12/2022 14:41:21
Showing 1 changed files
... ...
@@ -2061,8 +2061,6 @@ int
2061 2061
 re_addprint(re_t *re)
2062 2062
 {
2063 2063
         int i;
2064
-        long frompos,topos;
2065
-        int coldone;
2066 2064
         if(re==NULL)
2067 2065
                 return(-1);
2068 2066
         /* ensure space for the new printout */
... ...
@@ -2092,6 +2090,8 @@ re_addprint(re_t *re)
2092 2090
         re->usedprints++;
2093 2091
         /* copy contents (and set clipboard contents and unselect)*/
2094 2092
         if(re->selactive) {
2093
+                long frompos,topos;
2094
+                int coldone;
2095 2095
                 if(redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
2096 2096
                   && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
2097 2097
                         re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
Browse code

Make "Click on a printout" to go to that line in the main editor window

Dario Rodriguez authored on 01/12/2022 14:34:38
Showing 1 changed files
... ...
@@ -69,6 +69,7 @@ typedef struct printout_t {
69 69
         int originline;
70 70
         int origincol;
71 71
         int showonlyn;
72
+        int mouseselactive;
72 73
         int dirty;
73 74
 } printout_t;
74 75
 
... ...
@@ -310,6 +311,7 @@ fprintf(stderr,"RENDER\n");
310 311
                           || (event.type==SDL_TEXTEDITING && (windowID=event.edit.windowID)!=SDL_GetWindowID(re->ui->win))
311 312
                           || (event.type==SDL_TEXTINPUT && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
312 313
                           || (event.type==SDL_MOUSEWHEEL && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
314
+                          || ((event.type==SDL_MOUSEBUTTONDOWN || event.type==SDL_MOUSEMOTION || event.type==SDL_MOUSEBUTTONUP) && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
313 315
                           ) {
314 316
                                 printout_t *printout;
315 317
                                 for(i=0;i<re->sizeprints;i++) {
... ...
@@ -376,6 +378,32 @@ fprintf(stderr,"RENDER\n");
376 378
                                                         printout->dirty=1;
377 379
                                                 }
378 380
                                                 break;
381
+                                        case SDL_MOUSEBUTTONDOWN:
382
+                                        case SDL_MOUSEBUTTONUP:
383
+                                        case SDL_MOUSEMOTION:
384
+                                                if(!(event.type==SDL_MOUSEMOTION && re->mouseselactive==0)) {
385
+                                                        int mx,my;
386
+                                                        int newposx,newposy;
387
+                                                        long tmppos;
388
+                                                        if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT) {
389
+                                                                printout->mouseselactive=1;
390
+                                                        } else if( event.type==SDL_MOUSEBUTTONUP && event.button.button==SDL_BUTTON_LEFT) {
391
+                                                                printout->mouseselactive=0;
392
+                                                        }
393
+                                                        mx=(event.type!=SDL_MOUSEMOTION)?event.button.x:event.motion.x;
394
+                                                        my=(event.type!=SDL_MOUSEMOTION)?event.button.y:event.motion.y;
395
+                                                        newposx=(mx-(printout->ui->fontwidth*8+printout->ui->fontwidth/2))/printout->ui->fontwidth;
396
+                                                        newposx=(newposx<0)?0:newposx;
397
+                                                        newposy=my/printout->ui->fontheight;
398
+                                                        if(redata_linecol2pos(re->data, printout->originline+newposy, printout->origincol+newposx,&tmppos,NULL)==0) {
399
+                                                                re->curline=printout->originline+newposy;
400
+                                                                re->curcol=printout->origincol+newposx;
401
+                                                                re->headerdirty=1;
402
+                                                                re->contentsdirty=1;
403
+                                                                re_fixorigin_center(re);                                                        }
404
+                                                }
405
+                                                break;
406
+
379 407
                                 }
380 408
                                 continue; /* only want window events from printouts */
381 409
                         }
Browse code

Make Control+Click search the string under the cursor in the function list and got to the line of the first ocurrence, as simplification of 'go to function definition'.

Dario Rodriguez authored on 08/09/2022 21:59:55
Showing 1 changed files
... ...
@@ -63,7 +63,7 @@
63 63
 #define COLOR_INFOFG "\xee\xee\x46\xff"
64 64
 #define COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
65 65
 
66
-typedef struct print_t {
66
+typedef struct printout_t {
67 67
         reui_t *ui;
68 68
         redata_t *data;
69 69
         int originline;
... ...
@@ -495,7 +495,7 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
495 495
                                                 int mx,my;
496 496
                                                 mx=(event.type!=SDL_MOUSEMOTION)?event.button.x:event.motion.x;
497 497
                                                 my=(event.type!=SDL_MOUSEMOTION)?event.button.y:event.motion.y;
498
-                                                if(re->mouseselactive==0 && event.type==SDL_MOUSEBUTTONDOWN && my<re->y && re->funclisting==NULL) {
498
+                                                if(re->mouseselactive==0 && event.type==SDL_MOUSEBUTTONDOWN && !(SDL_GetModState()&KMOD_CTRL) && my<re->y && re->funclisting==NULL) {
499 499
                                                         redata_t *funclisting;
500 500
                                                         if((funclisting=re_getfunclisting(re))==NULL)
501 501
                                                                 break; /* mem. insuf. */
... ...
@@ -524,6 +524,72 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
524 524
                                                         }
525 525
                                                         redata_free(re->funclisting),re->funclisting=NULL;
526 526
                                                         re->contentsdirty=1;
527
+                                                } else if(event.type==SDL_MOUSEBUTTONUP && (SDL_GetModState()&KMOD_CTRL) && my>=re->y) {
528
+                                                        /* control+click: search function definition */
529
+                                                        int newposx,newposy;
530
+                                                        long tmppos;
531
+                                                        newposx=(mx-re->x-(re->showlinenumbers?(re->ui->fontwidth*7+re->ui->fontwidth/2):0))/re->ui->fontwidth;
532
+                                                        newposx=(newposx<0)?0:newposx;
533
+                                                        newposy=(my-re->y)/re->ui->fontheight;
534
+                                                        if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
535
+                                                                char searchbuf[1024]; /* magic number: max. size of string to search (truncated if bigger) */
536
+                                                                int usedsearchbuf;
537
+                                                                char utfchar[5];
538
+                                                                int usedutfchar;
539
+                                                                long startpos,curpos,endpos;
540
+                                                                int c;
541
+                                                                redata_t *funclisting;
542
+                                                                /* search start of word */
543
+                                                                for(curpos=startpos=tmppos;redata_getprevutf8char(re->data,curpos,utfchar,sizeof(utfchar),&usedutfchar)==0;startpos=curpos) {
544
+                                                                        curpos-=usedutfchar;
545
+                                                                        if(usedutfchar==1) {
546
+                                                                                c=utfchar[0];
547
+                                                                                if(!((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'))
548
+                                                                                        break;
549
+                                                                        }
550
+                                                                }
551
+                                                                /* search end of word */
552
+                                                                for(curpos=endpos=tmppos;redata_getutf8char(re->data,curpos,utfchar,sizeof(utfchar),&usedutfchar)==0;endpos=curpos) {
553
+                                                                        curpos+=usedutfchar;
554
+                                                                        if(usedutfchar==1) {
555
+                                                                                c=utfchar[0];
556
+                                                                                if(!((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'))
557
+                                                                                        break;
558
+                                                                        }
559
+                                                                }
560
+                                                                /* extract word, generate funclisting, search word in funclisting */
561
+                                                                funclisting=NULL;
562
+                                                                if(redata_getsubstr(re->data,startpos,endpos,searchbuf,sizeof(searchbuf),&usedsearchbuf)==0
563
+                                                                   && (funclisting=re_getfunclisting(re))!=NULL
564
+                                                                   && (curpos=redata_searchforward(funclisting,0,searchbuf,usedsearchbuf))!=-1) {
565
+                                                                        char linebuf[32],*cmdend;
566
+                                                                        int funcline,funccol;
567
+                                                                        if(redata_pos2linecol(funclisting,curpos,&funcline,&funccol)==0
568
+                                                                           && redata_line_getstartstrtrimmed(funclisting,funcline,linebuf,sizeof(linebuf)," ")==0) {
569
+                                                                                int oldline;
570
+                                                                                if((cmdend=strchr(linebuf,':'))!=NULL)
571
+                                                                                        *cmdend='\0';
572
+                                                                                re->command=COMMAND_GOTOLINE;
573
+                                                                                strncpy(re->commandbuf,linebuf,sizeof(re->commandbuf));
574
+                                                                                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
575
+                                                                                oldline=re->curline;
576
+                                                                                re_processcommand(re);
577
+                                                                                if(oldline!=re->curline) {
578
+                                                                                        /* position the cursor near the top of the window */
579
+                                                                                        re->originline=re->curline-3;
580
+                                                                                        re->originline=(re->originline<0)?0:re->originline;
581
+                                                                                }
582
+                                                                                /* position the cursor at the start of the line */
583
+                                                                                re->origincol=0;
584
+                                                                                re->curcol=0;
585
+                                                                                /* redraw */
586
+                                                                                re->contentsdirty=1;
587
+                                                                        }
588
+                                                                        redata_free(re->funclisting),re->funclisting=NULL;
589
+                                                                }
590
+                                                                if(funclisting!=NULL)
591
+                                                                        redata_free(funclisting),funclisting=NULL;
592
+                                                        }
527 593
                                                 } else if(event.type==SDL_MOUSEMOTION && re->funclisting!=NULL) {
528 594
                                                         if(mx<re->ui->fontwidth*10) {
529 595
                                                                 /* scroll */
... ...
@@ -552,7 +618,7 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
552 618
                                                 } else if(!(event.type==SDL_MOUSEMOTION && (re->mouseselactive==0 || my<re->y || mx<re->x))) {
553 619
                                                         int newposx,newposy;
554 620
                                                         long tmppos;
555
-                                                        if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT) {
621
+                                                        if(event.type==SDL_MOUSEBUTTONDOWN && !(SDL_GetModState()&KMOD_CTRL) && event.button.button==SDL_BUTTON_LEFT) {
556 622
                                                                 re->mouseselactive=1;
557 623
                                                         } else if( event.type==SDL_MOUSEBUTTONUP && event.button.button==SDL_BUTTON_LEFT) {
558 624
                                                                 re->mouseselactive=0;
Browse code

fix: tweak the quirk with inserted characters when doing CTRL+/CTRL- to change the font size, as it was inserting the + and - into the edited file

Dario Rodriguez authored on 22/08/2022 10:10:39
Showing 1 changed files
... ...
@@ -1172,12 +1172,10 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1172 1172
         } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1173 1173
 #warning XXX TODO: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation)
1174 1174
                 re_changefontsize(re, 1);
1175
-                if(re->quirk_duplicates)
1176
-                        re->ignorenkeys++;
1175
+                re->ignorenkeys++;
1177 1176
         } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1178 1177
                 re_changefontsize(re, -1);
1179
-                if(re->quirk_duplicates)
1180
-                        re->ignorenkeys++;
1178
+                re->ignorenkeys++;
1181 1179
         } else if(event->key.keysym.sym==SDLK_0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
1182 1180
                 re_changefontsize(re, 0);
1183 1181
                 if(re->quirk_duplicates)
Browse code

bugfix: when showing line numbers scrolling to the right was not working correctly

Dario Rodriguez authored on 13/08/2022 09:24:14
Showing 1 changed files
... ...
@@ -694,7 +694,7 @@ re_setuidata(re_t *re)
694 694
                 return(-1);
695 695
         re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
696 696
         re->maxrow=re->h/re->ui->fontheight-1;
697
-        re->maxcol=re->w/re->ui->fontwidth-1;
697
+        re->maxcol=(re->w-(re->showlinenumbers?(re->ui->fontwidth*7+re->ui->fontwidth/2):0))/re->ui->fontwidth-1;
698 698
         re_fixorigin(re);
699 699
         return(0);
700 700
 }
... ...
@@ -1233,6 +1233,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1233 1233
                 re_addprint(re);
1234 1234
         } else if(event->key.keysym.sym==SDLK_n && (SDL_GetModState()&KMOD_CTRL)!=0) {
1235 1235
                 re->showlinenumbers=1-re->showlinenumbers;
1236
+                re_setuidata(re);
1236 1237
                 re->contentsdirty=1;
1237 1238
         }
1238 1239
         return(0);
Browse code

bugfix: click to move cursor was moving to a wrong place when showing line numbers

Dario Rodriguez authored on 13/08/2022 09:10:38
Showing 1 changed files
... ...
@@ -557,7 +557,8 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
557 557
                                                         } else if( event.type==SDL_MOUSEBUTTONUP && event.button.button==SDL_BUTTON_LEFT) {
558 558
                                                                 re->mouseselactive=0;
559 559
                                                         }
560
-                                                        newposx=(mx-re->x)/re->ui->fontwidth;
560
+                                                        newposx=(mx-re->x-(re->showlinenumbers?(re->ui->fontwidth*7+re->ui->fontwidth/2):0))/re->ui->fontwidth;
561
+                                                        newposx=(newposx<0)?0:newposx;
561 562
                                                         newposy=(my-re->y)/re->ui->fontheight;
562 563
                                                         if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
563 564
                                                                 re->curline=re->originline+newposy;
Browse code

Add quirk_duplicates, as it seems that the ignorenkeys hack is only necessary on Debian 10 Buster' sdl 2.0.9

Dario Rodriguez authored on 22/05/2022 18:09:47
Showing 1 changed files
... ...
@@ -76,6 +76,7 @@ typedef struct re_t {
76 76
         redata_t *data;
77 77
         reui_t *ui;
78 78
         int viewonly;
79
+        int quirk_duplicates;
79 80
         int flag_newfile;
80 81
         int showlinenumbers;
81 82
         char filename[PATH_MAX];
... ...
@@ -631,6 +632,7 @@ re_t *
631 632
 re_init(int viewonly)
632 633
 {
633 634
         re_t *re;
635
+        SDL_version linked_version;
634 636
         if((re=malloc(sizeof(re_t)))==NULL)
635 637
                 return(NULL); /* insuf. mem. */
636 638
         memset(re,0,sizeof(re_t));
... ...
@@ -655,6 +657,8 @@ re_init(int viewonly)
655 657
                 return(NULL); /* video init error */
656 658
         }
657 659
         re->viewonly=(viewonly!=0)?1:0;
660
+        SDL_GetVersion(&linked_version);
661
+        re->quirk_duplicates=(linked_version.major==2 && linked_version.minor==0 && linked_version.patch==9)?1:0;
658 662
         return(re);
659 663
 }
660 664
 
... ...
@@ -1167,13 +1171,16 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1167 1171
         } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1168 1172
 #warning XXX TODO: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation)
1169 1173
                 re_changefontsize(re, 1);
1170
-                re->ignorenkeys++;
1174
+                if(re->quirk_duplicates)
1175
+                        re->ignorenkeys++;
1171 1176
         } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1172 1177
                 re_changefontsize(re, -1);
1173
-                re->ignorenkeys++;
1178
+                if(re->quirk_duplicates)
1179
+                        re->ignorenkeys++;
1174 1180
         } else if(event->key.keysym.sym==SDLK_0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
1175 1181
                 re_changefontsize(re, 0);
1176
-                re->ignorenkeys++;
1182
+                if(re->quirk_duplicates)
1183
+                        re->ignorenkeys++;
1177 1184
         } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
1178 1185
                 long frompos,topos;
1179 1186
                 int coldone;
... ...
@@ -1198,7 +1205,8 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1198 1205
                         re_sel_toggle(re);
1199 1206
                         re->contentsdirty=1;
1200 1207
                 }
1201
-                re->ignorenkeys++;
1208
+                if(re->quirk_duplicates)
1209
+                        re->ignorenkeys++;
1202 1210
         } else if(event->key.keysym.sym==SDLK_v && (SDL_GetModState()&KMOD_CTRL)!=0) {
1203 1211
                 long cursorpos;
1204 1212
                 /* Mac-HIG/OpenLook-style paste (ctrl+v)*/
... ...
@@ -1218,7 +1226,8 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1218 1226
                 }
1219 1227
                 if(re->usedselectbuf>0)
1220 1228
                         re_textinsert(re, re->selectbuf,re->usedselectbuf);
1221
-                re->ignorenkeys++;
1229
+                if(re->quirk_duplicates)
1230
+                        re->ignorenkeys++;
1222 1231
         } else if(/*re->selactive &&*/ event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
1223 1232
                 re_addprint(re);
1224 1233
         } else if(event->key.keysym.sym==SDLK_n && (SDL_GetModState()&KMOD_CTRL)!=0) {
... ...
@@ -1352,8 +1361,10 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
1352 1361
                 re->command=NULL;
1353 1362
                 re->headerdirty=1;
1354 1363
         }
1355
-        if(!(SDL_GetModState()&KMOD_CTRL))
1356
-                re->ignorenkeys=1; /* control was not pressed, we will receive again this key as SDL_TEXTINPUT */
1364
+        if(!(SDL_GetModState()&KMOD_CTRL)) {
1365
+                if(re->quirk_duplicates)
1366
+                        re->ignorenkeys=1; /* control was not pressed, we will receive again this key as SDL_TEXTINPUT */
1367
+        }
1357 1368
         return(0);
1358 1369
 }
1359 1370
 
Browse code

Implement scrolling with mousewheel

Dario Rodriguez authored on 24/03/2022 18:13:42
Showing 1 changed files
... ...
@@ -14,6 +14,7 @@
14 14
 #include <limits.h>
15 15
 #include <signal.h>
16 16
 #include <time.h>
17
+#include <sys/time.h>
17 18
 
18 19
 #include "re_data.h"
19 20
 #include "re_plugin_unsaved.h"
... ...
@@ -111,6 +112,7 @@ typedef struct re_t {
111 112
         redata_t *funclisting;
112 113
         int originlinefunclisting;
113 114
         int curlinefunclisting;
115
+        struct timeval lastwheel;
114 116
 } re_t;
115 117
 
116 118
 volatile int flag_sigint;
... ...
@@ -159,6 +161,7 @@ int re_drawheader_command(re_t *re);
159 161
 int re_drawcontents(re_t *re, printout_t *printout);
160 162
 redata_t *re_getfunclisting(re_t *re);
161 163
 int re_funclistingxy2line(re_t *re,int mx,int my);
164
+int re_wheelaccel(re_t *re, int rawamount);
162 165
 
163 166
 
164 167
 int
... ...
@@ -305,6 +308,7 @@ fprintf(stderr,"RENDER\n");
305 308
                           || (event.type==SDL_KEYDOWN && (windowID=event.key.windowID)!=SDL_GetWindowID(re->ui->win))
306 309
                           || (event.type==SDL_TEXTEDITING && (windowID=event.edit.windowID)!=SDL_GetWindowID(re->ui->win))
307 310
                           || (event.type==SDL_TEXTINPUT && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
311
+                          || (event.type==SDL_MOUSEWHEEL && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
308 312
                           ) {
309 313
                                 printout_t *printout;
310 314
                                 for(i=0;i<re->sizeprints;i++) {
... ...
@@ -316,6 +320,7 @@ fprintf(stderr,"RENDER\n");
316 320
                                 if(i>=re->sizeprints)
317 321
                                         continue; /* unknown window */
318 322
                                 printout=re->prints+i;
323
+                                /* transfor mousewheel events to keydown events */
319 324
                                 switch(event.type) {
320 325
                                         case SDL_WINDOWEVENT:
321 326
                                                 if(event.window.event==SDL_WINDOWEVENT_SHOWN
... ...
@@ -331,18 +336,24 @@ fprintf(stderr,"RENDER\n");
331 336
                                                 }
332 337
                                                 break;
333 338
                                         case SDL_KEYDOWN:
334
-                                                if(event.key.keysym.sym==SDLK_ESCAPE) {
339
+                                        case SDL_MOUSEWHEEL:
340
+                                                if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE) {
335 341
                                                         re_delprint(re,i);
336
-                                                } if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP || event.key.keysym.sym==SDLK_PAGEDOWN || event.key.keysym.sym==SDLK_PAGEUP) {
342
+                                                } if(event.type==SDL_MOUSEWHEEL || (event.type==SDL_KEYDOWN
343
+                                                  && (event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP
344
+                                                   || event.key.keysym.sym==SDLK_PAGEDOWN || event.key.keysym.sym==SDLK_PAGEUP))) {
337 345
                                                         int neworiginline;
338 346
                                                         int maxrow;
339 347
                                                         int linetotal;
348
+                                                        int wheelamount;
349
+                                                        wheelamount=(event.type==SDL_MOUSEWHEEL)?re_wheelaccel(re,-event.wheel.y):0;
340 350
                                                         maxrow=printout->ui->h/printout->ui->fontheight-1;
341 351
                                                         neworiginline=printout->originline;
342
-                                                        neworiginline+=(event.key.keysym.sym==SDLK_UP)?-1:
343
-                                                                       (event.key.keysym.sym==SDLK_DOWN)?1:
344
-                                                                       (event.key.keysym.sym==SDLK_PAGEUP)?-maxrow:
345
-                                                                       (event.key.keysym.sym==SDLK_PAGEDOWN)?maxrow:
352
+                                                        neworiginline+=(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_UP)?-1:
353
+                                                                       (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_DOWN)?1:
354
+                                                                       (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_PAGEUP)?-maxrow:
355
+                                                                       (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_PAGEDOWN)?maxrow:
356
+                                                                       (event.type==SDL_MOUSEWHEEL)?wheelamount:
346 357
                                                                        0;
347 358
                                                         linetotal=redata_line_total((printout->data!=NULL)?printout->data:re->data);
348 359
                                                         neworiginline=(neworiginline<0)?0:neworiginline;
... ...
@@ -351,12 +362,12 @@ fprintf(stderr,"RENDER\n");
351 362
                                                                 break; /* nothing to do, at top */
352 363
                                                         printout->originline=neworiginline;
353 364
                                                         printout->dirty=1;
354
-                                                } else if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP) {
365
+                                                } else if(event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP)) {
355 366
                                                         if(event.key.keysym.sym==SDLK_UP && printout->originline==0)
356 367
                                                                 break; /* nothing to do, at top */
357 368
                                                         printout->originline+=((event.key.keysym.sym==SDLK_UP)?-1:1);
358 369
                                                         printout->dirty=1;
359
-                                                } else if(event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT) {
370
+                                                } else if(event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT)) {
360 371
                                                         if(event.key.keysym.sym==SDLK_LEFT && printout->origincol==0)
361 372
                                                                 break; /* nothing to do, at top */
362 373
                                                         printout->origincol+=((event.key.keysym.sym==SDLK_LEFT)?-1:1)*8;
... ...
@@ -386,19 +397,25 @@ fprintf(stderr,"RENDER\n");
386 397
                                 case SDL_KEYDOWN:
387 398
                                 case SDL_TEXTINPUT:
388 399
                                 case SDL_TEXTEDITING:
400
+                                case SDL_MOUSEWHEEL:
389 401
                                         if(re->viewonly && (event.type==SDL_TEXTINPUT || event.type==SDL_TEXTEDITING))
390 402
                                                 break;
391
-                                        if(re->viewonly && event.type==SDL_KEYDOWN) {
392
-                                                if(event.key.keysym.sym==SDLK_ESCAPE) {
403
+                                        if(re->viewonly && (event.type==SDL_KEYDOWN || event.type==SDL_MOUSEWHEEL)) {
404
+                                                if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE) {
393 405
                                                         do_exit=1;
394
-                                                } if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP || event.key.keysym.sym==SDLK_PAGEDOWN || event.key.keysym.sym==SDLK_PAGEUP) {
406
+                                                } if(event.type==SDL_MOUSEWHEEL || (event.type==SDL_KEYDOWN
407
+                                                  && (event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP
408
+                                                   || event.key.keysym.sym==SDLK_PAGEDOWN || event.key.keysym.sym==SDLK_PAGEUP))) {
395 409
                                                         int neworiginline;
396 410
                                                         int linetotal;
411
+                                                        int wheelamount;
412
+                                                        wheelamount=(event.type==SDL_MOUSEWHEEL)?re_wheelaccel(re,-event.wheel.y):0;
397 413
                                                         neworiginline=re->originline;
398
-                                                        neworiginline+=(event.key.keysym.sym==SDLK_UP)?-1:
399
-                                                                       (event.key.keysym.sym==SDLK_DOWN)?1:
400
-                                                                       (event.key.keysym.sym==SDLK_PAGEUP)?-re->maxrow:
401
-                                                                       (event.key.keysym.sym==SDLK_PAGEDOWN)?re->maxrow:
414
+                                                        neworiginline+=(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_UP)?-1:
415
+                                                                       (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_DOWN)?1:
416
+                                                                       (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_PAGEUP)?-re->maxrow:
417
+                                                                       (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_PAGEDOWN)?re->maxrow:
418
+                                                                       (event.type==SDL_MOUSEWHEEL)?wheelamount:
402 419
                                                                        0;
403 420
                                                         linetotal=redata_line_total(re->data);
404 421
                                                         neworiginline=(neworiginline<0)?0:neworiginline;
... ...
@@ -409,7 +426,7 @@ fprintf(stderr,"RENDER\n");
409 426
                                                         re->originline=neworiginline;
410 427
                                                         re->headerdirty=1;
411 428
                                                         re->contentsdirty=1;
412
-                                                } else if(event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT) {
429
+                                                } else if(event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT)) {
413 430
                                                         if(event.key.keysym.sym==SDLK_LEFT && re->origincol==0)
414 431
                                                                 break; /* nothing to do, at top */
415 432
                                                         re->origincol+=((event.key.keysym.sym==SDLK_LEFT)?-1:1)*8;
... ...
@@ -829,6 +846,7 @@ int
829 846
 re_processkey_editing(re_t *re, SDL_Event *event)
830 847
 {
831 848
         SDL_Event fakeevent;
849
+        int wheelamount=0;
832 850
         if(re==NULL || event==NULL)
833 851
                 return(-1); /* sanity check failed */
834 852
         /* convert RETURN KEYDOWN to TEXTINPUT */
... ...
@@ -844,7 +862,6 @@ re_processkey_editing(re_t *re, SDL_Event *event)
844 862
                 event=&fakeevent;
845 863
                 event->type=SDL_TEXTINPUT;
846 864
                 /* If control is pressed, insert a real tab, otherwise, insert spaces until next tabstop */
847
-
848 865
                 if((SDL_GetModState()&KMOD_CTRL)!=0) {
849 866
                         strncpy(event->text.text,"\t",sizeof(event->text.text));
850 867
                         event->text.text[sizeof(event->text.text)-1]='\0';
... ...
@@ -887,6 +904,12 @@ fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
887 904
 #if 0
888 905
 fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
889 906
 #endif
907
+        } else if(event->type==SDL_MOUSEWHEEL && event->wheel.y!=0) {
908
+                wheelamount=re_wheelaccel(re,-event->wheel.y);
909
+                memset(&fakeevent,0,sizeof(SDL_Event));
910
+                event=&fakeevent;
911
+                event->type=SDL_KEYDOWN;
912
+                event->key.keysym.sym=(wheelamount>0)?SDLK_DOWN:SDLK_UP;
890 913
         }
891 914
         /* special case: text editing event */
892 915
         if(event->type==SDL_TEXTINPUT) {
... ...
@@ -938,18 +961,20 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
938 961
         } else if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
939 962
                 int move_res;
940 963
                 int oldcol=re->curcol,oldline=re->curline;
941
-                if((SDL_GetModState()&KMOD_CTRL)!=0 && event->key.keysym.sym==SDLK_UP && re->originline==0)
964
+                if(((SDL_GetModState()&KMOD_CTRL)!=0 || wheelamount!=0) && event->key.keysym.sym==SDLK_UP && re->originline==0)
942 965
                         return(0); /* nothing to do, already at top */
943
-                move_res=re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1);
966
+                move_res=re_moveupdown(re,(wheelamount!=0)?wheelamount:(event->key.keysym.sym==SDLK_UP)?-1:1);
944 967
                 if(move_res==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
945 968
                         re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_UP)?-1:1);
946 969
                 }
947
-                if(move_res==0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
970
+                if(move_res==0 && ((SDL_GetModState()&KMOD_CTRL)!=0 || wheelamount!=0)) {
948 971
                         if(event->key.keysym.sym==SDLK_UP && re->originline>0) {
949
-                                re->originline--;
972
+                                re->originline-=(wheelamount==0)?1:((wheelamount<0)?-wheelamount:wheelamount);
973
+                                re->originline=(re->originline<0)?0:re->originline;
950 974
                                 re->contentsdirty=1;
951 975
                         } else if(event->key.keysym.sym==SDLK_DOWN && re->originline<re->curline) {
952
-                                re->originline++;
976
+                                re->originline+=(wheelamount==0)?1:((wheelamount<0)?-wheelamount:wheelamount);
977
+                                re->originline=(re->originline>re->curline)?re->curline:re->originline;
953 978
                                 re->contentsdirty=1;
954 979
                         }
955 980
                 }
... ...
@@ -2575,6 +2600,26 @@ re_funclistingxy2line(re_t *re,int mx,int my)
2575 2600
         return(-1);
2576 2601
 }
2577 2602
 
2603
+int
2604
+re_wheelaccel(re_t *re, int rawamount)
2605
+{
2606
+        int wheelamount;
2607
+        struct timeval old;
2608
+        struct timezone dummy;
2609
+        int oldmsec,newmsec,d;
2610
+        if(re==NULL || rawamount==0)
2611
+                return(rawamount);
2612
+        memcpy(&old,&(re->lastwheel),sizeof(old));
2613
+        if(gettimeofday(&(re->lastwheel),&dummy)!=0 || old.tv_sec<(re->lastwheel.tv_sec-1) || old.tv_sec>re->lastwheel.tv_sec)
2614
+                return(rawamount);
2615
+        oldmsec=old.tv_usec/1000;
2616
+        newmsec=re->lastwheel.tv_usec/1000+((old.tv_sec<re->lastwheel.tv_sec)?1000:0);
2617
+        d=newmsec-oldmsec;
2618
+        wheelamount=rawamount;
2619
+        if(d<70)
2620
+                wheelamount*=10;
2621
+        return(wheelamount);
2622
+}
2578 2623
 
2579 2624
 
2580 2625
 
Browse code

Small cosmetic adjustments for line numbers

Dario Rodriguez authored on 18/03/2022 18:32:20
Showing 1 changed files
... ...
@@ -2253,7 +2253,10 @@ re_drawcontents(re_t *re, printout_t *printout)
2253 2253
         }
2254 2254
         if(flaglineno) {
2255 2255
                 linenosize=6;
2256
-                linenowidth=linenosize*ui->fontwidth+ui->fontwidth*3/2;
2256
+                if(printout==NULL)
2257
+                        linenowidth=linenosize*ui->fontwidth+ui->fontwidth*3/2;
2258
+                else
2259
+                        linenowidth=linenosize*ui->fontwidth+ui->fontwidth*2;
2257 2260
                 x0+=linenowidth;
2258 2261
         }
2259 2262
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
... ...
@@ -2331,12 +2334,12 @@ re_drawcontents(re_t *re, printout_t *printout)
2331 2334
                 usedlenlinecolor=0;
2332 2335
                 lastcolor="\x00\x00\x00\xff";                      
2333 2336
                 in_error=0;
2334
-                if(flaglineno) {
2337
+                if(flaglineno && origincol==0) {
2335 2338
                         int i,n;
2336 2339
                         char buf[2]={0};
2337 2340
                         for(i=linenosize,n=originline+row+1;i>=0;i--,n/=10) {
2338 2341
                                 buf[0]=(n>0 || i==linenosize)?(n%10)+'0':' ';
2339
-                                reui_write(ui,x0-linenowidth+(i-1)*ui->fontwidth,y,"\x00\x00\x00\x2f",buf,1);
2342
+                                reui_write(ui,x0-linenowidth+(i-1)*ui->fontwidth,y,"\xb6\xb6\xb6\xff",buf,1);
2340 2343
                         }
2341 2344
                 }
2342 2345
                 /* draw each part of this line */
Browse code

bugfix: change show-line-numbers toggle from Control+L to Control+N, as Control+L is search-next

Dario Rodriguez authored on 05/03/2022 19:14:12
Showing 1 changed files
... ...
@@ -1196,7 +1196,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1196 1196
                 re->ignorenkeys++;
1197 1197
         } else if(/*re->selactive &&*/ event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
1198 1198
                 re_addprint(re);
1199
-        } else if(event->key.keysym.sym==SDLK_l && (SDL_GetModState()&KMOD_CTRL)!=0) {
1199
+        } else if(event->key.keysym.sym==SDLK_n && (SDL_GetModState()&KMOD_CTRL)!=0) {
1200 1200
                 re->showlinenumbers=1-re->showlinenumbers;
1201 1201
                 re->contentsdirty=1;
1202 1202
         }
Browse code

Make the function listing slightly transparent (as intended)

Dario Rodriguez authored on 05/03/2022 19:08:23
Showing 1 changed files
... ...
@@ -2468,16 +2468,16 @@ re_drawcontents(re_t *re, printout_t *printout)
2468 2468
                 int total,i,ypos;
2469 2469
                 char linebuf[1024];
2470 2470
                 char *fg;
2471
-                reui_fill(ui,x0,y0,w,re->h-y0,"\x44\x33\x22\x7f");
2471
+                reui_fillblended(ui,x0-linenowidth,y0,w,re->h,"\x44\x33\x22\xef");
2472 2472
                 for(total=redata_line_total(re->funclisting),i=re->originlinefunclisting,ypos=y0;i<total && ypos<re->h;i++,ypos+=(ui->fontheight/((linebuf[0]=='\0')?2:1))) {
2473 2473
                         fg="\xff\xff\xff\xff";
2474 2474
                         if(i==re->curlinefunclisting) {
2475
-                                reui_fill(ui,x0+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,"\xdf\xdf\xdf\xff");
2475
+                                reui_fill(ui,x0-linenowidth+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,"\xdf\xdf\xdf\xff");
2476 2476
                                 fg="\x00\x00\x00\xff";
2477 2477
                         }
2478 2478
                         if(redata_line_getstartstr(re->funclisting,i,linebuf,sizeof(linebuf))!=0)
2479 2479
                                 break;
2480
-                        reui_write(ui,x0+ui->fontwidth*3,ypos,fg,linebuf,strlen(linebuf));
2480
+                        reui_write(ui,x0-linenowidth+ui->fontwidth*3,ypos,fg,linebuf,strlen(linebuf));
2481 2481
                 }
2482 2482
         }
2483 2483
         /* all done */
Browse code

Make Control+L show/hide line numbers

Dario Rodriguez authored on 05/03/2022 18:37:40
Showing 1 changed files
... ...
@@ -76,6 +76,7 @@ typedef struct re_t {
76 76
         reui_t *ui;
77 77
         int viewonly;
78 78
         int flag_newfile;
79
+        int showlinenumbers;
79 80
         char filename[PATH_MAX];
80 81
         int x, y, w, h; // contents rect
81 82
         int fontheightpercent;
... ...
@@ -1195,6 +1196,9 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1195 1196
                 re->ignorenkeys++;
1196 1197
         } else if(/*re->selactive &&*/ event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
1197 1198
                 re_addprint(re);
1199
+        } else if(event->key.keysym.sym==SDLK_l && (SDL_GetModState()&KMOD_CTRL)!=0) {
1200
+                re->showlinenumbers=1-re->showlinenumbers;
1201
+                re->contentsdirty=1;
1198 1202
         }
1199 1203
         return(0);
1200 1204
 }
... ...
@@ -2224,7 +2228,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2224 2228
         maxcol=re->maxcol;
2225 2229
         maxrow=re->maxrow;
2226 2230
         showonlyn=0;
2227
-        flaglineno=0;
2231
+        flaglineno=(printout==NULL)?re->showlinenumbers:0;
2228 2232
         linenosize=linenowidth=0;
2229 2233
         if(printout==NULL && re->viewonly==1) {
2230 2234
                 memset(&fakeprintout,0,sizeof(printout_t));
... ...
@@ -2246,6 +2250,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2246 2250
                 maxrow=h/ui->fontheight-1;
2247 2251
                 showonlyn=printout->showonlyn;
2248 2252
                 flaglineno=1;
2253
+        }
2254
+        if(flaglineno) {
2249 2255
                 linenosize=6;
2250 2256
                 linenowidth=linenosize*ui->fontwidth+ui->fontwidth*3/2;
2251 2257
                 x0+=linenowidth;
Browse code

More printout functionality: Add PageUp/PageDown movement, fill entire printout window regardless of selection size, show line numbers in printouts

Dario Rodriguez authored on 05/03/2022 18:26:22
Showing 1 changed files
... ...
@@ -332,6 +332,24 @@ fprintf(stderr,"RENDER\n");
332 332
                                         case SDL_KEYDOWN:
333 333
                                                 if(event.key.keysym.sym==SDLK_ESCAPE) {
334 334
                                                         re_delprint(re,i);
335
+                                                } if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP || event.key.keysym.sym==SDLK_PAGEDOWN || event.key.keysym.sym==SDLK_PAGEUP) {
336
+                                                        int neworiginline;
337
+                                                        int maxrow;
338
+                                                        int linetotal;
339
+                                                        maxrow=printout->ui->h/printout->ui->fontheight-1;
340
+                                                        neworiginline=printout->originline;
341
+                                                        neworiginline+=(event.key.keysym.sym==SDLK_UP)?-1:
342
+                                                                       (event.key.keysym.sym==SDLK_DOWN)?1:
343
+                                                                       (event.key.keysym.sym==SDLK_PAGEUP)?-maxrow:
344
+                                                                       (event.key.keysym.sym==SDLK_PAGEDOWN)?maxrow:
345
+                                                                       0;
346
+                                                        linetotal=redata_line_total((printout->data!=NULL)?printout->data:re->data);
347
+                                                        neworiginline=(neworiginline<0)?0:neworiginline;
348
+                                                        neworiginline=(neworiginline>linetotal)?linetotal:neworiginline;
349
+                                                        if(neworiginline==printout->originline)
350
+                                                                break; /* nothing to do, at top */
351
+                                                        printout->originline=neworiginline;
352
+                                                        printout->dirty=1;
335 353
                                                 } else if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP) {
336 354
                                                         if(event.key.keysym.sym==SDLK_UP && printout->originline==0)
337 355
                                                                 break; /* nothing to do, at top */
... ...
@@ -372,11 +390,22 @@ fprintf(stderr,"RENDER\n");
372 390
                                         if(re->viewonly && event.type==SDL_KEYDOWN) {
373 391
                                                 if(event.key.keysym.sym==SDLK_ESCAPE) {
374 392
                                                         do_exit=1;
375
-                                                } if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP) {
376
-                                                        if(event.key.keysym.sym==SDLK_UP && re->originline==0)
393
+                                                } if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP || event.key.keysym.sym==SDLK_PAGEDOWN || event.key.keysym.sym==SDLK_PAGEUP) {
394
+                                                        int neworiginline;
395
+                                                        int linetotal;
396
+                                                        neworiginline=re->originline;
397
+                                                        neworiginline+=(event.key.keysym.sym==SDLK_UP)?-1:
398
+                                                                       (event.key.keysym.sym==SDLK_DOWN)?1:
399
+                                                                       (event.key.keysym.sym==SDLK_PAGEUP)?-re->maxrow:
400
+                                                                       (event.key.keysym.sym==SDLK_PAGEDOWN)?re->maxrow:
401
+                                                                       0;
402
+                                                        linetotal=redata_line_total(re->data);
403
+                                                        neworiginline=(neworiginline<0)?0:neworiginline;
404
+                                                        neworiginline=(neworiginline>linetotal)?linetotal:neworiginline;
405
+                                                        if(neworiginline==re->originline)
377 406
                                                                 break; /* nothing to do, at top */
378
-                                                        re->originline+=((event.key.keysym.sym==SDLK_UP)?-1:1);
379
-                                                        re->curline+=((event.key.keysym.sym==SDLK_UP)?-1:1);
407
+                                                        re->curline+=(neworiginline-re->originline);
408
+                                                        re->originline=neworiginline;
380 409
                                                         re->headerdirty=1;
381 410
                                                         re->contentsdirty=1;
382 411
                                                 } else if(event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT) {
... ...
@@ -1164,7 +1193,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1164 1193
                 if(re->usedselectbuf>0)
1165 1194
                         re_textinsert(re, re->selectbuf,re->usedselectbuf);
1166 1195
                 re->ignorenkeys++;
1167
-        } else if(re->selactive && event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
1196
+        } else if(/*re->selactive &&*/ event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
1168 1197
                 re_addprint(re);
1169 1198
         }
1170 1199
         return(0);
... ...
@@ -1900,7 +1929,7 @@ re_addprint(re_t *re)
1900 1929
         int i;
1901 1930
         long frompos,topos;
1902 1931
         int coldone;
1903
-        if(re==NULL || re->selactive==0)
1932
+        if(re==NULL)
1904 1933
                 return(-1);
1905 1934
         /* ensure space for the new printout */
1906 1935
         if(re->usedprints==re->sizeprints) {
... ...
@@ -1928,20 +1957,27 @@ re_addprint(re_t *re)
1928 1957
         }
1929 1958
         re->usedprints++;
1930 1959
         /* copy contents (and set clipboard contents and unselect)*/
1931
-        if(redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
1932
-          && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
1933
-                re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
1960
+        if(re->selactive) {
1961
+                if(redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
1962
+                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
1963
+                        re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
1964
+                        redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
1965
+                        SDL_SetClipboardText(re->selectbuf);
1966
+                        re_sel_toggle(re);
1967
+                        re->contentsdirty=1;
1968
+                }
1969
+        } else {
1970
+                re_selectbuf_fill(re,0,redata_getused(re->data),0);
1934 1971
                 redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
1935 1972
                 SDL_SetClipboardText(re->selectbuf);
1936
-                re_sel_toggle(re);
1937 1973
                 re->contentsdirty=1;
1938 1974
         }
1939 1975
 #else
1940 1976
 /* option B: printouts are a window into a fixed place of the file */
1941 1977
         re->prints[i].data=NULL;
1942
-        re->prints[i].originline=re->sellinefrom;
1978
+        re->prints[i].originline=(re->selactive)?re->sellinefrom:0;
1943 1979
         re->prints[i].origincol=0;
1944
-        re->prints[i].showonlyn=re->sellineto-re->sellinefrom+1;
1980
+        re->prints[i].showonlyn=0 /* (re->selactive)?re->sellineto-re->sellinefrom+1:0 */ ;
1945 1981
         re->usedprints++;
1946 1982
 #endif
1947 1983
         re->prints[i].dirty=1;
... ...
@@ -2169,6 +2205,9 @@ re_drawcontents(re_t *re, printout_t *printout)
2169 2205
         char matchingchar;
2170 2206
         int mline,mcol;
2171 2207
         int showonlyn;
2208
+        int flaglineno;
2209
+        int linenowidth;
2210
+        int linenosize;
2172 2211
         if(re==NULL || (printout!=NULL && printout->ui==NULL))
2173 2212
                 return(-1);
2174 2213
         /* init vars and clear screen */
... ...
@@ -2185,6 +2224,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2185 2224
         maxcol=re->maxcol;
2186 2225
         maxrow=re->maxrow;
2187 2226
         showonlyn=0;
2227
+        flaglineno=0;
2228
+        linenosize=linenowidth=0;
2188 2229
         if(printout==NULL && re->viewonly==1) {
2189 2230
                 memset(&fakeprintout,0,sizeof(printout_t));
2190 2231
                 fakeprintout.ui=re->ui;
... ...
@@ -2204,10 +2245,14 @@ re_drawcontents(re_t *re, printout_t *printout)
2204 2245
                 maxcol=w/ui->fontwidth-1;
2205 2246
                 maxrow=h/ui->fontheight-1;
2206 2247
                 showonlyn=printout->showonlyn;
2248
+                flaglineno=1;
2249
+                linenosize=6;
2250
+                linenowidth=linenosize*ui->fontwidth+ui->fontwidth*3/2;
2251
+                x0+=linenowidth;
2207 2252
         }
2208 2253
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
2209 2254
                 return(0); /* error obtaining position */
2210
-        reui_fill(ui,x0,y0,w,h,"\xdf\xdf\xdf\xff");
2255
+        reui_fill(ui,x0-linenowidth,y0,w,h,"\xdf\xdf\xdf\xff");
2211 2256
         row=curline-originline;
2212 2257
         pos=cursorpos;
2213 2258
         /* get position/row/col of character at top left of screen */
... ...
@@ -2220,10 +2265,10 @@ re_drawcontents(re_t *re, printout_t *printout)
2220 2265
         }
2221 2266
         /* highlight current line (in printouts, highlight alternating lines) */
2222 2267
         if(printout==NULL) {
2223
-                reui_fill(ui,x0,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
2268
+                reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
2224 2269
         } else {
2225 2270
                 for(y=y0+((printout->data==NULL)?1:(printout->originline%2))*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
2226
-                        reui_fill(ui,x0,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
2271
+                        reui_fill(ui,x0-linenowidth,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
2227 2272
         }
2228 2273
         /* highlight the selection */
2229 2274
         if(printout==NULL && re->selactive) {
... ...
@@ -2280,6 +2325,14 @@ re_drawcontents(re_t *re, printout_t *printout)
2280 2325
                 usedlenlinecolor=0;
2281 2326
                 lastcolor="\x00\x00\x00\xff";                      
2282 2327
                 in_error=0;
2328
+                if(flaglineno) {
2329
+                        int i,n;
2330
+                        char buf[2]={0};
2331
+                        for(i=linenosize,n=originline+row+1;i>=0;i--,n/=10) {
2332
+                                buf[0]=(n>0 || i==linenosize)?(n%10)+'0':' ';
2333
+                                reui_write(ui,x0-linenowidth+(i-1)*ui->fontwidth,y,"\x00\x00\x00\x2f",buf,1);
2334
+                        }
2335
+                }
2283 2336
                 /* draw each part of this line */
2284 2337
                 for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(origincol+maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
2285 2338
                         int has_nl;
Browse code

Make commandbuffer input to accept Control+TAB (to be able to search/substitute real tabs. Put a cursor con commandbuffer input

Dario Rodriguez authored on 20/02/2022 15:03:32
Showing 1 changed files
... ...
@@ -1302,9 +1302,18 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
1302 1302
 int
1303 1303
 re_processkey_commanddata(re_t *re, SDL_Event *event)
1304 1304
 {
1305
+        SDL_Event fakeevent;
1305 1306
         if(re==NULL || event==NULL)
1306 1307
                 return(-1); /* sanity check failed */
1307 1308
         /* special case: text editing event */
1309
+        if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_TAB && (SDL_GetModState()&KMOD_CTRL)!=0) {
1310
+                /* If control+tab is pressed, insert a real tab (to be able to search for them using Control+F) */
1311
+                memset(&fakeevent,0,sizeof(SDL_Event));
1312
+                event=&fakeevent;
1313
+                event->type=SDL_TEXTINPUT;
1314
+                strncpy(event->text.text,"\t",sizeof(event->text.text));
1315
+                event->text.text[sizeof(event->text.text)-1]='\0';
1316
+        }
1308 1317
         if(event->type==SDL_TEXTINPUT) {
1309 1318
                 int len;
1310 1319
                 if(re->ignorenkeys>0) {
... ...
@@ -2118,10 +2127,12 @@ re_drawheader_command(re_t *re)
2118 2127
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
2119 2128
                 commandlen=redata_generic_utf8len(re->command,strlen(re->command));
2120 2129
                 reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s",re->command);
2130
+                commandbuflen=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf));
2121 2131
                 if(!(re->is_oldcommandbuf) || re->commandbuf[0]=='\0') {
2122 2132
                         reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG,"%s",re->commandbuf);
2133
+                        /* draw something that to indicate the end of the commandbuf (useful if commandbuf ends in spaces) */
2134
+                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1+commandbuflen)+1,re->ui->fontheight/2,1,re->ui->fontheight/2,COLOR_QUERYFG);
2123 2135
                 } else {
2124
-                        commandbuflen=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf));
2125 2136
                         reui_fillrounded(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD);
2126 2137
                         reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD,"%s",re->commandbuf);
2127 2138
                 }
Browse code

Show real tabs as a red space, insert a real tab with Control+Tab (this functionality is to be able to edit Makefiles)

Dario Rodriguez authored on 20/02/2022 14:38:48
Showing 1 changed files
... ...
@@ -813,8 +813,15 @@ re_processkey_editing(re_t *re, SDL_Event *event)
813 813
                 memset(&fakeevent,0,sizeof(SDL_Event));
814 814
                 event=&fakeevent;
815 815
                 event->type=SDL_TEXTINPUT;
816
-                strncpy(event->text.text,spaces+(re->curcol%8),sizeof(event->text.text));
817
-                event->text.text[sizeof(event->text.text)-1]='\0';
816
+                /* If control is pressed, insert a real tab, otherwise, insert spaces until next tabstop */
817
+
818
+                if((SDL_GetModState()&KMOD_CTRL)!=0) {
819
+                        strncpy(event->text.text,"\t",sizeof(event->text.text));
820
+                        event->text.text[sizeof(event->text.text)-1]='\0';
821
+                } else {
822
+                        strncpy(event->text.text,spaces+(re->curcol%8),sizeof(event->text.text));
823
+                        event->text.text[sizeof(event->text.text)-1]='\0';
824
+                }
818 825
         } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_DELETE) {
819 826
 #if 0
820 827
 fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
... ...
@@ -2265,7 +2272,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2265 2272
                 /* draw each part of this line */
2266 2273
                 for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(origincol+maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
2267 2274
                         int has_nl;
2268
-                        char *ptr;
2275
+                        char *ptr,*aux;
2269 2276
                         int incompletestart,incompleteend,endreq;
2270 2277
                         int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */
2271 2278
                         if(redata_line_rawinfo(data,pos,&newpos,&ptr,&len,&is_continuation)==-1) {
... ...
@@ -2280,6 +2287,18 @@ re_drawcontents(re_t *re, printout_t *printout)
2280 2287
                         /* while the avail text is larger than the linecolor len */
2281 2288
                         while(curlinecolor<nlinecolors && (len-has_nl-incompleteend-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
2282 2289
                                 lastcolor=colors[linecolors[curlinecolor].color].rgba;
2290
+                                while((aux=memchr(ptr+used,'\t',linecolors[curlinecolor].len-usedlenlinecolor))!=NULL) {
2291
+                                        /* there is a tab, we want it highlighted with red bg */
2292
+                                        int thislen=aux-(ptr+used);
2293
+                                        reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,ptr+used,thislen);
2294
+                                        usedcol+=redata_generic_utf8len(ptr+used,thislen);
2295
+                                        used+=thislen;
2296
+                                        usedlenlinecolor+=thislen;
2297
+                                        reui_fill(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,ui->fontwidth,ui->fontheight+1,"\xba\x07\x07\xff");
2298
+                                        usedcol++;
2299
+                                        used++;
2300
+                                        usedlenlinecolor++;
2301
+                                }
2283 2302
                                 reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
2284 2303
                                 usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
2285 2304
                                 used+=linecolors[curlinecolor].len-usedlenlinecolor;
... ...
@@ -2328,7 +2347,11 @@ re_drawcontents(re_t *re, printout_t *printout)
2328 2347
                                 drawn_cursor=1;
2329 2348
                                 usedcursorchar=0;
2330 2349
                                 redata_getutf8char(re->data,cursorpos,cursorchar,sizeof(cursorchar),&usedcursorchar);
2331
-                                reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",cursorchar,usedcursorchar);
2350
+                                /* tab chars are drawn as an almost filled block, other chars are written as-is */
2351
+                                if(usedcursorchar==1 && *cursorchar=='\t')
2352
+                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol)+1,y+1,ui->fontwidth-2,ui->fontheight+1-2,"\xff\xff\xff\xff");
2353
+                                else
2354
+                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",cursorchar,usedcursorchar);
2332 2355
                                 /* get matching braces/parens/anglebracket/curlybraces for highlighting */
2333 2356
                                 if(usedcursorchar==1 && strchr("[]{}<>()",*cursorchar)!=NULL)
2334 2357
                                         matchingpos=re_getmatchingbracket(re,cursorpos,*cursorchar,&matchingchar);
Browse code

bugfix: fix uninitialized variable when getting func listing

Dario Rodriguez authored on 19/02/2022 17:46:26
Showing 1 changed files
... ...
@@ -2418,6 +2418,7 @@ re_getfunclisting(re_t *re)
2418 2418
                 return(NULL); /* sanity check error */;
2419 2419
         if((newdata=redata_init(NULL))==NULL)
2420 2420
                 return(NULL); /* couldn't init new buffer */
2421
+        flag_havenextendbuf=0;
2421 2422
         for(lineno=0,total=redata_line_total(re->data);lineno<total;lineno++) {
2422 2423
                 if(redata_line_getstartstr(re->data,lineno,startbuf,sizeof(startbuf))!=0)
2423 2424
                         break; /* internal error */
Browse code

Implement a primitive function navigator when clicking on the status line

Dario Rodriguez authored on 17/02/2022 22:52:05
Showing 1 changed files
... ...
@@ -107,6 +107,9 @@ typedef struct re_t {
107 107
         int sizeprints;
108 108
         int usedprints;
109 109
         printout_t *prints;
110
+        redata_t *funclisting;
111
+        int originlinefunclisting;
112
+        int curlinefunclisting;
110 113
 } re_t;
111 114
 
112 115
 volatile int flag_sigint;
... ...
@@ -153,6 +156,9 @@ long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchi
153 156
 int re_drawheader_editing(re_t *re);
154 157
 int re_drawheader_command(re_t *re);
155 158
 int re_drawcontents(re_t *re, printout_t *printout);
159
+redata_t *re_getfunclisting(re_t *re);
160
+int re_funclistingxy2line(re_t *re,int mx,int my);
161
+
156 162
 
157 163
 int
158 164
 main(int argc, char *argv[])
... ...
@@ -437,11 +443,65 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
437 443
                                 case SDL_MOUSEBUTTONUP:
438 444
                                 case SDL_MOUSEMOTION:
439 445
                                         {
440
-#warning TODO
446
+#warning TODO: select with mouse
441 447
                                                 int mx,my;
442 448
                                                 mx=(event.type!=SDL_MOUSEMOTION)?event.button.x:event.motion.x;
443 449
                                                 my=(event.type!=SDL_MOUSEMOTION)?event.button.y:event.motion.y;
444
-                                                if(!(event.type==SDL_MOUSEMOTION && (re->mouseselactive==0 || my<re->y || mx<re->x))) {
450
+                                                if(re->mouseselactive==0 && event.type==SDL_MOUSEBUTTONDOWN && my<re->y && re->funclisting==NULL) {
451
+                                                        redata_t *funclisting;
452
+                                                        if((funclisting=re_getfunclisting(re))==NULL)
453
+                                                                break; /* mem. insuf. */
454
+                                                        if(re->funclisting!=NULL)
455
+                                                                redata_free(re->funclisting),re->funclisting=NULL;
456
+                                                        re->funclisting=funclisting;
457
+                                                        re->originlinefunclisting=0;
458
+                                                        re->curlinefunclisting=-1;
459
+                                                        re->contentsdirty=1;
460
+                                                } else if(event.type==SDL_MOUSEBUTTONUP && re->funclisting!=NULL) {
461
+                                                        char linebuf[32],*cmdend;
462
+                                                        if(redata_line_getstartstrtrimmed(re->funclisting,re->curlinefunclisting,linebuf,sizeof(linebuf)," ")==0) {
463
+                                                                int oldline;
464
+                                                                if((cmdend=strchr(linebuf,':'))!=NULL)
465
+                                                                        *cmdend='\0';
466
+                                                                re->command=COMMAND_GOTOLINE;
467
+                                                                strncpy(re->commandbuf,linebuf,sizeof(re->commandbuf));
468
+                                                                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
469
+                                                                oldline=re->curline;
470
+                                                                re_processcommand(re);
471
+                                                                if(oldline!=re->curline) {
472
+                                                                        /* position the cursor near the top of the window */
473
+                                                                        re->originline=re->curline-3;
474
+                                                                        re->originline=(re->originline<0)?0:re->originline;
475
+                                                                }
476
+                                                        }
477
+                                                        redata_free(re->funclisting),re->funclisting=NULL;
478
+                                                        re->contentsdirty=1;
479
+                                                } else if(event.type==SDL_MOUSEMOTION && re->funclisting!=NULL) {
480
+                                                        if(mx<re->ui->fontwidth*10) {
481
+                                                                /* scroll */
482
+                                                                int total;
483
+                                                                total=redata_line_total(re->funclisting);
484
+                                                                if(my<re->y) {
485
+                                                                        if(re->originlinefunclisting!=0) {
486
+                                                                                re->originlinefunclisting=0;
487
+                                                                                re->contentsdirty=1;
488
+                                                                        }
489
+                                                                } else if(my>re->y && re->h>re->y) {
490
+                                                                        int old;
491
+                                                                        old=re->originlinefunclisting;
492
+                                                                        re->originlinefunclisting=total*(my-re->y)/(re->h-re->y);
493
+                                                                        if(old!=re->originlinefunclisting)
494
+                                                                                re->contentsdirty=1;
495
+                                                                }
496
+                                                        } else {
497
+                                                                /* select */
498
+                                                                int oldlinefunclisting;
499
+                                                                oldlinefunclisting=re->curlinefunclisting;
500
+                                                                re->curlinefunclisting=re_funclistingxy2line(re,mx,my);
501
+                                                                if(oldlinefunclisting!=re->curlinefunclisting)
502
+                                                                        re->contentsdirty=1;
503
+                                                        }
504
+                                                } else if(!(event.type==SDL_MOUSEMOTION && (re->mouseselactive==0 || my<re->y || mx<re->x))) {
445 505
                                                         int newposx,newposy;
446 506
                                                         long tmppos;
447 507
                                                         if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT) {
... ...
@@ -557,6 +617,8 @@ re_free(re_t *re)
557 617
         int i;
558 618
         if(re==NULL)
559 619
                 return; /* all done */
620
+        if(re->funclisting!=NULL)
621
+                redata_free(re->funclisting),re->funclisting=NULL;
560 622
         for(i=0;i<re->sizeprints;i++) {
561 623
                 if(re->prints[i].ui!=NULL)
562 624
                         re_delprint(re,i);
... ...
@@ -1771,25 +1833,18 @@ re_selectbuf_resize(re_t *re,long size)
1771 1833
 int
1772 1834
 re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces)
1773 1835
 {
1774
-        int nchunk,off,avail;
1775
-        long n;
1776
-        if(re==NULL || size<0 || nadditionalspaces<0 || (frompos+size)>redata_getused(re->data) || redata_getposptr(re->data,frompos,&nchunk,&off)!=0)
1836
+        if(re==NULL || size<0 || nadditionalspaces<0 || (frompos+size)>redata_getused(re->data))
1777 1837
                 return(-1); /* sanity check failed */
1778 1838
         re->usedselectbuf=0;
1779 1839
         if((size+nadditionalspaces+1)>re->sizeselectbuf
1780 1840
           && re_selectbuf_resize(re,size+nadditionalspaces+1)!=0) {
1781 1841
                 return(-1); /* insuf. mem. */
1782 1842
         }
1783
-        for(n=0;n<size && nchunk<re->data->sizechunks;nchunk++,off=0) {
1784
-                avail=re->data->chunks[nchunk]->useddata-off;
1785
-                if(avail<=0)
1786
-                        continue;
1787
-                if(avail>(size-n))
1788
-                        avail=size-n;
1789
-                memcpy(re->selectbuf+n,re->data->chunks[nchunk]->data+off,avail);
1790
-                n+=avail;
1843
+        if(redata_getdata(re->data,frompos,size,re->selectbuf)!=0) {
1844
+                re->usedselectbuf=0;
1845
+                return(-1); /* internal error */
1791 1846
         }
1792
-        re->usedselectbuf=n;
1847
+        re->usedselectbuf=size;
1793 1848
         if(nadditionalspaces>0) {
1794 1849
                 memset(re->selectbuf+re->usedselectbuf,' ',nadditionalspaces);
1795 1850
                 re->usedselectbuf+=nadditionalspaces;
... ...
@@ -2315,6 +2370,23 @@ re_drawcontents(re_t *re, printout_t *printout)
2315 2370
                                 reui_balloon(ui, '\0', x0+w/2, y0+ui->fontheight*((curline-originline)*2+5)/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
2316 2371
                 }
2317 2372
         }
2373
+        /* show func listing if requested */
2374
+        if(printout==NULL && re->funclisting!=NULL) {
2375
+                int total,i,ypos;
2376
+                char linebuf[1024];
2377
+                char *fg;
2378
+                reui_fill(ui,x0,y0,w,re->h-y0,"\x44\x33\x22\x7f");
2379
+                for(total=redata_line_total(re->funclisting),i=re->originlinefunclisting,ypos=y0;i<total && ypos<re->h;i++,ypos+=(ui->fontheight/((linebuf[0]=='\0')?2:1))) {
2380
+                        fg="\xff\xff\xff\xff";
2381
+                        if(i==re->curlinefunclisting) {
2382
+                                reui_fill(ui,x0+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,"\xdf\xdf\xdf\xff");
2383
+                                fg="\x00\x00\x00\xff";
2384
+                        }
2385
+                        if(redata_line_getstartstr(re->funclisting,i,linebuf,sizeof(linebuf))!=0)
2386
+                                break;
2387
+                        reui_write(ui,x0+ui->fontwidth*3,ypos,fg,linebuf,strlen(linebuf));
2388
+                }
2389
+        }
2318 2390
         /* all done */
2319 2391
         if(printout==NULL || printout==&fakeprintout) {
2320 2392
                 re->contentsdirty=0;
... ...
@@ -2326,4 +2398,93 @@ re_drawcontents(re_t *re, printout_t *printout)
2326 2398
         return(0);
2327 2399
 }
2328 2400
 
2401
+redata_t *
2402
+re_getfunclisting(re_t *re)
2403
+{
2404
+        int lineno,total;
2405
+        char startbuf[3];
2406
+        char endbuf[3];
2407
+        char nextendbuf[3];
2408
+        int flag_havenextendbuf;
2409
+        int flag_isstart;
2410
+        int flag_semicolon;
2411
+        int flag_curlybrace;
2412
+        int flag_nextcurlybrace;
2413
+        int flag_previsstart;
2414
+        char linebuf[1024];
2415
+        char annotatedlinebuf[1024];
2416
+        redata_t *newdata;
2417
+        if(re==NULL)
2418
+                return(NULL); /* sanity check error */;
2419
+        if((newdata=redata_init(NULL))==NULL)
2420
+                return(NULL); /* couldn't init new buffer */
2421
+        for(lineno=0,total=redata_line_total(re->data);lineno<total;lineno++) {
2422
+                if(redata_line_getstartstr(re->data,lineno,startbuf,sizeof(startbuf))!=0)
2423
+                        break; /* internal error */
2424
+                if(flag_havenextendbuf==1) {
2425
+                        strncpy(endbuf,nextendbuf,sizeof(endbuf));
2426
+                        endbuf[sizeof(endbuf)-1]='\0';
2427
+                } else if(redata_line_getendstrtrimmed(re->data,lineno,endbuf,sizeof(endbuf)," \t")!=0) {
2428
+                        break; /* internal error */
2429
+                }
2430
+                flag_havenextendbuf=flag_nextcurlybrace=0;
2431
+                if(redata_line_getendstrtrimmed(re->data,lineno+1,nextendbuf,sizeof(nextendbuf)," \t")==0) {
2432
+                        flag_havenextendbuf=1;
2433
+                        flag_nextcurlybrace=(*nextendbuf!='\0' && nextendbuf[strlen(nextendbuf)-1]=='{')?1:0;
2434
+                }
2435
+                flag_isstart=(*startbuf!='\0' && strchr("# \t{/",*startbuf)==NULL)?1:0;
2436
+                flag_semicolon=(*endbuf!='\0' && endbuf[strlen(endbuf)-1]==';')?1:0;
2437
+                flag_curlybrace=(*endbuf!='\0' && endbuf[strlen(endbuf)-1]=='{')?1:0;
2438
+
2439
+                if(flag_isstart && !flag_semicolon && (flag_curlybrace || (flag_havenextendbuf && flag_nextcurlybrace))) {
2440
+                        if(flag_previsstart) {
2441
+                                snprintf(annotatedlinebuf,sizeof(annotatedlinebuf),"%6i: %s\n",lineno+1-1,linebuf);
2442
+                                annotatedlinebuf[sizeof(annotatedlinebuf)-1]='\0';
2443
+                                redata_op_add(newdata,redata_getused(newdata),annotatedlinebuf,strlen(annotatedlinebuf),NULL);
2444
+                                flag_previsstart=0;
2445
+                        }
2446
+                        redata_line_getstartstr(re->data,lineno,linebuf,sizeof(linebuf));
2447
+                        snprintf(annotatedlinebuf,sizeof(annotatedlinebuf),"%6i: %s\n\n",lineno+1,linebuf);
2448
+                        annotatedlinebuf[sizeof(annotatedlinebuf)-1]='\0';
2449
+                        redata_op_add(newdata,redata_getused(newdata),annotatedlinebuf,strlen(annotatedlinebuf),NULL);
2450
+                } else if(flag_isstart) {
2451
+                        redata_line_getstartstr(re->data,lineno,linebuf,sizeof(linebuf));
2452
+                        flag_previsstart=1;
2453
+                } else {
2454
+                        flag_previsstart=0;
2455
+                }
2456
+        }
2457
+        return(newdata);
2458
+}
2459
+
2460
+int
2461
+re_funclistingxy2line(re_t *re,int mx,int my)
2462
+{
2463
+        int total,i,ypos;
2464
+        char linebuf[2];
2465
+        int h;
2466
+        if(re==NULL || mx<0 || my<0)
2467
+                return(-1);
2468
+        for(total=redata_line_total(re->funclisting),i=re->originlinefunclisting,ypos=re->y;i<total && ypos<re->h;i++,ypos+=h) {
2469
+                if(redata_line_getstartstr(re->funclisting,i,linebuf,sizeof(linebuf))!=0)
2470
+                        break;
2471
+                h=(re->ui->fontheight/((linebuf[0]=='\0')?2:1));
2472
+                if(my>=ypos && my<(ypos+h)) {
2473
+                        if(linebuf[0]=='\0')
2474
+                                return(-1);
2475
+                        return(i);
2476
+                }
2477
+        }
2478
+        return(-1);
2479
+}
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2329 2490
 
Browse code

Implement more coherent behaviour when selecting with shift

Dario Rodriguez authored on 11/01/2022 15:20:32
Showing 1 changed files
... ...
@@ -85,6 +85,9 @@ typedef struct re_t {
85 85
         int headerdirty;
86 86
         int contentsdirty;
87 87
         int command_first_key;
88
+        int selstartactive;
89
+        int selstartline;
90
+        int selstartcol;
88 91
         int selactive;
89 92
         int sellinefrom,sellineto;
90 93
         int selcolfrom,selcolto;
... ...
@@ -350,6 +353,11 @@ fprintf(stderr,"RENDER\n");
350 353
                                                 do_exit=1;
351 354
                                         }
352 355
                                         break;
356
+                                case SDL_KEYUP:
357
+                                        if(event.key.keysym.sym==SDLK_RSHIFT || event.key.keysym.sym==SDLK_LSHIFT) {
358
+                                                re->selstartactive=0;
359
+                                        }
360
+                                        break;
353 361
                                 case SDL_KEYDOWN:
354 362
                                 case SDL_TEXTINPUT:
355 363
                                 case SDL_TEXTEDITING:
... ...
@@ -375,6 +383,11 @@ fprintf(stderr,"RENDER\n");
375 383
                                                 }
376 384
                                                 break;
377 385
                                         }
386
+                                        if(!re->viewonly && event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_RSHIFT || event.key.keysym.sym==SDLK_LSHIFT)) {
387
+                                                re->selstartactive=1;
388
+                                                re->selstartline=re->curline;
389
+                                                re->selstartcol=re->curcol;
390
+                                        }
378 391
                                         if(re->command==NULL || strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_INFO)==0)
379 392
                                                 re_processkey_editing(re,&event);
380 393
                                         else if(re->command[0]=='\0')
... ...
@@ -843,19 +856,24 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
843 856
                 }
844 857
         } else if((event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT)) {
845 858
                 int oldcol=re->curcol,oldline=re->curline;
846
-                if(re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
859
+                if(re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline))
847 860
                         re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
848
-                }
849 861
         } else if((SDL_GetModState()&KMOD_CTRL)!=0 && (event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP)) {
850 862
                 long cursorpos;
863
+                int oldcol=re->curcol,oldline=re->curline;
851 864
                 cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
852 865
                 cursorpos=(cursorpos<0)?0:cursorpos;
853 866
                 redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
854 867
                 re_fixorigin_center(re);
868
+                if((SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline))
869
+                        re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_PAGEUP)?-1:1);
855 870
                 re->headerdirty=1;
856 871
                 re->contentsdirty=1;
857 872
         } else if(event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP) {
873
+                int oldcol=re->curcol,oldline=re->curline;
858 874
                 re_moveupdown(re,(event->key.keysym.sym==SDLK_PAGEUP)?-(re->maxrow):re->maxrow);
875
+                if((SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline))
876
+                        re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_PAGEUP)?-1:1);
859 877
         } else if(event->key.keysym.sym==SDLK_HOME || event->key.keysym.sym==SDLK_END) {
860 878
                 long newpos;
861 879
                 long cursorpos;
... ...
@@ -869,9 +887,8 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
869 887
                 cursorpos=newpos;
870 888
                 if(redata_pos2linecol(re->data,cursorpos,NULL,&(re->curcol))==-1)
871 889
                         return(-1); /* couldn't get col of current pos */;
872
-                if((SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
890
+                if((SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline))
873 891
                         re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_HOME)?-1:1);
874
-                }
875 892
                 re_fixorigin(re);
876 893
                 re->headerdirty=1;
877 894
                 re->contentsdirty=1;
... ...
@@ -1632,27 +1649,40 @@ re_sel_resize(re_t *re,int oldcol,int oldline,int direction)
1632 1649
 {
1633 1650
         if(re==NULL || oldcol<0 || oldline<0 || (direction!=-1 && direction!=1))
1634 1651
                 return(-1);
1635
-        if(direction==-1) {
1636
-                if(re->selactive==0) {
1637
-                        re_sel_setstart(re,re->curline,re->curcol);
1638
-                        re_sel_setend(re,oldline,oldcol);
1639
-                } else if(re_sel_lincolisafter(re,re->curline,re->curcol) || re_sel_lincolisinside(re,re->curline,re->curcol)) {
1640
-                        re_sel_setend(re,re->curline,re->curcol);
1652
+        if(re->selstartactive==0) {
1653
+                /* we don't know the start position, manage with the nifo we have */
1654
+                if(direction==-1) {
1655
+                        if(re->selactive==0) {
1656
+                                re_sel_setstart(re,re->curline,re->curcol);
1657
+                                re_sel_setend(re,oldline,oldcol);
1658
+                        } else if(re_sel_lincolisafter(re,re->curline,re->curcol) || re_sel_lincolisinside(re,re->curline,re->curcol)) {
1659
+                                re_sel_setend(re,re->curline,re->curcol);
1660
+                        } else {
1661
+                                re_sel_setstart(re,re->curline,re->curcol);
1662
+                        }
1641 1663
                 } else {
1642
-                        re_sel_setstart(re,re->curline,re->curcol);
1664
+                        if(re->selactive==0 || re_sel_lincolisbefore(re,oldline,oldcol)) {
1665
+                                re_sel_setstart(re,oldline,oldcol);
1666
+                                re_sel_setend(re,re->curline,re->curcol);
1667
+                        } else if(re_sel_lincolisinside(re,oldline,oldcol)) {
1668
+                                re_sel_setstart(re,re->curline,re->curcol);
1669
+                        } else {
1670
+                                re_sel_setend(re,re->curline,re->curcol);
1671
+                        }
1643 1672
                 }
1644 1673
         } else {
1645
-                if(re->selactive==0 || re_sel_lincolisbefore(re,oldline,oldcol)) {
1646
-                        re_sel_setstart(re,oldline,oldcol);
1647
-                        re_sel_setend(re,re->curline,re->curcol);
1648
-                } else if(re_sel_lincolisinside(re,oldline,oldcol)) {
1674
+                /* we know the start position, try to select accordingly */
1675
+                if(re->curline<re->selstartline || (re->curline==re->selstartline && re->curcol<=re->selstartcol)) {
1649 1676
                         re_sel_setstart(re,re->curline,re->curcol);
1677
+                        re_sel_setend(re,re->selstartline,re->selstartcol);
1650 1678
                 } else {
1679
+                        re_sel_setstart(re,re->selstartline,re->selstartcol);
1651 1680
                         re_sel_setend(re,re->curline,re->curcol);
1652 1681
                 }
1653 1682
         }
1654 1683
         if(re->sellinefrom==re->sellineto && re->selcolfrom==re->selcolto)
1655 1684
                 re->selactive=0;
1685
+
1656 1686
         return(0);
1657 1687
 }
1658 1688
 
Browse code

bugfix: inserting in the space after the last character of the line now doesn't move selections after the insertion point

Dario Rodriguez authored on 07/01/2022 18:15:46
Showing 1 changed files
... ...
@@ -645,11 +645,6 @@ re_textinsert(re_t *re, char *text, int sizetext)
645 645
         }
646 646
         fixsel=0;
647 647
         selstart=selend=0;
648
-        if(re->selactive
649
-          && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&selstart,NULL)==0
650
-          && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&selend,NULL)==0) {
651
-                fixsel=1;
652
-        }
653 648
         at_end=(cursorpos==realend)?1:0;
654 649
         for(nspaces=0;nspaces<sizetext && text[nspaces]==' ';nspaces++)
655 650
                 ;
... ...
@@ -668,6 +663,11 @@ re_textinsert(re_t *re, char *text, int sizetext)
668 663
                 /* increment cursorpos; spaces are 1 byte, so the number of columns advanced is the number of bytes advanced */
669 664
                 cursorpos+=re->curcol-col;
670 665
         }
666
+        if(re->selactive
667
+          && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&selstart,NULL)==0
668
+          && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&selend,NULL)==0) {
669
+                fixsel=1;
670
+        }
671 671
         if(redata_op_add(re->data,cursorpos,text,sizetext,NULL)!=0)
672 672
                 return(-1); /* couldn't add requested text */
673 673
         /* fix selection */
Browse code

Update author email

Dario Rodriguez authored on 07/01/2022 17:57:32
Showing 1 changed files
... ...
@@ -3,9 +3,10 @@
3 3
  *
4 4
  * A programmers editor
5 5
  *
6
- * Author: Dario Rodriguez dario@softhome.net
6
+ * Author: Dario Rodriguez antartica@whereismybit.com
7 7
  * This program is licensed under the terms of GNU GPL v2.1+
8 8
  */
9
+
9 10
 #include <stdio.h>
10 11
 #include <stdlib.h>
11 12
 #include <unistd.h>
Browse code

Implement relative go-to-line (i.e. ctrl+q-l '+5')

Dario Rodriguez authored on 04/12/2021 18:04:41
Showing 1 changed files
... ...
@@ -1287,7 +1287,12 @@ re_processcommand(re_t *re)
1287 1287
         } else if(strcmp(re->command,COMMAND_GOTOLINE)==0) {
1288 1288
                 int line;
1289 1289
                 long pos;
1290
-                line=atoi(re->commandbuf)-1;
1290
+                if(re->commandbuf[0]=='+')
1291
+                        line=re->curline+atoi(re->commandbuf+1);
1292
+                else if(re->commandbuf[0]=='-')
1293
+                        line=re->curline-atoi(re->commandbuf+1);
1294
+                else
1295
+                        line=atoi(re->commandbuf)-1;
1291 1296
                 line=(line<0)?0:line;
1292 1297
                 if(redata_linecol2pos(re->data,line,re->curcol,&pos,NULL)==-1) {
1293 1298
                         re->command=COMMAND_WARNING;
Browse code

make printout data change as the original data changes (that is, printouts are now a view to another part of the file)

Dario Rodriguez authored on 02/09/2021 20:36:13
Showing 1 changed files
... ...
@@ -66,6 +66,7 @@ typedef struct print_t {
66 66
         redata_t *data;
67 67
         int originline;
68 68
         int origincol;
69
+        int showonlyn;
69 70
         int dirty;
70 71
 } printout_t;
71 72
 
... ...
@@ -259,8 +260,15 @@ fprintf(stderr,"REDRAW Header (command)\n");
259 260
                                 }
260 261
                         }
261 262
                 }
262
-                if(re->contentsdirty)
263
+                if(re->contentsdirty) {
264
+                        /* set associated printouts as dirty too */
265
+                        for(i=0;i<re->sizeprints;i++) {
266
+                                if(re->prints[i].ui!=NULL && re->prints[i].data==NULL)
267
+                                        re->prints[i].dirty=1;
268
+                        }
269
+                        /* redraw contents */
263 270
                         re_drawcontents(re,NULL);
271
+                }
264 272
                 if(re->ui->rendererdirty) {
265 273
 #if 0
266 274
 fprintf(stderr,"RENDER\n");
... ...
@@ -661,12 +669,34 @@ re_textinsert(re_t *re, char *text, int sizetext)
661 669
         }
662 670
         if(redata_op_add(re->data,cursorpos,text,sizetext,NULL)!=0)
663 671
                 return(-1); /* couldn't add requested text */
672
+        /* fix selection */
664 673
         if(fixsel) {
665 674
                 if(cursorpos<=selstart)
666 675
                         redata_pos2linecol(re->data,selstart+sizetext,&(re->sellinefrom),&(re->selcolfrom));
667 676
                 if(cursorpos<=selend)
668 677
                         redata_pos2linecol(re->data,selend+sizetext,&(re->sellineto),&(re->selcolto));
669 678
         }
679
+        /* fix printouts scope */
680
+        if(re->usedprints>0) {
681
+                int i;
682
+                int numnl;
683
+                printout_t *printout;
684
+                for(numnl=0,ptr=strchr(text,'\n');ptr!=NULL;ptr=strchr(ptr+1,'\n'))
685
+                        numnl++;
686
+                for(i=0;i<re->usedprints;i++) {
687
+                        printout=re->prints+i;
688
+                        if(printout->data!=NULL)
689
+                                continue; /* has its own copy of the data */
690
+                        if(printout->originline>re->curline) {
691
+                                printout->originline+=numnl;
692
+                        } else if(printout->showonlyn>0
693
+                            && re->curline>=printout->originline
694
+                            && re->curline<(printout->originline+printout->showonlyn)) {
695
+                                printout->showonlyn+=numnl;
696
+                        }
697
+                }
698
+        }
699
+        /* fix cursor pos */
670 700
         for(ptr=text,next=memchr(text,'\n',sizetext);ptr!=NULL;ptr=(next!=NULL)?next+1:NULL,next=(ptr!=NULL)?memchr(ptr,'\n',sizetext-(ptr-text)):NULL) {
671 701
                 len=(next!=NULL)?(next-ptr):sizetext-(ptr-text);
672 702
                 re->curcol+=redata_generic_utf8len(ptr,len);
... ...
@@ -907,6 +937,23 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
907 937
                         dellen=cursorpos-delpos;
908 938
                         redata_op_del(re->data,delpos,dellen,NULL);
909 939
                         cursorpos=delpos;
940
+                        /* fix printouts scope */
941
+                        if(re->usedprints>0) {
942
+                                int i;
943
+                                printout_t *printout;
944
+                                for(i=0;i<re->usedprints;i++) {
945
+                                        printout=re->prints+i;
946
+                                        if(printout->data!=NULL)
947
+                                                continue; /* has its own copy of the data */
948
+                                        if(printout->originline>re->curline) {
949
+                                                printout->originline--;
950
+                                        } else if(printout->showonlyn>1
951
+                                            && re->curline>=printout->originline
952
+                                            && re->curline<(printout->originline+printout->showonlyn)) {
953
+                                                printout->showonlyn--;
954
+                                        }
955
+                                }
956
+                        }
910 957
                 }
911 958
                 redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
912 959
                 if(fixsel) {
... ...
@@ -1766,6 +1813,8 @@ re_addprint(re_t *re)
1766 1813
         /* setup window */
1767 1814
         if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL)
1768 1815
                 return(-1); /* couldn't init window */
1816
+#if 0
1817
+/* option A: printouts are immutable */
1769 1818
         if((re->prints[i].data=redata_init(redata_highlighter_register,NULL))==NULL) {
1770 1819
                 reui_free(re->prints[i].ui),re->prints[i].ui=NULL;
1771 1820
                 return(-1); /* couldn't init data store */
... ...
@@ -1780,6 +1829,14 @@ re_addprint(re_t *re)
1780 1829
                 re_sel_toggle(re);
1781 1830
                 re->contentsdirty=1;
1782 1831
         }
1832
+#else
1833
+/* option B: printouts are a window into a fixed place of the file */
1834
+        re->prints[i].data=NULL;
1835
+        re->prints[i].originline=re->sellinefrom;
1836
+        re->prints[i].origincol=0;
1837
+        re->prints[i].showonlyn=re->sellineto-re->sellinefrom+1;
1838
+        re->usedprints++;
1839
+#endif
1783 1840
         re->prints[i].dirty=1;
1784 1841
         return(0);
1785 1842
 }
... ...
@@ -2002,7 +2059,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2002 2059
         int matchingpos;
2003 2060
         char matchingchar;
2004 2061
         int mline,mcol;
2005
-        if(re==NULL || (printout!=NULL && (printout->ui==NULL || printout->data==NULL)))
2062
+        int showonlyn;
2063
+        if(re==NULL || (printout!=NULL && printout->ui==NULL))
2006 2064
                 return(-1);
2007 2065
         /* init vars and clear screen */
2008 2066
         ui=re->ui;
... ...
@@ -2017,6 +2075,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2017 2075
         curcol=re->curcol;
2018 2076
         maxcol=re->maxcol;
2019 2077
         maxrow=re->maxrow;
2078
+        showonlyn=0;
2020 2079
         if(printout==NULL && re->viewonly==1) {
2021 2080
                 memset(&fakeprintout,0,sizeof(printout_t));
2022 2081
                 fakeprintout.ui=re->ui;
... ...
@@ -2026,7 +2085,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2026 2085
                 printout=&fakeprintout;
2027 2086
         } else if(printout!=NULL) {
2028 2087
                 ui=printout->ui;
2029
-                data=printout->data;
2088
+                data=(printout->data==NULL)?re->data:printout->data;
2030 2089
                 x0=0;
2031 2090
                 y0=0;
2032 2091
                 w=ui->w;
... ...
@@ -2035,6 +2094,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2035 2094
                 origincol=curcol=printout->origincol;
2036 2095
                 maxcol=w/ui->fontwidth-1;
2037 2096
                 maxrow=h/ui->fontheight-1;
2097
+                showonlyn=printout->showonlyn;
2038 2098
         }
2039 2099
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
2040 2100
                 return(0); /* error obtaining position */
... ...
@@ -2053,7 +2113,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2053 2113
         if(printout==NULL) {
2054 2114
                 reui_fill(ui,x0,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
2055 2115
         } else {
2056
-                for(y=y0+(printout->originline%2)*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
2116
+                for(y=y0+((printout->data==NULL)?1:(printout->originline%2))*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
2057 2117
                         reui_fill(ui,x0,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
2058 2118
         }
2059 2119
         /* highlight the selection */
... ...
@@ -2096,6 +2156,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2096 2156
                 /* definition of vars for tracking linecolor usage */
2097 2157
                 int curlinecolor; /* current linecolor */
2098 2158
                 int usedlenlinecolor; /* number of bytes of current linecolor already drawn */
2159
+                if(showonlyn>0 && ui->fontheight>0 && (showonlyn)<((y-y0)/ui->fontheight))
2160
+                        break; /* this printout is configured to only show up to here */
2099 2161
                 /* get start/end of line */
2100 2162
                 if(redata_line_realstart(data,pos,&realstart)==-1 || redata_line_realend(data,pos,&realend)==-1)
2101 2163
                         break; /* couldn't get real start/end */
Browse code

add commandbuf suggestion for 'find and replace' replace string

Dario Rodriguez authored on 01/09/2021 20:38:40
Showing 1 changed files
... ...
@@ -1280,6 +1280,7 @@ re_processcommand(re_t *re)
1280 1280
                 re->cachelastsearch[sizeof(re->cachelastsearch)-1]='\0';
1281 1281
                 strncpy(re->commandbuf,re->cachelastreplacewith,sizeof(re->commandbuf));
1282 1282
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1283
+                re->is_oldcommandbuf=1;
1283 1284
                 re->headerdirty=1;
1284 1285
                 return(0);
1285 1286
         } else if(strcmp(re->command,COMMAND_REPLACEWITH)==0) {
... ...
@@ -1287,6 +1288,7 @@ re_processcommand(re_t *re)
1287 1288
                 strncpy(re->cachelastreplacewith,re->commandbuf,sizeof(re->cachelastreplacewith));
1288 1289
                 re->cachelastreplacewith[sizeof(re->cachelastreplacewith)-1]='\0';
1289 1290
                 re->commandbuf[0]='\0';
1291
+                re->is_oldcommandbuf=0;
1290 1292
                 re->headerdirty=1;
1291 1293
                 return(0);
1292 1294
         } else if(strcmp(re->command,COMMAND_REPLACEHOW)==0) {
Browse code

rounded corners for commandbuf suggestion

Dario Rodriguez authored on 01/09/2021 20:33:06
Showing 1 changed files
... ...
@@ -1965,7 +1965,7 @@ re_drawheader_command(re_t *re)
1965 1965
                         reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG,"%s",re->commandbuf);
1966 1966
                 } else {
1967 1967
                         commandbuflen=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf));
1968
-                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD);
1968
+                        reui_fillrounded(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD);
1969 1969
                         reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD,"%s",re->commandbuf);
1970 1970
                 }
1971 1971
         }
Browse code

Make old commandbuf (search string, etc) only a suggestion: reset commandbuf if key is not RIGHT/END/ENTER when showing the suggestion

Dario Rodriguez authored on 01/09/2021 18:43:41
Showing 1 changed files
... ...
@@ -51,6 +51,8 @@
51 51
 
52 52
 #define COLOR_QUERYBG "\xad\x92\x5e\xff"
53 53
 #define COLOR_QUERYFG "\xd0\xef\x4f\xff"
54
+#define COLOR_QUERYBGOLD "\x83\x75\x59\xff"
55
+#define COLOR_QUERYFGOLD "\xb1\xc5\x5e\xff"
54 56
 
55 57
 #define COLOR_WARNINGBG "\xba\x07\x07\xff"
56 58
 #define COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
... ...
@@ -84,11 +86,14 @@ typedef struct re_t {
84 86
         int selactive;
85 87
         int sellinefrom,sellineto;
86 88
         int selcolfrom,selcolto;
89
+        int mouseselactive;
90
+        int sellinestart,selcolstart;
87 91
         long sizeselectbuf;
88 92
         long usedselectbuf;
89 93
         char *selectbuf;
90 94
         char *command;
91 95
         char commandbuf[COMMANDBUFSIZE];
96
+        int is_oldcommandbuf;
92 97
         char cachelastsearch[COMMANDBUFSIZE];
93 98
         char cachelastreplacewith[COMMANDBUFSIZE];
94 99
         question_t *question;
... ...
@@ -135,6 +140,7 @@ int re_sel_lincolisend(re_t *re, int line, int col);
135 140
 int re_selectbuf_resize(re_t *re,long size);
136 141
 int re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces);
137 142
 int re_selectbuf_replace(re_t *re,char *newdata);
143
+int re_clipget(re_t *re);
138 144
 int re_addprint(re_t *re);
139 145
 int re_delprint(re_t *re, int nprint);
140 146
 int re_rtrim(re_t *re, long curpos, int *trimmed);
... ...
@@ -406,16 +412,29 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
406 412
                                         }
407 413
                                         break;
408 414
                                 case SDL_MOUSEBUTTONDOWN:
409
-                                        if(event.button.y>=re->y && event.button.x>=re->x) {
410
-                                                int newposx,newposy;
411
-                                                long tmppos;
412
-                                                newposx=(event.button.x-re->x)/re->ui->fontwidth;
413
-                                                newposy=(event.button.y-re->y)/re->ui->fontheight;
414
-                                                if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
415
-                                                        re->curline=re->originline+newposy;
416
-                                                        re->curcol=re->origincol+newposx;
417
-                                                        re->headerdirty=1;
418
-                                                        re->contentsdirty=1;
415
+                                case SDL_MOUSEBUTTONUP:
416
+                                case SDL_MOUSEMOTION:
417
+                                        {
418
+#warning TODO
419
+                                                int mx,my;
420
+                                                mx=(event.type!=SDL_MOUSEMOTION)?event.button.x:event.motion.x;
421
+                                                my=(event.type!=SDL_MOUSEMOTION)?event.button.y:event.motion.y;
422
+                                                if(!(event.type==SDL_MOUSEMOTION && (re->mouseselactive==0 || my<re->y || mx<re->x))) {
423
+                                                        int newposx,newposy;
424
+                                                        long tmppos;
425
+                                                        if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button==SDL_BUTTON_LEFT) {
426
+                                                                re->mouseselactive=1;
427
+                                                        } else if( event.type==SDL_MOUSEBUTTONUP && event.button.button==SDL_BUTTON_LEFT) {
428
+                                                                re->mouseselactive=0;
429
+                                                        }
430
+                                                        newposx=(mx-re->x)/re->ui->fontwidth;
431
+                                                        newposy=(my-re->y)/re->ui->fontheight;
432
+                                                        if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
433
+                                                                re->curline=re->originline+newposy;
434
+                                                                re->curcol=re->origincol+newposx;
435
+                                                                re->headerdirty=1;
436
+                                                                re->contentsdirty=1;
437
+                                                        }
419 438
                                                 }
420 439
                                         }
421 440
                                         break;
... ...
@@ -1029,16 +1048,19 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
1029 1048
         if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_l) {
1030 1049
                 re->command=COMMAND_GOTOLINE;
1031 1050
                 re->commandbuf[0]='\0';
1051
+                re->is_oldcommandbuf=0;
1032 1052
                 re->headerdirty=1;
1033 1053
         } else if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_f) {
1034 1054
                 re->command=COMMAND_SEARCHFORWARD;
1035 1055
                 strncpy(re->commandbuf,re->cachelastsearch,sizeof(re->commandbuf));
1036 1056
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1057
+                re->is_oldcommandbuf=1;
1037 1058
                 re->headerdirty=1;
1038 1059
         } else if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_a) {
1039 1060
                 re->command=COMMAND_REPLACEWHAT;
1040 1061
                 strncpy(re->commandbuf,re->cachelastsearch,sizeof(re->commandbuf));
1041 1062
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1063
+                re->is_oldcommandbuf=1;
1042 1064
                 re->headerdirty=1;
1043 1065
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
1044 1066
                 if(redata_needs_saving(re->data)) {
... ...
@@ -1048,6 +1070,7 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
1048 1070
                         re->command=COMMAND_EXIT;
1049 1071
                         re->commandbuf[0]='\0';
1050 1072
                 }
1073
+                re->is_oldcommandbuf=0;
1051 1074
                 re->headerdirty=1;
1052 1075
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_h) {
1053 1076
                 re_sel_toggle(re);
... ...
@@ -1154,6 +1177,10 @@ re_processkey_commanddata(re_t *re, SDL_Event *event)
1154 1177
                         re->ignorenkeys--;
1155 1178
                         return(0); /* this is an already processed key, ignore it */
1156 1179
                 }
1180
+                if(re->is_oldcommandbuf) {
1181
+                        re->commandbuf[0]='\0';
1182
+                        re->is_oldcommandbuf=0;
1183
+                }
1157 1184
                 len=strlen(event->text.text);
1158 1185
                 if((strlen(re->commandbuf)+len+1)>=sizeof(re->commandbuf))
1159 1186
                         return(-1); /* No space for text */
... ...
@@ -1172,12 +1199,24 @@ re_processkey_commanddata(re_t *re, SDL_Event *event)
1172 1199
         } else if(event->key.keysym.sym==SDLK_BACKSPACE && re->commandbuf[0]!='\0') {
1173 1200
                 int nchar;
1174 1201
                 char *ptr;
1202
+                if(re->is_oldcommandbuf) {
1203
+                        re->commandbuf[0]='\0';
1204
+                        re->is_oldcommandbuf=0;
1205
+                        re->headerdirty=1;
1206
+                        return(0);
1207
+                }
1175 1208
                 if((nchar=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf)))<=0)
1176 1209
                         return(-1); /* error parsing commandbuf */
1177 1210
                 if((ptr=redata_generic_utf8col(re->commandbuf,strlen(re->commandbuf),nchar-1))==NULL)
1178 1211
                         return(-1); /* error positioning in commandbuf */
1179 1212
                 *ptr='\0';
1180 1213
                 re->headerdirty=1;
1214
+        } else if(event->key.keysym.sym==SDLK_RIGHT || event->key.keysym.sym==SDLK_END) {
1215
+                if(re->is_oldcommandbuf) {
1216
+                        re->is_oldcommandbuf=0;
1217
+                        re->headerdirty=1;
1218
+                        return(0);
1219
+                }
1181 1220
         } else if(event->key.keysym.sym==SDLK_RETURN) {
1182 1221
                 re_processcommand(re);
1183 1222
         }
... ...
@@ -1691,6 +1730,14 @@ re_selectbuf_replace(re_t *re,char *newdata)
1691 1730
         return(0);
1692 1731
 }
1693 1732
 
1733
+int
1734
+re_clipget(re_t *re)
1735
+{
1736
+#warning TODO
1737
+        return(-1);
1738
+}
1739
+
1740
+
1694 1741
 int
1695 1742
 re_addprint(re_t *re)
1696 1743
 {
... ...
@@ -1908,9 +1955,19 @@ re_drawheader_command(re_t *re)
1908 1955
                    ,(q->nopts>3)?" 4.":"",(q->nopts>4)?(q->optsshort!=NULL)?q->optsshort[3]:q->opts[3]:""
1909 1956
                    ,re->commandbuf);
1910 1957
         } else {
1958
+                int commandlen;
1959
+                int commandbuflen;
1911 1960
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
1912 1961
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1913
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s %s",re->command,re->commandbuf);
1962
+                commandlen=redata_generic_utf8len(re->command,strlen(re->command));
1963
+                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s",re->command);
1964
+                if(!(re->is_oldcommandbuf) || re->commandbuf[0]=='\0') {
1965
+                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG,"%s",re->commandbuf);
1966
+                } else {
1967
+                        commandbuflen=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf));
1968
+                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD);
1969
+                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD,"%s",re->commandbuf);
1970
+                }
1914 1971
         }
1915 1972
         re->headerdirty=0;
1916 1973
         re->ui->rendererdirty=1;
Browse code

Move cursor to mouse click

Dario Rodriguez authored on 03/06/2021 05:01:07
Showing 1 changed files
... ...
@@ -405,6 +405,20 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
405 405
                                                 re->contentsdirty=1;
406 406
                                         }
407 407
                                         break;
408
+                                case SDL_MOUSEBUTTONDOWN:
409
+                                        if(event.button.y>=re->y && event.button.x>=re->x) {
410
+                                                int newposx,newposy;
411
+                                                long tmppos;
412
+                                                newposx=(event.button.x-re->x)/re->ui->fontwidth;
413
+                                                newposy=(event.button.y-re->y)/re->ui->fontheight;
414
+                                                if(redata_linecol2pos(re->data, re->originline+newposy, re->origincol+newposx,&tmppos,NULL)==0) {
415
+                                                        re->curline=re->originline+newposy;
416
+                                                        re->curcol=re->origincol+newposx;
417
+                                                        re->headerdirty=1;
418
+                                                        re->contentsdirty=1;
419
+                                                }
420
+                                        }
421
+                                        break;
408 422
                                 default:
409 423
                                         break;
410 424
                         }
Browse code

bugfix: fix memory leak when getting the clipboard text

Dario Rodriguez authored on 02/06/2021 05:33:05
Showing 1 changed files
... ...
@@ -984,8 +984,11 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
984 984
                         return(-1); /* error obtaining position */
985 985
                 if(re->selactive)
986 986
                         re_sel_toggle(re);
987
-                if(SDL_HasClipboardText())
988
-                        re_selectbuf_replace(re,SDL_GetClipboardText());
987
+                if(SDL_HasClipboardText()) {
988
+                        char *ptr;
989
+                        re_selectbuf_replace(re,(ptr=SDL_GetClipboardText()));
990
+                        SDL_free(ptr),ptr=NULL;
991
+                }
989 992
                 if(SDL_HasClipboardText()) {
990 993
                         char *ptr;
991 994
                         re_selectbuf_replace(re,(ptr=SDL_GetClipboardText()));
Browse code

fix: correctly set the boundaries of data to move on Ctrl+K+C/Ctrl+K+V

Dario Rodriguez authored on 02/06/2021 05:31:03
Showing 1 changed files
... ...
@@ -986,9 +986,11 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
986 986
                         re_sel_toggle(re);
987 987
                 if(SDL_HasClipboardText())
988 988
                         re_selectbuf_replace(re,SDL_GetClipboardText());
989
-#if 1
990
-fprintf(stderr,"SELECTBUF:\"%s\" len:%i\n",re->selectbuf,(int)strlen(re->selectbuf));
991
-#endif
989
+                if(SDL_HasClipboardText()) {
990
+                        char *ptr;
991
+                        re_selectbuf_replace(re,(ptr=SDL_GetClipboardText()));
992
+                        SDL_free(ptr),ptr=NULL;
993
+                }
992 994
                 if(re->usedselectbuf>0)
993 995
                         re_textinsert(re, re->selectbuf,re->usedselectbuf);
994 996
                 re->ignorenkeys++;
Browse code

fix: correctly handling of spaces at start and end of doing a Ctrl+C/Ctrl+V.

Dario Rodriguez authored on 30/05/2021 15:04:46
Showing 1 changed files
... ...
@@ -116,6 +116,7 @@ int re_setuidata(re_t *re);
116 116
 int re_setfilename(re_t *re, char *filename);
117 117
 int re_fixorigin(re_t *re);
118 118
 int re_fixorigin_center(re_t *re);
119
+int re_textinsert(re_t *re, char *text, int sizetext);
119 120
 int re_processkey_editing(re_t *re, SDL_Event *event);
120 121
 int re_processkey_commandwait(re_t *re, SDL_Event *event);
121 122
 int re_processkey_commanddata(re_t *re, SDL_Event *event);
... ...
@@ -582,6 +583,78 @@ re_fixorigin_center(re_t *re)
582 583
         return(0);
583 584
 }
584 585
 
586
+int
587
+re_textinsert(re_t *re, char *text, int sizetext)
588
+{
589
+        long realend;
590
+        int at_end;
591
+        int nspaces;
592
+        long cursorpos;
593
+        long selstart,selend;
594
+        int fixsel;
595
+        char *ptr,*next;
596
+        int len;
597
+        int trimmed;
598
+        if(re==NULL || text==NULL || sizetext<=0)
599
+                return(-1); /* sanity check failed */
600
+        if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0
601
+          || redata_line_realend(re->data,cursorpos,&realend)==-1) {
602
+                return(-1); /* couldn't get current line info */
603
+        }
604
+        fixsel=0;
605
+        selstart=selend=0;
606
+        if(re->selactive
607
+          && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&selstart,NULL)==0
608
+          && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&selend,NULL)==0) {
609
+                fixsel=1;
610
+        }
611
+        at_end=(cursorpos==realend)?1:0;
612
+        for(nspaces=0;nspaces<sizetext && text[nspaces]==' ';nspaces++)
613
+                ;
614
+        if(nspaces>0 && nspaces==sizetext && at_end) {
615
+                /* instead of adding spaces at the end of the line, we move the cursor to the right */
616
+                re_moveleftright(re,nspaces);
617
+                return(0); /* no need to add spaces at the end of the line */
618
+        }
619
+        redata_undo_groupinit(re->data,NULL);
620
+        if(!(text[0]=='\n' && sizetext==1) && at_end) {
621
+                int col;
622
+                if(redata_pos2linecol(re->data,cursorpos,NULL,&col)==-1)
623
+                        return(-1); /* couldn't get line info */
624
+                if(redata_op_addn(re->data,cursorpos,' ',re->curcol-col,NULL)!=0)
625
+                        return(-1); /* couldn't add spaces up to current displayed pos */
626
+                /* increment cursorpos; spaces are 1 byte, so the number of columns advanced is the number of bytes advanced */
627
+                cursorpos+=re->curcol-col;
628
+        }
629
+        if(redata_op_add(re->data,cursorpos,text,sizetext,NULL)!=0)
630
+                return(-1); /* couldn't add requested text */
631
+        if(fixsel) {
632
+                if(cursorpos<=selstart)
633
+                        redata_pos2linecol(re->data,selstart+sizetext,&(re->sellinefrom),&(re->selcolfrom));
634
+                if(cursorpos<=selend)
635
+                        redata_pos2linecol(re->data,selend+sizetext,&(re->sellineto),&(re->selcolto));
636
+        }
637
+        for(ptr=text,next=memchr(text,'\n',sizetext);ptr!=NULL;ptr=(next!=NULL)?next+1:NULL,next=(ptr!=NULL)?memchr(ptr,'\n',sizetext-(ptr-text)):NULL) {
638
+                len=(next!=NULL)?(next-ptr):sizetext-(ptr-text);
639
+                re->curcol+=redata_generic_utf8len(ptr,len);
640
+                cursorpos+=len;
641
+                if(next!=NULL) {
642
+                        cursorpos++;
643
+                        if(re_rtrim(re,cursorpos-1,&trimmed)!=-1)
644
+                                cursorpos-=trimmed;
645
+                        re->curline++;
646
+                        re->curcol=0;
647
+                }
648
+        }
649
+        /* trim last line inserted */
650
+        if(redata_getchar(re->data,cursorpos)=='\n' && re_rtrim(re,cursorpos,&trimmed)!=-1)
651
+                cursorpos-=trimmed;
652
+        redata_undo_groupcommit(re->data,NULL);
653
+        re_fixorigin(re);
654
+        re->headerdirty=1;
655
+        re->contentsdirty=1;
656
+        return(0);
657
+}
585 658
 
586 659
 int
587 660
 re_processkey_editing(re_t *re, SDL_Event *event)
... ...
@@ -641,13 +714,6 @@ fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
641 714
         }
642 715
         /* special case: text editing event */
643 716
         if(event->type==SDL_TEXTINPUT) {
644
-                int len;
645
-                long realend;
646
-                int at_end;
647
-                int nspaces;
648
-                long cursorpos;
649
-                long selstart,selend;
650
-                int fixsel;
651 717
                 if(re->ignorenkeys>0) {
652 718
                         re->ignorenkeys--;
653 719
                         return(0); /* this is an already processed key, ignore it */
... ...
@@ -655,63 +721,7 @@ fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
655 721
 #if 0
656 722
 fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
657 723
 #endif
658
-                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0
659
-                  || redata_line_realend(re->data,cursorpos,&realend)==-1) {
660
-                        return(-1); /* couldn't get current line info */
661
-                }
662
-                fixsel=0;
663
-                selstart=selend=0;
664
-                if(re->selactive
665
-                  && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&selstart,NULL)==0
666
-                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&selend,NULL)==0) {
667
-                        fixsel=1;
668
-                }
669
-                at_end=(cursorpos==realend)?1:0;
670
-                for(nspaces=0;event->text.text[nspaces]==' ';nspaces++)
671
-                        ;
672
-                if(nspaces>0 && event->text.text[nspaces]=='\0' && at_end) {
673
-                        /* instead of adding spaces at the end of the line, we move the cursor to the right */
674
-                        re_moveleftright(re,nspaces);
675
-                        return(0); /* no need to add spaces at the end of the line */
676
-                }
677
-                redata_undo_groupinit(re->data,NULL);
678
-                if(!(event->text.text[0]=='\n' && event->text.text[1]=='\0') && at_end) {
679
-                        int col;
680
-                        if(redata_pos2linecol(re->data,cursorpos,NULL,&col)==-1)
681
-                                return(-1); /* couldn't get line info */
682
-                        if(redata_op_addn(re->data,cursorpos,' ',re->curcol-col,NULL)!=0)
683
-                                return(-1); /* couldn't add spaces up to current displayed pos */
684
-                        /* increment cursorpos; spaces are 1 byte, so the number of columns advanced is the number of bytes advanced */
685
-                        cursorpos+=re->curcol-col;
686
-                }
687
-                len=strlen(event->text.text);
688
-                if(redata_op_add(re->data,cursorpos,event->text.text,len,NULL)!=0)
689
-                        return(-1); /* couldn't add requested text */
690
-                if(fixsel) {
691
-                        if(cursorpos<=selstart)
692
-                                redata_pos2linecol(re->data,selstart+len,&(re->sellinefrom),&(re->selcolfrom));
693
-                        if(cursorpos<=selend)
694
-                                redata_pos2linecol(re->data,selend+len,&(re->sellineto),&(re->selcolto));
695
-                }
696
-                cursorpos+=len;
697
-                if(event->text.text[0]=='\n' && event->text.text[1]=='\0') {
698
-                        int trimmed;
699
-                        if(re_rtrim(re,cursorpos-len,&trimmed))
700
-                                cursorpos-=trimmed;
701
-#if 1
702
-#if 0
703
-fprintf(stderr,"SDL_TEXTINPUT: Insering newline\n");
704
-#endif
705
-#endif
706
-                        re->curline++;
707
-                        re->curcol=0;
708
-                } else {
709
-                        re->curcol+=redata_generic_utf8len(event->text.text,len);
710
-                }
711
-                redata_undo_groupcommit(re->data,NULL);
712
-                re_fixorigin(re);
713
-                re->headerdirty=1;
714
-                re->contentsdirty=1;
724
+                re_textinsert(re,event->text.text,strlen(event->text.text));
715 725
         }
716 726
 #if 0
717 727
         else if(event->type==SDL_TEXTEDITING) {
... ...
@@ -953,10 +963,13 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
953 963
                         re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
954 964
                         SDL_SetClipboardText(re->selectbuf);
955 965
                         if(is_cut) {
966
+                                int trimmed;
956 967
                                 redata_undo_groupinit(re->data,NULL);
957 968
                                 redata_op_del(re->data,frompos,topos-frompos,NULL);
958
-                                redata_undo_groupcommit(re->data,NULL);
959 969
                                 redata_pos2linecol(re->data,frompos,&(re->curline),&(re->curcol));
970
+                                if(redata_getchar(re->data,frompos)=='\n' && re_rtrim(re,frompos,&trimmed)!=-1)
971
+                                        frompos-=trimmed;
972
+                                redata_undo_groupcommit(re->data,NULL);
960 973
                                 re_fixorigin(re);
961 974
                                 re->headerdirty=1;
962 975
                         }
... ...
@@ -973,16 +986,11 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
973 986
                         re_sel_toggle(re);
974 987
                 if(SDL_HasClipboardText())
975 988
                         re_selectbuf_replace(re,SDL_GetClipboardText());
976
-                if(re->usedselectbuf>0) {
977
-                        redata_undo_groupinit(re->data,NULL);
978
-                        redata_op_add(re->data,cursorpos,re->selectbuf,re->usedselectbuf,NULL);
979
-                        redata_undo_groupcommit(re->data,NULL);
980
-                        cursorpos+=re->usedselectbuf;
981
-                        redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
982
-                        re_fixorigin(re);
983
-                        re->headerdirty=1;
984
-                        re->contentsdirty=1;
985
-                }
989
+#if 1
990
+fprintf(stderr,"SELECTBUF:\"%s\" len:%i\n",re->selectbuf,(int)strlen(re->selectbuf));
991
+#endif
992
+                if(re->usedselectbuf>0)
993
+                        re_textinsert(re, re->selectbuf,re->usedselectbuf);
986 994
                 re->ignorenkeys++;
987 995
         } else if(re->selactive && event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
988 996
                 re_addprint(re);
Browse code

bugfix: rearch&replace was not replacing the last occurrences if the new string was larger than the old string and the occurrence was close to the end of the selection

Dario Rodriguez authored on 25/04/2021 10:10:41
Showing 1 changed files
... ...
@@ -1263,6 +1263,7 @@ re_processcommand(re_t *re)
1263 1263
                   ;total++,oldpos=newpos+rlen) {
1264 1264
                         redata_op_del(re->data,newpos,slen,NULL);
1265 1265
                         redata_op_add(re->data,newpos,re->cachelastreplacewith,rlen,NULL);
1266
+                        endpos=endpos-slen+rlen;
1266 1267
                 }
1267 1268
                 redata_undo_groupcommit(re->data,NULL);
1268 1269
                 redata_pos2linecol(re->data,oldpos,&(re->curline),&(re->curcol));
Browse code

Make Shift+HOME/Shift+END change the selection accordingly

Dario Rodriguez authored on 25/04/2021 10:02:40
Showing 1 changed files
... ...
@@ -785,6 +785,7 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
785 785
         } else if(event->key.keysym.sym==SDLK_HOME || event->key.keysym.sym==SDLK_END) {
786 786
                 long newpos;
787 787
                 long cursorpos;
788
+                int oldcol=re->curcol,oldline=re->curline;
788 789
                 if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
789 790
                         return(0); /* error obtaining position */
790 791
                 if((event->key.keysym.sym==SDLK_HOME && redata_line_realstart(re->data,cursorpos,&newpos)==-1)
... ...
@@ -794,6 +795,9 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
794 795
                 cursorpos=newpos;
795 796
                 if(redata_pos2linecol(re->data,cursorpos,NULL,&(re->curcol))==-1)
796 797
                         return(-1); /* couldn't get col of current pos */;
798
+                if((SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
799
+                        re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_HOME)?-1:1);
800
+                }
797 801
                 re_fixorigin(re);
798 802
                 re->headerdirty=1;
799 803
                 re->contentsdirty=1;
Browse code

Workaround for some graphics drivers: disable partial updates for now (using partial updates showed flickering, supposedly from frames from double buffering)

Dario Rodriguez authored on 18/04/2021 18:50:39
Showing 1 changed files
... ...
@@ -223,6 +223,13 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
223 223
                                 }
224 224
                         }
225 225
                 }
226
+                /* workaround for some nvidia linux drivers, that show old data on partial updates */
227
+                if(re->headerdirty || re->contentsdirty || re->ui->rendererdirty) {
228
+                        re->headerdirty=1;
229
+                        re->contentsdirty=1;
230
+                        re->ui->rendererdirty=1;
231
+                }
232
+                /* end of fix */
226 233
                 if(re->headerdirty) {
227 234
                         if(re->command==NULL) {
228 235
 #if 0
Browse code

bugfix: was showing strange characters when a multibyte UTF-8 char crossed a chunk boundary; now behaves as expected (multibyte UTF-8 characters crossing a boundary display correctly)

Dario Rodriguez authored on 20/03/2021 01:53:12
Showing 1 changed files
... ...
@@ -1889,31 +1889,24 @@ re_drawcontents(re_t *re, printout_t *printout)
1889 1889
         int curline,curcol;
1890 1890
         int maxcol,maxrow;
1891 1891
         long pos,newpos;
1892
-        char *ptr;
1893
-        int len;
1894 1892
         int y,row,tmprow;
1895
-        char *curptr;
1896
-        int curptrlen;
1897
-        int has_nl;
1893
+        long cursorpos;
1898 1894
         int is_continuation;
1899
-        int tmpcol,availcol;
1900
-        int in_error;
1901
-        long realstart,realend;
1902
-        int drawn_cursor;
1903
-        hcolor_t *colors;
1895
+        printout_t fakeprintout;
1896
+        hcolor_t *colors,fakecolor;
1904 1897
         int ncolors;
1905
-        linecolor_t *linecolors;
1898
+        const char selcolornormal[]={"\xde\xcf\x7f\xff"};
1899
+        const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
1900
+        long realstart,realend;
1901
+        linecolor_t *linecolors,fakelinecolors;
1906 1902
         int nlinecolors;
1903
+        int drawn_cursor;
1907 1904
         int matchingpos;
1908 1905
         char matchingchar;
1909 1906
         int mline,mcol;
1910
-        long cursorpos;
1911
-        printout_t fakeprintout;
1912
-        const char *hint;
1913
-        const char selcolornormal[]={"\xde\xcf\x7f\xff"};
1914
-        const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
1915 1907
         if(re==NULL || (printout!=NULL && (printout->ui==NULL || printout->data==NULL)))
1916 1908
                 return(-1);
1909
+        /* init vars and clear screen */
1917 1910
         ui=re->ui;
1918 1911
         data=re->data;
1919 1912
         x0=re->x;
... ...
@@ -1950,6 +1943,7 @@ re_drawcontents(re_t *re, printout_t *printout)
1950 1943
         reui_fill(ui,x0,y0,w,h,"\xdf\xdf\xdf\xff");
1951 1944
         row=curline-originline;
1952 1945
         pos=cursorpos;
1946
+        /* get position/row/col of character at top left of screen */
1953 1947
         while(row>0 && pos>0) {
1954 1948
                 if(redata_line_rawinfo(data,pos,&newpos,NULL,NULL,&is_continuation)==-1)
1955 1949
                         return(-1);
... ...
@@ -1985,70 +1979,108 @@ re_drawcontents(re_t *re, printout_t *printout)
1985 1979
                                 if(x2>(x0))
1986 1980
                                         reui_fill(ui,x0,y0+row*ui->fontheight,x2-x0,ui->fontheight+1,selcolor);
1987 1981
                         }
1988
-
1989 1982
                 }
1990 1983
                 row=tmprow;
1991 1984
         }
1992 1985
         /* draw the lines */
1986
+        if((colors=redata_highlighter_getcolors(data,&ncolors))==NULL) {
1987
+                colors=&fakecolor;
1988
+                ncolors=1;
1989
+                memcpy(fakecolor.rgba,"\x00\x00\x00\xff",5);
1990
+        }
1993 1991
         drawn_cursor=0;
1994
-        colors=redata_highlighter_getcolors(data,&ncolors);
1995 1992
         matchingpos=-1;
1996 1993
         matchingchar='\0';
1997 1994
         for(y=y0;y<(y0+h);y+=ui->fontheight,row++) {
1995
+                int in_error;
1996
+                int availcol,tmpcol,len;
1997
+                char *lastcolor;
1998 1998
                 /* definition of vars for tracking linecolor usage */
1999 1999
                 int curlinecolor; /* current linecolor */
2000 2000
                 int usedlenlinecolor; /* number of bytes of current linecolor already drawn */
2001
-                /* end of definitions */
2002
-                if(redata_line_realstart(data,pos,&realstart)==-1 || redata_line_realend(data,pos,&realend)==-1) {
2001
+                /* get start/end of line */
2002
+                if(redata_line_realstart(data,pos,&realstart)==-1 || redata_line_realend(data,pos,&realend)==-1)
2003 2003
                         break; /* couldn't get real start/end */
2004
+                /* setup colors */
2005
+                if(colors==(&fakecolor) || (linecolors=redata_highlighter_getline(data,originline+row,&nlinecolors))==NULL) {
2006
+                        linecolors=&fakelinecolors;
2007
+                        fakelinecolors.len=1;
2008
+                        fakelinecolors.color=0;
2004 2009
                 }
2005
-                in_error=0;
2006
-                linecolors=(colors==NULL)?NULL:redata_highlighter_getline(data,originline+row,&nlinecolors);
2007 2010
                 curlinecolor=0;
2008 2011
                 usedlenlinecolor=0;
2012
+                lastcolor="\x00\x00\x00\xff";                      
2013
+                in_error=0;
2014
+                /* draw each part of this line */
2009 2015
                 for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(origincol+maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
2016
+                        int has_nl;
2017
+                        char *ptr;
2018
+                        int incompletestart,incompleteend,endreq;
2019
+                        int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */
2010 2020
                         if(redata_line_rawinfo(data,pos,&newpos,&ptr,&len,&is_continuation)==-1) {
2011 2021
                                 in_error=1;
2012 2022
                                 break; /* couldn't get this line part info */
2013 2023
                         }
2014 2024
                         has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
2015
-                        availcol=redata_generic_utf8len(ptr,len-has_nl);
2016
-#warning TODO: consider tabs
2017
-                        if(linecolors!=NULL) {
2018
-                                int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */
2019
-                                used=usedcol=0;
2020
-                                /* while the avail text is larger than the linecolor len */
2021
-                                while(curlinecolor<nlinecolors && (len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
2022
-                                        reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
2023
-                                        usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
2024
-                                        used+=linecolors[curlinecolor].len-usedlenlinecolor;
2025
-                                        curlinecolor++;
2026
-                                        usedlenlinecolor=0;
2027
-                                }
2028
-                                /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */
2029
-                                if(curlinecolor<nlinecolors && (len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) {
2030
-                                        reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used));
2031
-                                        usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-used));
2032
-                                        usedlenlinecolor+=(len-has_nl-used);
2033
-                                        used+=(len-has_nl-used);
2025
+                        availcol=redata_generic_utf8lenincomplete(ptr,len-has_nl,&incompletestart,&incompleteend,&endreq);
2026
+                        /* display the line */
2027
+                        used=incompletestart;
2028
+                        usedcol=0;
2029
+                        /* while the avail text is larger than the linecolor len */
2030
+                        while(curlinecolor<nlinecolors && (len-has_nl-incompleteend-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
2031
+                                lastcolor=colors[linecolors[curlinecolor].color].rgba;
2032
+                                reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
2033
+                                usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
2034
+                                used+=linecolors[curlinecolor].len-usedlenlinecolor;
2035
+                                curlinecolor++;
2036
+                                usedlenlinecolor=0;
2037
+                        }
2038
+                        /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */
2039
+                        if((len-has_nl-incompleteend-used)>0) {
2040
+                                if(curlinecolor<nlinecolors && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-incompleteend-used)) {
2041
+                                        lastcolor=colors[linecolors[curlinecolor].color].rgba;
2042
+                                        usedlenlinecolor+=(len-has_nl-incompleteend-used);
2043
+                                        if(usedlenlinecolor==linecolors[curlinecolor].len) {
2044
+                                                curlinecolor++;
2045
+                                                usedlenlinecolor=0;
2046
+                                        }
2034 2047
                                 }
2035
-                        } else {
2036
-                                reui_write(ui,x0+(tmpcol-origincol)*ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
2048
+                                reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,ptr+used,(len-has_nl-incompleteend-used));
2049
+                                usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-incompleteend-used));
2050
+                                used+=(len-has_nl-incompleteend-used);
2037 2051
                         }
2038
-                        if(printout==NULL && row==(curline-originline)) {
2039
-                                if(curcol>=tmpcol && curcol<(tmpcol+availcol)) {
2040
-                                        int utf8charlen;
2041
-                                        /* draw cursor */
2042
-                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
2043
-                                        drawn_cursor=1;
2044
-                                        curptr=redata_generic_utf8col(ptr,len-has_nl,curcol-tmpcol);
2045
-                                        curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
2046
-                                        utf8charlen=redata_generic_utf8charlen(curptr,curptrlen);
2047
-                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",curptr,utf8charlen);
2048
-                                        /* get matching braces/parens/anglebracket/curlybraces for highlighting */
2049
-                                        if(utf8charlen==1 && strchr("[]{}<>()",*curptr)!=NULL)
2050
-                                                matchingpos=re_getmatchingbracket(re,cursorpos,*curptr,&matchingchar);
2052
+                        /* if the last utf-8 char is broken into several blocks */
2053
+                        if(incompleteend>0) {
2054
+                                char broken[7];
2055
+                                int usedbroken;
2056
+                                usedbroken=0;
2057
+                                redata_getutf8char(re->data,newpos+len-has_nl-incompleteend,broken,sizeof(broken),&usedbroken);
2058
+                                /* write the just-recomposer character in the correct color */
2059
+                                if(curlinecolor<nlinecolors && (linecolors[curlinecolor].len-usedlenlinecolor)>=1) {
2060
+                                        lastcolor=colors[linecolors[curlinecolor].color].rgba;
2061
+                                        usedlenlinecolor+=1;
2062
+                                        if(usedlenlinecolor==linecolors[curlinecolor].len) {
2063
+                                                curlinecolor++;
2064
+                                                usedlenlinecolor=0;
2065
+                                        }
2051 2066
                                 }
2067
+                                reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,lastcolor,broken,usedbroken);
2068
+                                usedcol++;
2069
+                                availcol++;
2070
+                        }
2071
+                        /* draw cursor if applicable */
2072
+                        if(printout==NULL && row==(curline-originline) && curcol>=tmpcol && curcol<(tmpcol+availcol)) {
2073
+                                char cursorchar[7];
2074
+                                int usedcursorchar;
2075
+                                /* draw cursor */
2076
+                                reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
2077
+                                drawn_cursor=1;
2078
+                                usedcursorchar=0;
2079
+                                redata_getutf8char(re->data,cursorpos,cursorchar,sizeof(cursorchar),&usedcursorchar);
2080
+                                reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",cursorchar,usedcursorchar);
2081
+                                /* get matching braces/parens/anglebracket/curlybraces for highlighting */
2082
+                                if(usedcursorchar==1 && strchr("[]{}<>()",*cursorchar)!=NULL)
2083
+                                        matchingpos=re_getmatchingbracket(re,cursorpos,*cursorchar,&matchingchar);
2052 2084
                         }
2053 2085
                 }
2054 2086
                 if(printout==NULL && row==(curline-originline) && !drawn_cursor)
... ...
@@ -2056,7 +2088,6 @@ re_drawcontents(re_t *re, printout_t *printout)
2056 2088
                 if(in_error)
2057 2089
                         break;
2058 2090
                 pos=realend+1;
2059
-/*LONG LINE LEFT FOR DEBUGGING PURPOSES: reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));*/
2060 2091
         }
2061 2092
         /* highlight matching parens/brace/... if applicable */
2062 2093
         if(printout==NULL && matchingpos!=-1 && redata_pos2linecol(data,matchingpos,&mline,&mcol)!=-1) {
... ...
@@ -2078,14 +2109,14 @@ re_drawcontents(re_t *re, printout_t *printout)
2078 2109
                 else
2079 2110
                         reui_balloon(ui, '\0', x,y, fg, bg, &matchingchar,1);
2080 2111
         }
2081
-        /* display prototypes info if applicable */
2082 2112
         if(printout==NULL) {
2113
+                const char *hint;
2083 2114
                 hint=redata_prototypes_get(data, cursorpos);
2084 2115
                 if(hint!=NULL) {
2085
-                        if((curline-originline)>=(maxrow/2))
2116
+                        if((curline-originline)>=3)
2086 2117
                                 reui_balloon(ui, '\0', x0+w/2, y0+ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
2087 2118
                         else
2088
-                                reui_balloon(ui, '\0', x0+w/2, y0+h-ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *)hint,strlen(hint));
2119
+                                reui_balloon(ui, '\0', x0+w/2, y0+ui->fontheight*((curline-originline)*2+5)/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
2089 2120
                 }
2090 2121
         }
2091 2122
         /* all done */
Browse code

bugfix: selection was moving when inserting/deleting text before the selection

Dario Rodriguez authored on 12/03/2021 22:54:34
Showing 1 changed files
... ...
@@ -639,6 +639,8 @@ fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
639 639
                 int at_end;
640 640
                 int nspaces;
641 641
                 long cursorpos;
642
+                long selstart,selend;
643
+                int fixsel;
642 644
                 if(re->ignorenkeys>0) {
643 645
                         re->ignorenkeys--;
644 646
                         return(0); /* this is an already processed key, ignore it */
... ...
@@ -650,6 +652,13 @@ fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
650 652
                   || redata_line_realend(re->data,cursorpos,&realend)==-1) {
651 653
                         return(-1); /* couldn't get current line info */
652 654
                 }
655
+                fixsel=0;
656
+                selstart=selend=0;
657
+                if(re->selactive
658
+                  && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&selstart,NULL)==0
659
+                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&selend,NULL)==0) {
660
+                        fixsel=1;
661
+                }
653 662
                 at_end=(cursorpos==realend)?1:0;
654 663
                 for(nspaces=0;event->text.text[nspaces]==' ';nspaces++)
655 664
                         ;
... ...
@@ -671,6 +680,12 @@ fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
671 680
                 len=strlen(event->text.text);
672 681
                 if(redata_op_add(re->data,cursorpos,event->text.text,len,NULL)!=0)
673 682
                         return(-1); /* couldn't add requested text */
683
+                if(fixsel) {
684
+                        if(cursorpos<=selstart)
685
+                                redata_pos2linecol(re->data,selstart+len,&(re->sellinefrom),&(re->selcolfrom));
686
+                        if(cursorpos<=selend)
687
+                                redata_pos2linecol(re->data,selend+len,&(re->sellineto),&(re->selcolto));
688
+                }
674 689
                 cursorpos+=len;
675 690
                 if(event->text.text[0]=='\n' && event->text.text[1]=='\0') {
676 691
                         int trimmed;
... ...
@@ -777,12 +792,15 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
777 792
                 re->contentsdirty=1;
778 793
         } else if(event->key.keysym.sym==SDLK_BACKSPACE && (re->curline>0 || re->curcol>0)) {
779 794
                 int line,col;
780
-                long startpos,newpos,realstart,start;
795
+                long startpos,delpos,realstart,start;
796
+                long dellen;
781 797
                 char *ptr;
782 798
                 int len;
783 799
                 int trimmed;
784 800
                 int doneinc;
785 801
                 long cursorpos;
802
+                long selstart,selend;
803
+                int fixsel;
786 804
                 if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
787 805
 #if 0
788 806
 fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
... ...
@@ -797,27 +815,34 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
797 815
                 if(event!=&fakeevent)
798 816
                         redata_undo_groupinit(re->data,NULL);
799 817
                 /* delete the last character */
818
+                fixsel=0;
819
+                selstart=selend=0;
820
+                if(re->selactive
821
+                  && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&selstart,NULL)==0
822
+                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&selend,NULL)==0) {
823
+                        fixsel=1;
824
+                }           
800 825
                 if(col>0) {
801 826
                         if(redata_line_realstart(re->data,cursorpos,&realstart)==-1)
802 827
                                 return(-1); /* couldn't get line info */
803 828
                         /* get the start of the part to delete */
804 829
                         doneinc=0;
805
-                        for(ptr=NULL,len=0,start=0,newpos=cursorpos;doneinc!=1;) {
806
-                                if((newpos-1)<realstart)
830
+                        for(ptr=NULL,len=0,start=0,delpos=cursorpos;doneinc!=1;) {
831
+                                if((delpos-1)<realstart)
807 832
                                         break;
808
-                                newpos--;
809
-                                if(ptr==NULL || (start+len)<=newpos || newpos<start) {
810
-                                        if(redata_line_rawinfo(re->data,newpos,&start,&ptr,&len,NULL)==-1)
833
+                                delpos--;
834
+                                if(ptr==NULL || (start+len)<=delpos || delpos<start) {
835
+                                        if(redata_line_rawinfo(re->data,delpos,&start,&ptr,&len,NULL)==-1)
811 836
                                                 return(-1); /* couldn't get line data */
812 837
                                 }
813
-                                if(redata_generic_utf8isstartbyte(ptr[newpos-start]))
838
+                                if(redata_generic_utf8isstartbyte(ptr[delpos-start]))
814 839
                                         doneinc++;
815 840
                         }
816 841
                         /* delete */
817
-                        redata_op_del(re->data,newpos,cursorpos-newpos,NULL);
818
-                        cursorpos=newpos;
842
+                        dellen=cursorpos-delpos;
843
+                        redata_op_del(re->data,delpos,dellen,NULL);
844
+                        cursorpos=delpos;
819 845
                 } else {
820
-                        long delpos;
821 846
                         /* to make the code trivial, we're being lazy on '\n' deletion: we call ...rawinfo() for each byte in the multibyte utf-8 sequence */
822 847
                         for(delpos=cursorpos-1
823 848
                           ;delpos>0
... ...
@@ -825,10 +850,27 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
825 850
                                 if(redata_generic_utf8isstartbyte(ptr[delpos-startpos]))
826 851
                                         break;
827 852
                         }
828
-                        redata_op_del(re->data,delpos,cursorpos-delpos,NULL);
853
+                        dellen=cursorpos-delpos;
854
+                        redata_op_del(re->data,delpos,dellen,NULL);
829 855
                         cursorpos=delpos;
830 856
                 }
831 857
                 redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
858
+                if(fixsel) {
859
+                        if(delpos<=selstart) {
860
+                                /* if we deleted the start of selection, make the start of selection the cursorpos */
861
+                                if(selstart>=delpos && selstart<(delpos+dellen))
862
+                                        redata_pos2linecol(re->data,cursorpos,&(re->sellinefrom),&(re->selcolfrom));
863
+                                else
864
+                                        redata_pos2linecol(re->data,selstart-dellen,&(re->sellinefrom),&(re->selcolfrom));
865
+                        }
866
+                        if(delpos<=selend) {
867
+                                /* if we deleted the end of selection, make the start of selection the cursorpos */
868
+                                if(selend>=delpos && selend<(delpos+dellen))
869
+                                        redata_pos2linecol(re->data,cursorpos,&(re->sellineto),&(re->selcolto));
870
+                                else
871
+                                        redata_pos2linecol(re->data,selend-dellen,&(re->sellineto),&(re->selcolto));
872
+                        }
873
+                }
832 874
                 /* if cursor at end of line and there are trailing spaces at the end, delete them too */
833 875
                 if(re_rtrim(re,cursorpos,&trimmed))
834 876
                         cursorpos-=trimmed;
Browse code

Disable unnedded plugins in viewonly mode

Dario Rodriguez authored on 21/01/2021 21:21:23
Showing 1 changed files
... ...
@@ -109,7 +109,7 @@ static void sighandler_sigpipe(int num);
109 109
 static int mystricmp(const char *s1, const char *s2);
110 110
 
111 111
 
112
-re_t *re_init(void);
112
+re_t *re_init(int viewonly);
113 113
 void re_free(re_t *re);
114 114
 int re_setuidata(re_t *re);
115 115
 
... ...
@@ -152,17 +152,19 @@ main(int argc, char *argv[])
152 152
         int flag_had_events;
153 153
         time_t lastidle,now;
154 154
         int load_pending;
155
+        int viewonly;
155 156
         int i,l;
156 157
         if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
157 158
                 fprintf(stderr,"Syntax: %s filename\n",argv[0]);
158 159
                 return(1);
159 160
         }
160
-        if((re=re_init())==NULL) {
161
+        viewonly=0;
162
+        if((i=strlen(argv[0]))>=(l=strlen(VIEWONLYPROGNAME)) && strcmp(argv[0]+i-l,VIEWONLYPROGNAME)==0)
163
+                viewonly=1;
164
+        if((re=re_init(viewonly))==NULL) {
161 165
                 fprintf(stderr,"ERROR: couldn't init structs.\n");
162 166
                 return(2);
163 167
         }
164
-        if((i=strlen(argv[0]))>=(l=strlen(VIEWONLYPROGNAME)) && strcmp(argv[0]+i-l,VIEWONLYPROGNAME)==0)
165
-                re->viewonly=1;
166 168
         if((ssel=sselect_init())==NULL) {
167 169
                 fprintf(stderr,"ERROR: couln't init internal data.\n");
168 170
                 re_free(re),re=NULL;
... ...
@@ -456,17 +458,24 @@ mystricmp(const char *s1, const char *s2)
456 458
 }
457 459
 
458 460
 re_t *
459
-re_init(void)
461
+re_init(int viewonly)
460 462
 {
461 463
         re_t *re;
462 464
         if((re=malloc(sizeof(re_t)))==NULL)
463 465
                 return(NULL); /* insuf. mem. */
464 466
         memset(re,0,sizeof(re_t));
465
-        if((re->data=redata_init(
466
-          redata_unsaved_register,
467
-          redata_highlighter_register,
468
-          redata_prototypes_register,
469
-          NULL))==NULL) {
467
+        if(viewonly==0) {
468
+                re->data=redata_init(
469
+                  redata_unsaved_register,
470
+                  redata_highlighter_register,
471
+                  redata_prototypes_register,
472
+                  NULL);
473
+        } else { /* viewonly */
474
+               re->data=redata_init(
475
+                  redata_highlighter_register,
476
+                  NULL);
477
+        }
478
+        if(re->data==NULL) {
470 479
                 re_free(re),re=NULL;
471 480
                 return(NULL); /* insuf. mem. */
472 481
         }
... ...
@@ -475,6 +484,7 @@ re_init(void)
475 484
                 re_free(re),re=NULL;
476 485
                 return(NULL); /* video init error */
477 486
         }
487
+        re->viewonly=(viewonly!=0)?1:0;
478 488
         return(re);
479 489
 }
480 490
 
Browse code

Add viewonly support (enabled if the executable name ends with 'review')

Dario Rodriguez authored on 21/01/2021 21:14:04
Showing 1 changed files
... ...
@@ -31,6 +31,8 @@
31 31
 #define SELECTBUFBLOCK 16384
32 32
 #define SIZEBLOCKPRINTS 32
33 33
 
34
+#define VIEWONLYPROGNAME "review"
35
+
34 36
 #define COMMAND_WARNING "(!)"
35 37
 #define COMMAND_INFO "(i)"
36 38
 #define COMMAND_GOTOLINE "Go to line:"
... ...
@@ -68,6 +70,7 @@ typedef struct print_t {
68 70
 typedef struct re_t {
69 71
         redata_t *data;
70 72
         reui_t *ui;
73
+        int viewonly;
71 74
         int flag_newfile;
72 75
         char filename[PATH_MAX];
73 76
         int x, y, w, h; // contents rect
... ...
@@ -149,7 +152,7 @@ main(int argc, char *argv[])
149 152
         int flag_had_events;
150 153
         time_t lastidle,now;
151 154
         int load_pending;
152
-        int i;
155
+        int i,l;
153 156
         if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
154 157
                 fprintf(stderr,"Syntax: %s filename\n",argv[0]);
155 158
                 return(1);
... ...
@@ -158,6 +161,8 @@ main(int argc, char *argv[])
158 161
                 fprintf(stderr,"ERROR: couldn't init structs.\n");
159 162
                 return(2);
160 163
         }
164
+        if((i=strlen(argv[0]))>=(l=strlen(VIEWONLYPROGNAME)) && strcmp(argv[0]+i-l,VIEWONLYPROGNAME)==0)
165
+                re->viewonly=1;
161 166
         if((ssel=sselect_init())==NULL) {
162 167
                 fprintf(stderr,"ERROR: couln't init internal data.\n");
163 168
                 re_free(re),re=NULL;
... ...
@@ -323,6 +328,28 @@ fprintf(stderr,"RENDER\n");
323 328
                                 case SDL_KEYDOWN:
324 329
                                 case SDL_TEXTINPUT:
325 330
                                 case SDL_TEXTEDITING:
331
+                                        if(re->viewonly && (event.type==SDL_TEXTINPUT || event.type==SDL_TEXTEDITING))
332
+                                                break;
333
+                                        if(re->viewonly && event.type==SDL_KEYDOWN) {
334
+                                                if(event.key.keysym.sym==SDLK_ESCAPE) {
335
+                                                        do_exit=1;
336
+                                                } if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP) {
337
+                                                        if(event.key.keysym.sym==SDLK_UP && re->originline==0)
338
+                                                                break; /* nothing to do, at top */
339
+                                                        re->originline+=((event.key.keysym.sym==SDLK_UP)?-1:1);
340
+                                                        re->curline+=((event.key.keysym.sym==SDLK_UP)?-1:1);
341
+                                                        re->headerdirty=1;
342
+                                                        re->contentsdirty=1;
343
+                                                } else if(event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT) {
344
+                                                        if(event.key.keysym.sym==SDLK_LEFT && re->origincol==0)
345
+                                                                break; /* nothing to do, at top */
346
+                                                        re->origincol+=((event.key.keysym.sym==SDLK_LEFT)?-1:1)*8;
347
+                                                        re->origincol=(re->origincol<0)?0:re->origincol;
348
+                                                        re->headerdirty=1;
349
+                                                        re->contentsdirty=1;
350
+                                                }
351
+                                                break;
352
+                                        }
326 353
                                         if(re->command==NULL || strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_INFO)==0)
327 354
                                                 re_processkey_editing(re,&event);
328 355
                                         else if(re->command[0]=='\0')
... ...
@@ -708,7 +735,7 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
708 735
                                 re->contentsdirty=1;
709 736
                         }
710 737
                 }
711
-        } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
738
+        } else if((event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT)) {
712 739
                 int oldcol=re->curcol,oldline=re->curline;
713 740
                 if(re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
714 741
                         re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
... ...
@@ -1829,6 +1856,7 @@ re_drawcontents(re_t *re, printout_t *printout)
1829 1856
         char matchingchar;
1830 1857
         int mline,mcol;
1831 1858
         long cursorpos;
1859
+        printout_t fakeprintout;
1832 1860
         const char *hint;
1833 1861
         const char selcolornormal[]={"\xde\xcf\x7f\xff"};
1834 1862
         const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
... ...
@@ -1846,7 +1874,14 @@ re_drawcontents(re_t *re, printout_t *printout)
1846 1874
         curcol=re->curcol;
1847 1875
         maxcol=re->maxcol;
1848 1876
         maxrow=re->maxrow;
1849
-        if(printout!=NULL) {
1877
+        if(printout==NULL && re->viewonly==1) {
1878
+                memset(&fakeprintout,0,sizeof(printout_t));
1879
+                fakeprintout.ui=re->ui;
1880
+                fakeprintout.data=re->data;
1881
+                fakeprintout.originline=re->originline;
1882
+                fakeprintout.origincol=re->origincol;
1883
+                printout=&fakeprintout;
1884
+        } else if(printout!=NULL) {
1850 1885
                 ui=printout->ui;
1851 1886
                 data=printout->data;
1852 1887
                 x0=0;
... ...
@@ -2002,7 +2037,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2002 2037
                 }
2003 2038
         }
2004 2039
         /* all done */
2005
-        if(printout==NULL) {
2040
+        if(printout==NULL || printout==&fakeprintout) {
2006 2041
                 re->contentsdirty=0;
2007 2042
                 ui->rendererdirty=1;
2008 2043
         } else {
Browse code

Simple Up/down/left/right scrolling for the printouts

Dario Rodriguez authored on 21/01/2021 20:46:25
Showing 1 changed files
... ...
@@ -266,6 +266,7 @@ fprintf(stderr,"RENDER\n");
266 266
                           || (event.type==SDL_TEXTEDITING && (windowID=event.edit.windowID)!=SDL_GetWindowID(re->ui->win))
267 267
                           || (event.type==SDL_TEXTINPUT && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
268 268
                           ) {
269
+                                printout_t *printout;
269 270
                                 for(i=0;i<re->sizeprints;i++) {
270 271
                                         if(re->prints[i].ui!=NULL
271 272
                                           && windowID==SDL_GetWindowID(re->prints[i].ui->win)) {
... ...
@@ -274,16 +275,17 @@ fprintf(stderr,"RENDER\n");
274 275
                                 }
275 276
                                 if(i>=re->sizeprints)
276 277
                                         continue; /* unknown window */
278
+                                printout=re->prints+i;
277 279
                                 switch(event.type) {
278 280
                                         case SDL_WINDOWEVENT:
279 281
                                                 if(event.window.event==SDL_WINDOWEVENT_SHOWN
280 282
                                                   || event.window.event==SDL_WINDOWEVENT_EXPOSED) {
281
-                                                        re->prints[i].dirty=1;
283
+                                                        printout->dirty=1;
282 284
                                                 } else if((event.window.event==SDL_WINDOWEVENT_RESIZED
283 285
                                                   || event.window.event==SDL_WINDOWEVENT_SIZE_CHANGED)
284
-                                                  && (event.window.data1!=re->prints[i].ui->w || event.window.data2!=re->prints[i].ui->h)) {
285
-                                                        reui_resize(re->prints[i].ui,event.window.data1,event.window.data2);
286
-                                                        re->prints[i].dirty=1;
286
+                                                  && (event.window.data1!=printout->ui->w || event.window.data2!=printout->ui->h)) {
287
+                                                        reui_resize(printout->ui,event.window.data1,event.window.data2);
288
+                                                        printout->dirty=1;
287 289
                                                 } else if(event.window.event==SDL_WINDOWEVENT_CLOSE) {
288 290
                                                         re_delprint(re,i);
289 291
                                                 }
... ...
@@ -291,6 +293,17 @@ fprintf(stderr,"RENDER\n");
291 293
                                         case SDL_KEYDOWN:
292 294
                                                 if(event.key.keysym.sym==SDLK_ESCAPE) {
293 295
                                                         re_delprint(re,i);
296
+                                                } else if(event.key.keysym.sym==SDLK_DOWN || event.key.keysym.sym==SDLK_UP) {
297
+                                                        if(event.key.keysym.sym==SDLK_UP && printout->originline==0)
298
+                                                                break; /* nothing to do, at top */
299
+                                                        printout->originline+=((event.key.keysym.sym==SDLK_UP)?-1:1);
300
+                                                        printout->dirty=1;
301
+                                                } else if(event.key.keysym.sym==SDLK_LEFT || event.key.keysym.sym==SDLK_RIGHT) {
302
+                                                        if(event.key.keysym.sym==SDLK_LEFT && printout->origincol==0)
303
+                                                                break; /* nothing to do, at top */
304
+                                                        printout->origincol+=((event.key.keysym.sym==SDLK_LEFT)?-1:1)*8;
305
+                                                        printout->origincol=(printout->origincol<0)?0:printout->origincol;
306
+                                                        printout->dirty=1;
294 307
                                                 }
295 308
                                                 break;
296 309
                                 }
... ...
@@ -1861,7 +1874,7 @@ re_drawcontents(re_t *re, printout_t *printout)
1861 1874
         if(printout==NULL) {
1862 1875
                 reui_fill(ui,x0,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
1863 1876
         } else {
1864
-                for(y=y0;y<(y0+h);y+=ui->fontheight*2)
1877
+                for(y=y0+(printout->originline%2)*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
1865 1878
                         reui_fill(ui,x0,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
1866 1879
         }
1867 1880
         /* highlight the selection */
Browse code

fix: printouts should not have cursor, so don't draw cursor on printout windows

Dario Rodriguez authored on 15/01/2021 22:26:54
Showing 1 changed files
... ...
@@ -1935,7 +1935,7 @@ re_drawcontents(re_t *re, printout_t *printout)
1935 1935
                         } else {
1936 1936
                                 reui_write(ui,x0+(tmpcol-origincol)*ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
1937 1937
                         }
1938
-                        if(row==(curline-originline)) {
1938
+                        if(printout==NULL && row==(curline-originline)) {
1939 1939
                                 if(curcol>=tmpcol && curcol<(tmpcol+availcol)) {
1940 1940
                                         int utf8charlen;
1941 1941
                                         /* draw cursor */
... ...
@@ -1951,7 +1951,7 @@ re_drawcontents(re_t *re, printout_t *printout)
1951 1951
                                 }
1952 1952
                         }
1953 1953
                 }
1954
-                if(row==(curline-originline) && !drawn_cursor)
1954
+                if(printout==NULL && row==(curline-originline) && !drawn_cursor)
1955 1955
                         reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
1956 1956
                 if(in_error)
1957 1957
                         break;
Browse code

Add print selection to new window with Control+P, close that window with ESC

Dario Rodriguez authored on 15/01/2021 22:11:33
Showing 1 changed files
... ...
@@ -29,6 +29,7 @@
29 29
 #define COMMANDBUFSIZE 1024
30 30
 #define DEFAULTFONTHEIGHT 14
31 31
 #define SELECTBUFBLOCK 16384
32
+#define SIZEBLOCKPRINTS 32
32 33
 
33 34
 #define COMMAND_WARNING "(!)"
34 35
 #define COMMAND_INFO "(i)"
... ...
@@ -56,6 +57,14 @@
56 57
 #define COLOR_INFOFG "\xee\xee\x46\xff"
57 58
 #define COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
58 59
 
60
+typedef struct print_t {
61
+        reui_t *ui;
62
+        redata_t *data;
63
+        int originline;
64
+        int origincol;
65
+        int dirty;
66
+} printout_t;
67
+
59 68
 typedef struct re_t {
60 69
         redata_t *data;
61 70
         reui_t *ui;
... ...
@@ -82,6 +91,9 @@ typedef struct re_t {
82 91
         question_t *question;
83 92
         int showingwarning;
84 93
         int ignorenkeys;
94
+        int sizeprints;
95
+        int usedprints;
96
+        printout_t *prints;
85 97
 } re_t;
86 98
 
87 99
 volatile int flag_sigint;
... ...
@@ -119,11 +131,13 @@ int re_sel_lincolisend(re_t *re, int line, int col);
119 131
 int re_selectbuf_resize(re_t *re,long size);
120 132
 int re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces);
121 133
 int re_selectbuf_replace(re_t *re,char *newdata);
134
+int re_addprint(re_t *re);
135
+int re_delprint(re_t *re, int nprint);
122 136
 int re_rtrim(re_t *re, long curpos, int *trimmed);
123 137
 long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
124 138
 int re_drawheader_editing(re_t *re);
125 139
 int re_drawheader_command(re_t *re);
126
-int re_drawcontents(re_t *re);
140
+int re_drawcontents(re_t *re, printout_t *printout);
127 141
 
128 142
 int
129 143
 main(int argc, char *argv[])
... ...
@@ -135,6 +149,7 @@ main(int argc, char *argv[])
135 149
         int flag_had_events;
136 150
         time_t lastidle,now;
137 151
         int load_pending;
152
+        int i;
138 153
         if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
139 154
                 fprintf(stderr,"Syntax: %s filename\n",argv[0]);
140 155
                 return(1);
... ...
@@ -224,18 +239,64 @@ fprintf(stderr,"REDRAW Header (command)\n");
224 239
                         }
225 240
                 }
226 241
                 if(re->contentsdirty)
227
-                        re_drawcontents(re);
242
+                        re_drawcontents(re,NULL);
228 243
                 if(re->ui->rendererdirty) {
229 244
 #if 0
230 245
 fprintf(stderr,"RENDER\n");
231 246
 #endif
232 247
                         reui_present(re->ui);
233 248
                 }
249
+                for(i=0;i<re->sizeprints;i++) {
250
+                        if(re->prints[i].ui==NULL)
251
+                                continue;
252
+                        if(re->prints[i].dirty)
253
+                                re_drawcontents(re,re->prints+i);
254
+                        if(re->prints[i].ui->rendererdirty)
255
+                                reui_present(re->prints[i].ui);
256
+                }
234 257
                 sselect_wait(ssel,(flag_had_events)?10:100);
235 258
                 flag_had_events=(flag_had_events>0)?flag_had_events-1:0;
236 259
                 SDL_PumpEvents();
237 260
                 while(SDL_PeepEvents(&event,1,SDL_GETEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT)>0) {
261
+                        Uint32 windowID;
238 262
                         flag_had_events=10;
263
+                        /* Process printout events */
264
+                        if((event.type==SDL_WINDOWEVENT && (windowID=event.window.windowID)!=SDL_GetWindowID(re->ui->win))
265
+                          || (event.type==SDL_KEYDOWN && (windowID=event.key.windowID)!=SDL_GetWindowID(re->ui->win))
266
+                          || (event.type==SDL_TEXTEDITING && (windowID=event.edit.windowID)!=SDL_GetWindowID(re->ui->win))
267
+                          || (event.type==SDL_TEXTINPUT && (windowID=event.text.windowID)!=SDL_GetWindowID(re->ui->win))
268
+                          ) {
269
+                                for(i=0;i<re->sizeprints;i++) {
270
+                                        if(re->prints[i].ui!=NULL
271
+                                          && windowID==SDL_GetWindowID(re->prints[i].ui->win)) {
272
+                                                break;
273
+                                        }
274
+                                }
275
+                                if(i>=re->sizeprints)
276
+                                        continue; /* unknown window */
277
+                                switch(event.type) {
278
+                                        case SDL_WINDOWEVENT:
279
+                                                if(event.window.event==SDL_WINDOWEVENT_SHOWN
280
+                                                  || event.window.event==SDL_WINDOWEVENT_EXPOSED) {
281
+                                                        re->prints[i].dirty=1;
282
+                                                } else if((event.window.event==SDL_WINDOWEVENT_RESIZED
283
+                                                  || event.window.event==SDL_WINDOWEVENT_SIZE_CHANGED)
284
+                                                  && (event.window.data1!=re->prints[i].ui->w || event.window.data2!=re->prints[i].ui->h)) {
285
+                                                        reui_resize(re->prints[i].ui,event.window.data1,event.window.data2);
286
+                                                        re->prints[i].dirty=1;
287
+                                                } else if(event.window.event==SDL_WINDOWEVENT_CLOSE) {
288
+                                                        re_delprint(re,i);
289
+                                                }
290
+                                                break;
291
+                                        case SDL_KEYDOWN:
292
+                                                if(event.key.keysym.sym==SDLK_ESCAPE) {
293
+                                                        re_delprint(re,i);
294
+                                                }
295
+                                                break;
296
+                                }
297
+                                continue; /* only want window events from printouts */
298
+                        }
299
+                        /* process main window events */
239 300
                         switch(event.type) {
240 301
                                 case SDL_QUIT:
241 302
                                         if(redata_needs_saving(re->data)) {
... ...
@@ -370,7 +431,7 @@ re_init(void)
370 431
                 return(NULL); /* insuf. mem. */
371 432
         }
372 433
         re->fontheightpercent=100;
373
-        if((re->ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100))==NULL) {
434
+        if((re->ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,NULL))==NULL) {
374 435
                 re_free(re),re=NULL;
375 436
                 return(NULL); /* video init error */
376 437
         }
... ...
@@ -380,8 +441,15 @@ re_init(void)
380 441
 void
381 442
 re_free(re_t *re)
382 443
 {
444
+        int i;
383 445
         if(re==NULL)
384 446
                 return; /* all done */
447
+        for(i=0;i<re->sizeprints;i++) {
448
+                if(re->prints[i].ui!=NULL)
449
+                        re_delprint(re,i);
450
+        }
451
+        if(re->prints!=NULL)
452
+                free(re->prints),re->prints=NULL,re->sizeprints=re->usedprints=0;
385 453
         if(re->ui!=NULL)
386 454
                 reui_free(re->ui),re->ui=NULL;
387 455
         if(re->data!=NULL)
... ...
@@ -813,6 +881,8 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
813 881
                         re->contentsdirty=1;
814 882
                 }
815 883
                 re->ignorenkeys++;
884
+        } else if(re->selactive && event->key.keysym.sym==SDLK_p && (SDL_GetModState()&KMOD_CTRL)!=0) {
885
+                re_addprint(re);
816 886
         }
817 887
         return(0);
818 888
 }
... ...
@@ -1490,6 +1560,61 @@ re_selectbuf_replace(re_t *re,char *newdata)
1490 1560
         return(0);
1491 1561
 }
1492 1562
 
1563
+int
1564
+re_addprint(re_t *re)
1565
+{
1566
+        int i;
1567
+        long frompos,topos;
1568
+        int coldone;
1569
+        if(re==NULL || re->selactive==0)
1570
+                return(-1);
1571
+        /* ensure space for the new printout */
1572
+        if(re->usedprints==re->sizeprints) {
1573
+                printout_t *newprints;
1574
+                if((newprints=realloc(re->prints,sizeof(printout_t)*(re->sizeprints+SIZEBLOCKPRINTS)))==NULL)
1575
+                        return(-1); /* insuf. mem. */
1576
+                re->prints=newprints;
1577
+                memset(re->prints+re->sizeprints,0,sizeof(printout_t)*SIZEBLOCKPRINTS);
1578
+                re->sizeprints+=SIZEBLOCKPRINTS;
1579
+        }
1580
+        for(i=0;i<re->sizeprints;i++) {
1581
+                if(re->prints[i].ui==NULL)
1582
+                        break;
1583
+        }
1584
+        if(i>=re->sizeprints)
1585
+                return(-1); /* INTERNAL ERROR */
1586
+        /* setup window */
1587
+        if((re->prints[i].ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100,re->ui))==NULL)
1588
+                return(-1); /* couldn't init window */
1589
+        if((re->prints[i].data=redata_init(redata_highlighter_register,NULL))==NULL) {
1590
+                reui_free(re->prints[i].ui),re->prints[i].ui=NULL;
1591
+                return(-1); /* couldn't init data store */
1592
+        }
1593
+        re->usedprints++;
1594
+        /* copy contents (and set clipboard contents and unselect)*/
1595
+        if(redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
1596
+          && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
1597
+                re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
1598
+                redata_op_add(re->prints[i].data,0,re->selectbuf,strlen(re->selectbuf),NULL);
1599
+                SDL_SetClipboardText(re->selectbuf);
1600
+                re_sel_toggle(re);
1601
+                re->contentsdirty=1;
1602
+        }
1603
+        re->prints[i].dirty=1;
1604
+        return(0);
1605
+}
1606
+
1607
+int
1608
+re_delprint(re_t *re, int nprint)
1609
+{
1610
+        if(re==NULL || nprint<0 || nprint>re->sizeprints || re->prints[nprint].ui==NULL)
1611
+                return(-1);
1612
+        reui_free(re->prints[nprint].ui),re->prints[nprint].ui=NULL;
1613
+        if(re->prints[nprint].data!=NULL)
1614
+                redata_free(re->prints[nprint].data),re->prints[nprint].data=NULL;
1615
+        re->usedprints--;
1616
+        return(0);
1617
+}
1493 1618
 
1494 1619
 int
1495 1620
 re_rtrim(re_t *re, long curpos, int *trimmed)
... ...
@@ -1663,8 +1788,14 @@ re_drawheader_command(re_t *re)
1663 1788
 
1664 1789
 
1665 1790
 int
1666
-re_drawcontents(re_t *re)
1791
+re_drawcontents(re_t *re, printout_t *printout)
1667 1792
 {
1793
+        reui_t *ui;
1794
+        redata_t *data;
1795
+        int x0,y0,w,h;
1796
+        int originline,origincol;
1797
+        int curline,curcol;
1798
+        int maxcol,maxrow;
1668 1799
         long pos,newpos;
1669 1800
         char *ptr;
1670 1801
         int len;
... ...
@@ -1688,42 +1819,71 @@ re_drawcontents(re_t *re)
1688 1819
         const char *hint;
1689 1820
         const char selcolornormal[]={"\xde\xcf\x7f\xff"};
1690 1821
         const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
1691
-        if(re==NULL)
1822
+        if(re==NULL || (printout!=NULL && (printout->ui==NULL || printout->data==NULL)))
1692 1823
                 return(-1);
1693
-        if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1824
+        ui=re->ui;
1825
+        data=re->data;
1826
+        x0=re->x;
1827
+        y0=re->y;
1828
+        w=re->w;
1829
+        h=re->h;
1830
+        originline=re->originline;
1831
+        origincol=re->origincol;
1832
+        curline=re->curline;
1833
+        curcol=re->curcol;
1834
+        maxcol=re->maxcol;
1835
+        maxrow=re->maxrow;
1836
+        if(printout!=NULL) {
1837
+                ui=printout->ui;
1838
+                data=printout->data;
1839
+                x0=0;
1840
+                y0=0;
1841
+                w=ui->w;
1842
+                h=ui->h;
1843
+                originline=curline=printout->originline;
1844
+                origincol=curcol=printout->origincol;
1845
+                maxcol=w/ui->fontwidth-1;
1846
+                maxrow=h/ui->fontheight-1;
1847
+        }
1848
+        if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
1694 1849
                 return(0); /* error obtaining position */
1695
-        reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
1696
-        row=re->curline-re->originline;
1850
+        reui_fill(ui,x0,y0,w,h,"\xdf\xdf\xdf\xff");
1851
+        row=curline-originline;
1697 1852
         pos=cursorpos;
1698 1853
         while(row>0 && pos>0) {
1699
-                if(redata_line_rawinfo(re->data,pos,&newpos,NULL,NULL,&is_continuation)==-1)
1854
+                if(redata_line_rawinfo(data,pos,&newpos,NULL,NULL,&is_continuation)==-1)
1700 1855
                         return(-1);
1701 1856
                 pos=(newpos>0)?newpos-1:0;
1702 1857
                 if(!is_continuation)
1703 1858
                         row--;
1704 1859
         }
1705
-        /* highlight current line */
1706
-        reui_fill(re->ui,re->x,re->y+(re->curline-re->originline)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
1860
+        /* highlight current line (in printouts, highlight alternating lines) */
1861
+        if(printout==NULL) {
1862
+                reui_fill(ui,x0,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
1863
+        } else {
1864
+                for(y=y0;y<(y0+h);y+=ui->fontheight*2)
1865
+                        reui_fill(ui,x0,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
1866
+        }
1707 1867
         /* highlight the selection */
1708
-        if(re->selactive) {
1868
+        if(printout==NULL && re->selactive) {
1709 1869
                 const char *selcolor;
1710 1870
                 tmprow=row;
1711
-                for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1712
-                        selcolor=(row==(re->curline-re->originline))?selcolorcurline:selcolornormal;
1713
-                        if((re->originline+row)==re->sellinefrom && (re->originline+row)==re->sellineto) {
1714
-                                reui_fill(re->ui,re->x+(re->selcolfrom-re->origincol)*re->ui->fontwidth,re->y+row*re->ui->fontheight,(re->selcolto-re->selcolfrom)*re->ui->fontwidth,re->ui->fontheight+1,selcolor);
1715
-                        } else if((re->originline+row)==re->sellinefrom) {
1871
+                for(y=y0;y<(y0+h);y+=ui->fontheight,row++) {
1872
+                        selcolor=(row==(curline-originline))?selcolorcurline:selcolornormal;
1873
+                        if((originline+row)==re->sellinefrom && (originline+row)==re->sellineto) {
1874
+                                reui_fill(ui,x0+(re->selcolfrom-origincol)*ui->fontwidth,y0+row*ui->fontheight,(re->selcolto-re->selcolfrom)*ui->fontwidth,ui->fontheight+1,selcolor);
1875
+                        } else if((originline+row)==re->sellinefrom) {
1716 1876
                                 int x1;
1717
-                                x1=re->x+(re->selcolfrom-re->origincol)*re->ui->fontwidth;
1718
-                                if(x1<(re->x+re->w))
1719
-                                        reui_fill(re->ui,x1,re->y+row*re->ui->fontheight,re->w-x1,re->ui->fontheight+1,selcolor);
1720
-                        } else if((re->originline+row)>re->sellinefrom && (re->originline+row)<re->sellineto) {
1721
-                                reui_fill(re->ui,re->x,re->y+row*re->ui->fontheight,re->w,re->ui->fontheight+1,selcolor);
1722
-                        } else if((re->originline+row)==re->sellineto) {
1877
+                                x1=x0+(re->selcolfrom-origincol)*ui->fontwidth;
1878
+                                if(x1<(x0+w))
1879
+                                        reui_fill(ui,x1,y0+row*ui->fontheight,w-x1,ui->fontheight+1,selcolor);
1880
+                        } else if((originline+row)>re->sellinefrom && (originline+row)<re->sellineto) {
1881
+                                reui_fill(ui,x0,y0+row*ui->fontheight,w,ui->fontheight+1,selcolor);
1882
+                        } else if((originline+row)==re->sellineto) {
1723 1883
                                 int x2;
1724
-                                x2=re->x+(re->selcolto-re->origincol)*re->ui->fontwidth;
1725
-                                if(x2>(re->x))
1726
-                                        reui_fill(re->ui,re->x,re->y+row*re->ui->fontheight,x2-re->x,re->ui->fontheight+1,selcolor);
1884
+                                x2=x0+(re->selcolto-origincol)*ui->fontwidth;
1885
+                                if(x2>(x0))
1886
+                                        reui_fill(ui,x0,y0+row*ui->fontheight,x2-x0,ui->fontheight+1,selcolor);
1727 1887
                         }
1728 1888
 
1729 1889
                 }
... ...
@@ -1731,23 +1891,23 @@ re_drawcontents(re_t *re)
1731 1891
         }
1732 1892
         /* draw the lines */
1733 1893
         drawn_cursor=0;
1734
-        colors=redata_highlighter_getcolors(re->data,&ncolors);
1894
+        colors=redata_highlighter_getcolors(data,&ncolors);
1735 1895
         matchingpos=-1;
1736 1896
         matchingchar='\0';
1737
-        for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1897
+        for(y=y0;y<(y0+h);y+=ui->fontheight,row++) {
1738 1898
                 /* definition of vars for tracking linecolor usage */
1739 1899
                 int curlinecolor; /* current linecolor */
1740 1900
                 int usedlenlinecolor; /* number of bytes of current linecolor already drawn */
1741 1901
                 /* end of definitions */
1742
-                if(redata_line_realstart(re->data,pos,&realstart)==-1 || redata_line_realend(re->data,pos,&realend)==-1) {
1902
+                if(redata_line_realstart(data,pos,&realstart)==-1 || redata_line_realend(data,pos,&realend)==-1) {
1743 1903
                         break; /* couldn't get real start/end */
1744 1904
                 }
1745 1905
                 in_error=0;
1746
-                linecolors=(colors==NULL)?NULL:redata_highlighter_getline(re->data,re->originline+row,&nlinecolors);
1906
+                linecolors=(colors==NULL)?NULL:redata_highlighter_getline(data,originline+row,&nlinecolors);
1747 1907
                 curlinecolor=0;
1748 1908
                 usedlenlinecolor=0;
1749
-                for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(re->origincol+re->maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
1750
-                        if(redata_line_rawinfo(re->data,pos,&newpos,&ptr,&len,&is_continuation)==-1) {
1909
+                for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(origincol+maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
1910
+                        if(redata_line_rawinfo(data,pos,&newpos,&ptr,&len,&is_continuation)==-1) {
1751 1911
                                 in_error=1;
1752 1912
                                 break; /* couldn't get this line part info */
1753 1913
                         }
... ...
@@ -1759,7 +1919,7 @@ re_drawcontents(re_t *re)
1759 1919
                                 used=usedcol=0;
1760 1920
                                 /* while the avail text is larger than the linecolor len */
1761 1921
                                 while(curlinecolor<nlinecolors && (len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
1762
-                                        reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1922
+                                        reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1763 1923
                                         usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1764 1924
                                         used+=linecolors[curlinecolor].len-usedlenlinecolor;
1765 1925
                                         curlinecolor++;
... ...
@@ -1767,68 +1927,75 @@ re_drawcontents(re_t *re)
1767 1927
                                 }
1768 1928
                                 /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */
1769 1929
                                 if(curlinecolor<nlinecolors && (len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) {
1770
-                                        reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used));
1930
+                                        reui_write(ui,x0+(tmpcol-origincol+usedcol)*ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used));
1771 1931
                                         usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-used));
1772 1932
                                         usedlenlinecolor+=(len-has_nl-used);
1773 1933
                                         used+=(len-has_nl-used);
1774 1934
                                 }
1775 1935
                         } else {
1776
-                                reui_write(re->ui,re->x+(tmpcol-re->origincol)*re->ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
1936
+                                reui_write(ui,x0+(tmpcol-origincol)*ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
1777 1937
                         }
1778
-                        if(row==(re->curline-re->originline)) {
1779
-                                if(re->curcol>=tmpcol && re->curcol<(tmpcol+availcol)) {
1938
+                        if(row==(curline-originline)) {
1939
+                                if(curcol>=tmpcol && curcol<(tmpcol+availcol)) {
1780 1940
                                         int utf8charlen;
1781 1941
                                         /* draw cursor */
1782
-                                        reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
1942
+                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
1783 1943
                                         drawn_cursor=1;
1784
-                                        curptr=redata_generic_utf8col(ptr,len-has_nl,re->curcol-tmpcol);
1944
+                                        curptr=redata_generic_utf8col(ptr,len-has_nl,curcol-tmpcol);
1785 1945
                                         curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
1786 1946
                                         utf8charlen=redata_generic_utf8charlen(curptr,curptrlen);
1787
-                                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,utf8charlen);
1947
+                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",curptr,utf8charlen);
1788 1948
                                         /* get matching braces/parens/anglebracket/curlybraces for highlighting */
1789 1949
                                         if(utf8charlen==1 && strchr("[]{}<>()",*curptr)!=NULL)
1790 1950
                                                 matchingpos=re_getmatchingbracket(re,cursorpos,*curptr,&matchingchar);
1791 1951
                                 }
1792 1952
                         }
1793 1953
                 }
1794
-                if(row==(re->curline-re->originline) && !drawn_cursor)
1795
-                        reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
1954
+                if(row==(curline-originline) && !drawn_cursor)
1955
+                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
1796 1956
                 if(in_error)
1797 1957
                         break;
1798 1958
                 pos=realend+1;
1799
-/*LONG LINE LEFT FOR DEBUGGING PURPOSES: reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));*/
1959
+/*LONG LINE LEFT FOR DEBUGGING PURPOSES: reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));*/
1800 1960
         }
1801 1961
         /* highlight matching parens/brace/... if applicable */
1802
-        if(matchingpos!=-1 && redata_pos2linecol(re->data,matchingpos,&mline,&mcol)!=-1) {
1962
+        if(printout==NULL && matchingpos!=-1 && redata_pos2linecol(data,matchingpos,&mline,&mcol)!=-1) {
1803 1963
                 int x,y;
1804 1964
                 char *fg="\xff\x00\x00\x80";
1805 1965
                 char *bg="\xff\xff\xff\xaf";
1806
-                x=re->x+(mcol-re->origincol)*re->ui->fontwidth+(re->ui->fontwidth/2);
1807
-                x=(x<re->x)?re->x:(x>=(re->x+re->w))?(re->x+re->w-1):x;
1808
-                y=re->y+(mline-re->originline)*re->ui->fontheight+(re->ui->fontheight/2);
1809
-                y=(y<re->y)?re->y:(y>=(re->y+re->h))?(re->y+re->h-1):y;
1810
-                if(mline<re->originline)
1811
-                        reui_balloon(re->ui, 'n', x, re->y, fg, bg, &matchingchar,1);
1812
-                else if(mline>=(re->originline+re->maxrow))
1813
-                        reui_balloon(re->ui, 's', x, re->y+re->h-1, fg, bg, &matchingchar,1);
1814
-                else if(mcol<re->origincol)
1815
-                        reui_balloon(re->ui, 'w', re->x, y, fg, bg, &matchingchar,1);
1816
-                else if(mcol>=(re->origincol+re->maxcol))
1817
-                        reui_balloon(re->ui, 'e', re->x+re->w-1,y, fg, bg, &matchingchar,1);
1966
+                x=x0+(mcol-origincol)*ui->fontwidth+(ui->fontwidth/2);
1967
+                x=(x<x0)?x0:(x>=(x0+w))?(x0+w-1):x;
1968
+                y=y0+(mline-originline)*ui->fontheight+(ui->fontheight/2);
1969
+                y=(y<y0)?y0:(y>=(y0+h))?(y0+h-1):y;
1970
+                if(mline<originline)
1971
+                        reui_balloon(ui, 'n', x, y0, fg, bg, &matchingchar,1);
1972
+                else if(mline>=(originline+maxrow))
1973
+                        reui_balloon(ui, 's', x, y0+h-1, fg, bg, &matchingchar,1);
1974
+                else if(mcol<origincol)
1975
+                        reui_balloon(ui, 'w', x0, y, fg, bg, &matchingchar,1);
1976
+                else if(mcol>=(origincol+maxcol))
1977
+                        reui_balloon(ui, 'e', x0+w-1,y, fg, bg, &matchingchar,1);
1818 1978
                 else
1819
-                        reui_balloon(re->ui, '\0', x,y, fg, bg, &matchingchar,1);
1979
+                        reui_balloon(ui, '\0', x,y, fg, bg, &matchingchar,1);
1820 1980
         }
1821 1981
         /* display prototypes info if applicable */
1822
-        hint=redata_prototypes_get(re->data, cursorpos);
1823
-        if(hint!=NULL) {
1824
-                if((re->curline-re->originline)>=(re->maxrow/2))
1825
-                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
1826
-                else
1827
-                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *)hint,strlen(hint));
1982
+        if(printout==NULL) {
1983
+                hint=redata_prototypes_get(data, cursorpos);
1984
+                if(hint!=NULL) {
1985
+                        if((curline-originline)>=(maxrow/2))
1986
+                                reui_balloon(ui, '\0', x0+w/2, y0+ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
1987
+                        else
1988
+                                reui_balloon(ui, '\0', x0+w/2, y0+h-ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *)hint,strlen(hint));
1989
+                }
1828 1990
         }
1829 1991
         /* all done */
1830
-        re->contentsdirty=0;
1831
-        re->ui->rendererdirty=1;
1992
+        if(printout==NULL) {
1993
+                re->contentsdirty=0;
1994
+                ui->rendererdirty=1;
1995
+        } else {
1996
+                printout->dirty=0;
1997
+                printout->ui->rendererdirty=1;
1998
+        }
1832 1999
         return(0);
1833 2000
 }
1834 2001
 
Browse code

Implement Control+UP/DOWN: scroll the screen instead of moving the cursor position

Dario Rodriguez authored on 07/01/2021 18:23:45
Showing 1 changed files
... ...
@@ -610,10 +610,23 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
610 610
                 re->headerdirty=1;
611 611
                 re->contentsdirty=1;
612 612
         } else if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
613
+                int move_res;
613 614
                 int oldcol=re->curcol,oldline=re->curline;
614
-                if(re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
615
+                if((SDL_GetModState()&KMOD_CTRL)!=0 && event->key.keysym.sym==SDLK_UP && re->originline==0)
616
+                        return(0); /* nothing to do, already at top */
617
+                move_res=re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1);
618
+                if(move_res==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
615 619
                         re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_UP)?-1:1);
616 620
                 }
621
+                if(move_res==0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
622
+                        if(event->key.keysym.sym==SDLK_UP && re->originline>0) {
623
+                                re->originline--;
624
+                                re->contentsdirty=1;
625
+                        } else if(event->key.keysym.sym==SDLK_DOWN && re->originline<re->curline) {
626
+                                re->originline++;
627
+                                re->contentsdirty=1;
628
+                        }
629
+                }
617 630
         } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
618 631
                 int oldcol=re->curcol,oldline=re->curline;
619 632
                 if(re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
Browse code

fix: ensure cursor is in visible area after deleting a character

Dario Rodriguez authored on 02/01/2021 11:52:05
Showing 1 changed files
... ...
@@ -703,6 +703,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
703 703
                         cursorpos-=trimmed;
704 704
                 /* end of deletion */
705 705
                 redata_undo_groupcommit(re->data,NULL);
706
+                re_fixorigin(re);
706 707
                 re->headerdirty=1;
707 708
                 re->contentsdirty=1;
708 709
         } else if(event->key.keysym.sym==SDLK_q && (SDL_GetModState()&KMOD_CTRL)!=0) {
Browse code

Make scrolling when at the right end more pleasant (now only needs to scroll after several keystrokes)

Dario Rodriguez authored on 28/12/2020 20:55:54
Showing 1 changed files
... ...
@@ -435,8 +435,11 @@ re_fixorigin(re_t *re)
435 435
                 re->origincol=(re->origincol<0)?0:re->origincol;
436 436
         }
437 437
         if(re->curcol>=(re->origincol+re->maxcol-COLFORCESCROLL)) {
438
-                re->origincol=re->curcol+COLFORCESCROLL-re->maxcol;
438
+                int col;
439
+                col=re->curcol-(re->curcol%COLFORCESCROLL);
440
+                re->origincol=col+COLFORCESCROLL-re->maxcol;
439 441
                 re->origincol=(re->origincol<0)?0:re->origincol;
442
+
440 443
         }
441 444
         return(0);
442 445
 }
Browse code

fix: remove from the possible zoom list those with bad appearance

Dario Rodriguez authored on 28/12/2020 10:47:14
Showing 1 changed files
... ...
@@ -1245,7 +1245,7 @@ re_moveleftright(re_t *re, int totalinc)
1245 1245
 int
1246 1246
 re_changefontsize(re_t *re, int direction)
1247 1247
 {
1248
-        int validpercent[]={30,50,67,80,90,100,110,120,133,150,170,200,240,300};
1248
+        int validpercent[]={50,67,90,100,110,120,133,150,170,200,240,300};
1249 1249
         int newpercent;
1250 1250
         int i;
1251 1251
         if(re==NULL)
Browse code

Fix highlighting when using go-to-line (clamp origin var.). Make the info mesage dissappear when pressing Esc

Dario Rodriguez authored on 23/12/2020 17:39:36
Showing 1 changed files
... ...
@@ -566,6 +566,7 @@ fprintf(stderr,"SDL_TEXTINPUT: Insering newline\n");
566 566
                         re->curcol+=redata_generic_utf8len(event->text.text,len);
567 567
                 }
568 568
                 redata_undo_groupcommit(re->data,NULL);
569
+                re_fixorigin(re);
569 570
                 re->headerdirty=1;
570 571
                 re->contentsdirty=1;
571 572
         }
... ...
@@ -582,7 +583,9 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed
582 583
 #if 0
583 584
 fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
584 585
 #endif
585
-        if((SDL_GetModState()&KMOD_ALT)!=0 && re->selactive && (event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT)) {
586
+        if(event->key.keysym.sym==SDLK_ESCAPE) {
587
+                re->headerdirty=1;
588
+        } else if((SDL_GetModState()&KMOD_ALT)!=0 && re->selactive && (event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT)) {
586 589
                 int l;
587 590
                 int is_del;
588 591
                 int tolinefix;
... ...
@@ -742,6 +745,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
742 745
                 re->headerdirty=1;
743 746
                 re->contentsdirty=1;
744 747
         } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
748
+#warning XXX TODO: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation)
745 749
                 re_changefontsize(re, 1);
746 750
                 re->ignorenkeys++;
747 751
         } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
... ...
@@ -992,6 +996,7 @@ re_processcommand(re_t *re)
992 996
                 re->curline=line;
993 997
                 /* position the line in the center of viewport */
994 998
                 re->originline=line-(re->maxrow/2);
999
+                re->originline=(re->originline<0)?0:re->originline;
995 1000
                 re->headerdirty=1;
996 1001
                 re->contentsdirty=1;
997 1002
         } else if(strcmp(re->command,COMMAND_SEARCHFORWARD)==0) {
... ...
@@ -1670,13 +1675,7 @@ re_drawcontents(re_t *re)
1670 1675
                 return(-1);
1671 1676
         if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1672 1677
                 return(0); /* error obtaining position */
1673
-#if 0
1674
-fprintf(stderr,"re_drawcontents: pre  reuifill1\n");
1675
-#endif
1676 1678
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
1677
-#if 0
1678
-fprintf(stderr,"re_drawcontents: post reuifill1\n");
1679
-#endif
1680 1679
         row=re->curline-re->originline;
1681 1680
         pos=cursorpos;
1682 1681
         while(row>0 && pos>0) {
... ...
@@ -1687,20 +1686,11 @@ fprintf(stderr,"re_drawcontents: post reuifill1\n");
1687 1686
                         row--;
1688 1687
         }
1689 1688
         /* highlight current line */
1690
-#if 0
1691
-fprintf(stderr,"re_drawcontents: pre  reuifill2\n");
1692
-#endif
1693 1689
         reui_fill(re->ui,re->x,re->y+(re->curline-re->originline)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
1694
-#if 0
1695
-fprintf(stderr,"re_drawcontents: post reuifill2\n");
1696
-#endif
1697 1690
         /* highlight the selection */
1698 1691
         if(re->selactive) {
1699 1692
                 const char *selcolor;
1700 1693
                 tmprow=row;
1701
-#if 0
1702
-fprintf(stderr,"re_drawcontents: reuifill3: ");
1703
-#endif
1704 1694
                 for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1705 1695
                         selcolor=(row==(re->curline-re->originline))?selcolorcurline:selcolornormal;
1706 1696
                         if((re->originline+row)==re->sellinefrom && (re->originline+row)==re->sellineto) {
... ...
@@ -1711,13 +1701,7 @@ fprintf(stderr,"re_drawcontents: reuifill3: ");
1711 1701
                                 if(x1<(re->x+re->w))
1712 1702
                                         reui_fill(re->ui,x1,re->y+row*re->ui->fontheight,re->w-x1,re->ui->fontheight+1,selcolor);
1713 1703
                         } else if((re->originline+row)>re->sellinefrom && (re->originline+row)<re->sellineto) {
1714
-#if 0
1715
-fprintf(stderr,"{(ui,%i,%i,%i,%i,#%02X%02X%02X%02X)",re->x,re->y+row*re->ui->fontheight,re->w,re->ui->fontheight+1,((unsigned char *)selcolor)[0],((unsigned char *)selcolor)[1],((unsigned char *)selcolor)[2],((unsigned char *)selcolor)[3]);
1716
-#endif
1717 1704
                                 reui_fill(re->ui,re->x,re->y+row*re->ui->fontheight,re->w,re->ui->fontheight+1,selcolor);
1718
-#if 0
1719
-fprintf(stderr,"}");
1720
-#endif
1721 1705
                         } else if((re->originline+row)==re->sellineto) {
1722 1706
                                 int x2;
1723 1707
                                 x2=re->x+(re->selcolto-re->origincol)*re->ui->fontwidth;
... ...
@@ -1727,9 +1711,6 @@ fprintf(stderr,"}");
1727 1711
 
1728 1712
                 }
1729 1713
                 row=tmprow;
1730
-#if 0
1731
-fprintf(stderr,"\n");
1732
-#endif
1733 1714
         }
1734 1715
         /* draw the lines */
1735 1716
         drawn_cursor=0;
Browse code

tweak info header's colors and contents

Dario Rodriguez authored on 01/12/2020 17:59:37
Showing 1 changed files
... ...
@@ -6,7 +6,6 @@
6 6
  * Author: Dario Rodriguez dario@softhome.net
7 7
  * This program is licensed under the terms of GNU GPL v2.1+
8 8
  */
9
-
10 9
 #include <stdio.h>
11 10
 #include <stdlib.h>
12 11
 #include <unistd.h>
... ...
@@ -42,8 +41,10 @@
42 41
 #define COMMAND_QUESTION "(?)"
43 42
 #define COMMAND_EXIT "Exit"
44 43
 
44
+/* "forest" theme */
45 45
 #define COLOR_STATUSBG "\x14\x3a\xaf\xff"
46 46
 #define COLOR_STATUSFG "\xe6\xdc\x5d\xff"
47
+#define COLOR_STATUSFGLIGHT "\x6f\x73\xa3\xff"
47 48
 
48 49
 #define COLOR_QUERYBG "\xad\x92\x5e\xff"
49 50
 #define COLOR_QUERYFG "\xd0\xef\x4f\xff"
... ...
@@ -53,7 +54,7 @@
53 54
 
54 55
 #define COLOR_INFOBG "\x4e\x8a\x4e\xff"
55 56
 #define COLOR_INFOFG "\xee\xee\x46\xff"
56
-
57
+#define COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
57 58
 
58 59
 typedef struct re_t {
59 60
         redata_t *data;
... ...
@@ -1561,16 +1562,37 @@ int
1561 1562
 re_drawheader_editing(re_t *re)
1562 1563
 {
1563 1564
         long cursorpos;
1565
+        char linebuf[32],colbuf[32],posbuf[32],sizebuf[32];
1566
+        char *spaceslinebuf,*spacescolbuf,*spacesposbuf,*spacessizebuf;
1567
+        char spaces[128];
1568
+        int lenfilename;
1569
+        char *filename;
1570
+        char *spacesfilename;
1564 1571
         if(re==NULL)
1565 1572
                 return(-1);
1566 1573
         if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1567 1574
                 return(0); /* error obtaining position */
1568
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG);
1575
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needs_saving(re->data)?COLOR_STATUSBG:COLOR_INFOBG);
1569 1576
         /* for the user, lines start at 0 (internally they start at 0) */
1570
-        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i Col:%i Pos:%li Size:%li %s"
1571
-          ,re->filename,re->curline+1,re->curcol+1,cursorpos,redata_getused(re->data)
1572
-          ,"");
1573
-#warning #error MAKE THE PREVIOUS LINE LAST %s print: "CHANGED" when unsaved&not-in-reu, "changed" when unsaved but is in reu, "saved" when it is saved.
1577
+        memset(spaces,' ',sizeof(spaces));
1578
+        spaces[sizeof(spaces)-1]='\0';
1579
+        snprintf(linebuf,sizeof(linebuf),"%i",re->curline+1),linebuf[sizeof(linebuf)-1]='\0';
1580
+        spaceslinebuf=spaces+sizeof(spaces)-1-strlen(linebuf);
1581
+        snprintf(colbuf,sizeof(colbuf),"%i",re->curcol+1),colbuf[sizeof(colbuf)-1]='\0';
1582
+        spacescolbuf=spaces+sizeof(spaces)-1-strlen(colbuf);
1583
+        snprintf(posbuf,sizeof(posbuf),"%li",cursorpos),posbuf[sizeof(posbuf)-1]='\0';
1584
+        spacesposbuf=spaces+sizeof(spaces)-1-strlen(posbuf);
1585
+        snprintf(sizebuf,sizeof(sizebuf),"%li",redata_getused(re->data)),sizebuf[sizeof(sizebuf)-1]='\0';
1586
+        spacessizebuf=spaces+sizeof(spaces)-1-strlen(sizebuf);
1587
+        lenfilename=strlen(re->filename);
1588
+        filename=((lenfilename)>(sizeof(spaces)-1))?(re->filename+lenfilename-sizeof(spaces)-1):re->filename;
1589
+        spacesfilename=spaces+sizeof(spaces)-1-strlen(filename);
1590
+        reui_printf(re->ui,0,0,redata_needs_saving(re->data)?COLOR_STATUSFGLIGHT:COLOR_INFOFGLIGHT
1591
+           ,"File:%s%s Line:%s Col:%s Pos:%s Size:%s"
1592
+          ,spacesfilename,redata_needs_saving(re->data)?"*":" ",spaceslinebuf,spacescolbuf,spacesposbuf,spacessizebuf);
1593
+        reui_printf(re->ui,0,0,redata_needs_saving(re->data)?COLOR_STATUSFG:COLOR_INFOFG
1594
+           ,"     %s%s      %s     %s     %s      %s"
1595
+          ,filename," ",linebuf,colbuf,posbuf,sizebuf);
1574 1596
         re->headerdirty=0;
1575 1597
         re->ui->rendererdirty=1;
1576 1598
         return(0);
Browse code

Added 'Exit without saving?' confirmation dialog

Dario Rodriguez authored on 30/11/2020 21:40:46
Showing 1 changed files
... ...
@@ -38,6 +38,7 @@
38 38
 #define COMMAND_REPLACEWHAT "Search for:"
39 39
 #define COMMAND_REPLACEWITH "Replace with:"
40 40
 #define COMMAND_REPLACEHOW "Replace options (Igncase Selected Backwards Entire All Noconfirm):"
41
+#define COMMAND_CONFIRMEXIT "There is unsaved data. Please confirm exit with y+ENTER:"
41 42
 #define COMMAND_QUESTION "(?)"
42 43
 #define COMMAND_EXIT "Exit"
43 44
 
... ...
@@ -236,7 +237,13 @@ fprintf(stderr,"RENDER\n");
236 237
                         flag_had_events=10;
237 238
                         switch(event.type) {
238 239
                                 case SDL_QUIT:
239
-                                        do_exit=1;
240
+                                        if(redata_needs_saving(re->data)) {
241
+                                                re->command=COMMAND_CONFIRMEXIT;
242
+                                                re->commandbuf[0]='\0';
243
+                                                re->headerdirty=1;
244
+                                        } else {
245
+                                                do_exit=1;
246
+                                        }
240 247
                                         break;
241 248
                                 case SDL_KEYDOWN:
242 249
                                 case SDL_TEXTINPUT:
... ...
@@ -812,8 +819,13 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
812 819
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
813 820
                 re->headerdirty=1;
814 821
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
815
-                re->command=COMMAND_EXIT;
816
-                re->commandbuf[0]='\0';
822
+                if(redata_needs_saving(re->data)) {
823
+                        re->command=COMMAND_CONFIRMEXIT;
824
+                        re->commandbuf[0]='\0';
825
+                } else {
826
+                        re->command=COMMAND_EXIT;
827
+                        re->commandbuf[0]='\0';
828
+                }
817 829
                 re->headerdirty=1;
818 830
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_h) {
819 831
                 re_sel_toggle(re);
... ...
@@ -956,7 +968,15 @@ re_processcommand(re_t *re)
956 968
         if(re==NULL || re->command==NULL)
957 969
                 return(-1);
958 970
         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
959
-        if(strcmp(re->command,COMMAND_GOTOLINE)==0) {
971
+        if(strcmp(re->command,COMMAND_CONFIRMEXIT)==0) {
972
+                if(strcmp(re->commandbuf,"y")==0) {
973
+                        re->command=COMMAND_EXIT;
974
+                        re->commandbuf[0]='\0';
975
+                        re->headerdirty=1;
976
+                        return(0);
977
+                }
978
+                re->headerdirty=1;
979
+        } else if(strcmp(re->command,COMMAND_GOTOLINE)==0) {
960 980
                 int line;
961 981
                 long pos;
962 982
                 line=atoi(re->commandbuf)-1;
... ...
@@ -1566,7 +1586,7 @@ re_drawheader_command(re_t *re)
1566 1586
         if(re->command[0]=='\0') {
1567 1587
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
1568 1588
                 reui_printf(re->ui,0,0,COLOR_QUERYFG,"Command:");
1569
-        } else if(strcmp(re->command,COMMAND_WARNING)==0) {
1589
+        } else if(strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_CONFIRMEXIT)==0) {
1570 1590
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG);
1571 1591
                 reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf);
1572 1592
         } else if(strcmp(re->command,COMMAND_INFO)==0) {
Browse code

Add info header-type. Tweak header colors. FIRST USABLE VERSION.

Dario Rodriguez authored on 30/11/2020 20:51:14
Showing 1 changed files
... ...
@@ -32,6 +32,7 @@
32 32
 #define SELECTBUFBLOCK 16384
33 33
 
34 34
 #define COMMAND_WARNING "(!)"
35
+#define COMMAND_INFO "(i)"
35 36
 #define COMMAND_GOTOLINE "Go to line:"
36 37
 #define COMMAND_SEARCHFORWARD "Search:"
37 38
 #define COMMAND_REPLACEWHAT "Search for:"
... ...
@@ -40,14 +41,17 @@
40 41
 #define COMMAND_QUESTION "(?)"
41 42
 #define COMMAND_EXIT "Exit"
42 43
 
43
-#define COLOR_STATUSBG "\x00\x00\xff\xff"
44
-#define COLOR_STATUSFG "\xff\xff\x00\xff"
44
+#define COLOR_STATUSBG "\x14\x3a\xaf\xff"
45
+#define COLOR_STATUSFG "\xe6\xdc\x5d\xff"
45 46
 
46
-#define COLOR_QUERYBG "\xc0\xff\x00\xff"
47
-#define COLOR_QUERYFG "\x3f\x00\xff\xff"
47
+#define COLOR_QUERYBG "\xad\x92\x5e\xff"
48
+#define COLOR_QUERYFG "\xd0\xef\x4f\xff"
48 49
 
49
-#define COLOR_WARNINGBG "\xff\x00\x00\xff"
50
-#define COLOR_WARNINGFG "\xff\xff\x00\xff"
50
+#define COLOR_WARNINGBG "\xba\x07\x07\xff"
51
+#define COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
52
+
53
+#define COLOR_INFOBG "\x4e\x8a\x4e\xff"
54
+#define COLOR_INFOFG "\xee\xee\x46\xff"
51 55
 
52 56
 
53 57
 typedef struct re_t {
... ...
@@ -207,8 +211,8 @@ fprintf(stderr,"REDRAW Header (editing)\n");
207 211
 fprintf(stderr,"REDRAW Header (command)\n");
208 212
 #endif
209 213
                                 re_drawheader_command(re);
210
-                                if(strcmp(re->command,COMMAND_WARNING)==0) {
211
-                                        /* the warnings only get shown once, remove it */
214
+                                if(strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_INFO)==0) {
215
+                                        /* the warnings/info only get shown once, remove it */
212 216
                                         re->command=NULL;
213 217
                                         re->commandbuf[0]='\0';
214 218
                                         re->showingwarning=1;
... ...
@@ -237,7 +241,7 @@ fprintf(stderr,"RENDER\n");
237 241
                                 case SDL_KEYDOWN:
238 242
                                 case SDL_TEXTINPUT:
239 243
                                 case SDL_TEXTEDITING:
240
-                                        if(re->command==NULL || strcmp(re->command,COMMAND_WARNING)==0)
244
+                                        if(re->command==NULL || strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_INFO)==0)
241 245
                                                 re_processkey_editing(re,&event);
242 246
                                         else if(re->command[0]=='\0')
243 247
                                                 re_processkey_commandwait(re,&event);
... ...
@@ -695,7 +699,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
695 699
                 char *errormsg=NULL;
696 700
                 if(redata_save(re->data,re->filename,&errormsg)!=-1)
697 701
                         errormsg="File saved";
698
-                re->command=COMMAND_WARNING;
702
+                re->command=COMMAND_INFO;
699 703
                 snprintf(re->commandbuf,sizeof(re->commandbuf),errormsg);
700 704
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
701 705
                 re->headerdirty=1;
... ...
@@ -1049,7 +1053,7 @@ re_processcommand(re_t *re)
1049 1053
                 re_fixorigin_center(re);
1050 1054
                 re->headerdirty=1;
1051 1055
                 re->contentsdirty=1;
1052
-                re->command=COMMAND_WARNING;
1056
+                re->command=COMMAND_INFO;
1053 1057
                 snprintf(re->commandbuf,sizeof(re->commandbuf),"%li subst",total);
1054 1058
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1055 1059
                 re->headerdirty=1;
... ...
@@ -1565,6 +1569,9 @@ re_drawheader_command(re_t *re)
1565 1569
         } else if(strcmp(re->command,COMMAND_WARNING)==0) {
1566 1570
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG);
1567 1571
                 reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf);
1572
+        } else if(strcmp(re->command,COMMAND_INFO)==0) {
1573
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_INFOBG);
1574
+                reui_printf(re->ui,0,0,COLOR_INFOFG,"%s %s",re->command,re->commandbuf);
1568 1575
         } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
1569 1576
                 question_t *q;
1570 1577
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
Browse code

bugfix: fix inconsistencies between cursorpos and line/col (now, line/col is the authoritative position)

Dario Rodriguez authored on 30/11/2020 19:20:20
Showing 1 changed files
... ...
@@ -57,7 +57,6 @@ typedef struct re_t {
57 57
         char filename[PATH_MAX];
58 58
         int x, y, w, h; // contents rect
59 59
         int fontheightpercent;
60
-        long cursorpos;
61 60
         int originline,origincol;
62 61
         int curline,curcol;
63 62
         int maxrow,maxcol;
... ...
@@ -182,7 +181,6 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
182 181
                                         re->flag_newfile=0;
183 182
                                 re->originline=re->origincol=0;
184 183
                                 re->curline=re->curcol=0;
185
-                                re->cursorpos=0;
186 184
                                 load_pending=0;
187 185
                                 re->headerdirty=1;
188 186
                                 re->contentsdirty=1;
... ...
@@ -471,12 +469,15 @@ fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
471 469
 #endif
472 470
                 long realend;
473 471
                 int at_end;
474
-                if(re->cursorpos==redata_getused(re->data))
472
+                long cursorpos;
473
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0
474
+                  || cursorpos==redata_getused(re->data)) {
475 475
                         return(0); /* already at end, nothing to delete */
476
-                if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
476
+                }
477
+                if(redata_line_realend(re->data,cursorpos,&realend)==-1)
477 478
                         return(-1); /* couldn't get current line info */
478
-                at_end=(re->cursorpos==realend)?1:0;
479
-                if(at_end && (re->cursorpos+1)==redata_getused(re->data))
479
+                at_end=(cursorpos==realend)?1:0;
480
+                if(at_end && (cursorpos+1)==redata_getused(re->data))
480 481
                         return(-1); /* we shouldn't erase the final '\n' */
481 482
                 memset(&fakeevent,0,sizeof(SDL_Event));
482 483
                 event=&fakeevent;
... ...
@@ -485,12 +486,10 @@ fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
485 486
                 redata_undo_groupinit(re->data,NULL);
486 487
                 if(at_end) {
487 488
                         int col;
488
-                        if(redata_pos2linecol(re->data,re->cursorpos,NULL,&col)==-1)
489
+                        if(redata_pos2linecol(re->data,cursorpos,NULL,&col)==-1)
489 490
                                 return(-1); /* couldn't get line info */
490
-                        if(redata_op_addn(re->data,re->cursorpos,' ',re->curcol-col,NULL)!=0)
491
+                        if(redata_op_addn(re->data,cursorpos,' ',re->curcol-col,NULL)!=0)
491 492
                                 return(-1); /* couldn't add spaces up to current displayed pos */
492
-                        re->cursorpos+=re->curcol-col;
493
-                        re->cursorpos++;
494 493
                         re->curline++;
495 494
                         re->curcol=0;
496 495
                 } else {
... ...
@@ -506,6 +505,7 @@ fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
506 505
                 long realend;
507 506
                 int at_end;
508 507
                 int nspaces;
508
+                long cursorpos;
509 509
                 if(re->ignorenkeys>0) {
510 510
                         re->ignorenkeys--;
511 511
                         return(0); /* this is an already processed key, ignore it */
... ...
@@ -513,9 +513,11 @@ fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
513 513
 #if 0
514 514
 fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
515 515
 #endif
516
-                if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
516
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0
517
+                  || redata_line_realend(re->data,cursorpos,&realend)==-1) {
517 518
                         return(-1); /* couldn't get current line info */
518
-                at_end=(re->cursorpos==realend)?1:0;
519
+                }
520
+                at_end=(cursorpos==realend)?1:0;
519 521
                 for(nspaces=0;event->text.text[nspaces]==' ';nspaces++)
520 522
                         ;
521 523
                 if(nspaces>0 && event->text.text[nspaces]=='\0' && at_end) {
... ...
@@ -526,21 +528,21 @@ fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
526 528
                 redata_undo_groupinit(re->data,NULL);
527 529
                 if(!(event->text.text[0]=='\n' && event->text.text[1]=='\0') && at_end) {
528 530
                         int col;
529
-                        if(redata_pos2linecol(re->data,re->cursorpos,NULL,&col)==-1)
531
+                        if(redata_pos2linecol(re->data,cursorpos,NULL,&col)==-1)
530 532
                                 return(-1); /* couldn't get line info */
531
-                        if(redata_op_addn(re->data,re->cursorpos,' ',re->curcol-col,NULL)!=0)
533
+                        if(redata_op_addn(re->data,cursorpos,' ',re->curcol-col,NULL)!=0)
532 534
                                 return(-1); /* couldn't add spaces up to current displayed pos */
533 535
                         /* increment cursorpos; spaces are 1 byte, so the number of columns advanced is the number of bytes advanced */
534
-                        re->cursorpos+=re->curcol-col;
536
+                        cursorpos+=re->curcol-col;
535 537
                 }
536 538
                 len=strlen(event->text.text);
537
-                if(redata_op_add(re->data,re->cursorpos,event->text.text,len,NULL)!=0)
539
+                if(redata_op_add(re->data,cursorpos,event->text.text,len,NULL)!=0)
538 540
                         return(-1); /* couldn't add requested text */
539
-                re->cursorpos+=len;
541
+                cursorpos+=len;
540 542
                 if(event->text.text[0]=='\n' && event->text.text[1]=='\0') {
541 543
                         int trimmed;
542
-                        if(re_rtrim(re,re->cursorpos-len,&trimmed))
543
-                                re->cursorpos-=trimmed;
544
+                        if(re_rtrim(re,cursorpos-len,&trimmed))
545
+                                cursorpos-=trimmed;
544 546
 #if 1
545 547
 #if 0
546 548
 fprintf(stderr,"SDL_TEXTINPUT: Insering newline\n");
... ...
@@ -587,7 +589,6 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
587 589
                                 redata_op_del(re->data,pos,pos2-pos,NULL);
588 590
                 }
589 591
                 redata_undo_groupcommit(re->data,NULL);
590
-                redata_linecol2pos(re->data,re->curline,re->curcol,&(re->cursorpos),NULL);
591 592
                 re->headerdirty=1;
592 593
                 re->contentsdirty=1;
593 594
         } else if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
... ...
@@ -601,9 +602,10 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
601 602
                         re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
602 603
                 }
603 604
         } else if((SDL_GetModState()&KMOD_CTRL)!=0 && (event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP)) {
604
-                re->cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
605
-                re->cursorpos=(re->cursorpos<0)?0:re->cursorpos;
606
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
605
+                long cursorpos;
606
+                cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
607
+                cursorpos=(cursorpos<0)?0:cursorpos;
608
+                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
607 609
                 re_fixorigin_center(re);
608 610
                 re->headerdirty=1;
609 611
                 re->contentsdirty=1;
... ...
@@ -611,27 +613,33 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
611 613
                 re_moveupdown(re,(event->key.keysym.sym==SDLK_PAGEUP)?-(re->maxrow):re->maxrow);
612 614
         } else if(event->key.keysym.sym==SDLK_HOME || event->key.keysym.sym==SDLK_END) {
613 615
                 long newpos;
614
-                if((event->key.keysym.sym==SDLK_HOME && redata_line_realstart(re->data,re->cursorpos,&newpos)==-1)
615
-                  || (event->key.keysym.sym==SDLK_END && redata_line_realend(re->data,re->cursorpos,&newpos)==-1)) {
616
+                long cursorpos;
617
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
618
+                        return(0); /* error obtaining position */
619
+                if((event->key.keysym.sym==SDLK_HOME && redata_line_realstart(re->data,cursorpos,&newpos)==-1)
620
+                  || (event->key.keysym.sym==SDLK_END && redata_line_realend(re->data,cursorpos,&newpos)==-1)) {
616 621
                         return(-1); /* couldn't get destination pos data */
617 622
                 }
618
-                re->cursorpos=newpos;
619
-                if(redata_pos2linecol(re->data,re->cursorpos,NULL,&(re->curcol))==-1)
623
+                cursorpos=newpos;
624
+                if(redata_pos2linecol(re->data,cursorpos,NULL,&(re->curcol))==-1)
620 625
                         return(-1); /* couldn't get col of current pos */;
621 626
                 re_fixorigin(re);
622 627
                 re->headerdirty=1;
623 628
                 re->contentsdirty=1;
624
-        } else if(event->key.keysym.sym==SDLK_BACKSPACE && re->cursorpos>0) {
629
+        } else if(event->key.keysym.sym==SDLK_BACKSPACE && (re->curline>0 || re->curcol>0)) {
625 630
                 int line,col;
626 631
                 long startpos,newpos,realstart,start;
627 632
                 char *ptr;
628 633
                 int len;
629 634
                 int trimmed;
630 635
                 int doneinc;
636
+                long cursorpos;
637
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
631 638
 #if 0
632 639
 fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
633 640
 #endif
634
-                if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
641
+                        return(0); /* error obtaining position */
642
+                if(redata_pos2linecol(re->data,cursorpos,&line,&col)==-1)
635 643
                         return(-1); /* couldn't get current line data */
636 644
                 if(col<re->curcol) {
637 645
                         re_moveleftright(re,-1);
... ...
@@ -641,11 +649,11 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
641 649
                         redata_undo_groupinit(re->data,NULL);
642 650
                 /* delete the last character */
643 651
                 if(col>0) {
644
-                        if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
652
+                        if(redata_line_realstart(re->data,cursorpos,&realstart)==-1)
645 653
                                 return(-1); /* couldn't get line info */
646 654
                         /* get the start of the part to delete */
647 655
                         doneinc=0;
648
-                        for(ptr=NULL,len=0,start=0,newpos=re->cursorpos;doneinc!=1;) {
656
+                        for(ptr=NULL,len=0,start=0,newpos=cursorpos;doneinc!=1;) {
649 657
                                 if((newpos-1)<realstart)
650 658
                                         break;
651 659
                                 newpos--;
... ...
@@ -657,24 +665,24 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
657 665
                                         doneinc++;
658 666
                         }
659 667
                         /* delete */
660
-                        redata_op_del(re->data,newpos,re->cursorpos-newpos,NULL);
661
-                        re->cursorpos=newpos;
668
+                        redata_op_del(re->data,newpos,cursorpos-newpos,NULL);
669
+                        cursorpos=newpos;
662 670
                 } else {
663 671
                         long delpos;
664 672
                         /* to make the code trivial, we're being lazy on '\n' deletion: we call ...rawinfo() for each byte in the multibyte utf-8 sequence */
665
-                        for(delpos=re->cursorpos-1
673
+                        for(delpos=cursorpos-1
666 674
                           ;delpos>0
667 675
                           && redata_line_rawinfo(re->data,delpos,&startpos,&ptr,&len,NULL)==0;) {
668 676
                                 if(redata_generic_utf8isstartbyte(ptr[delpos-startpos]))
669 677
                                         break;
670 678
                         }
671
-                        redata_op_del(re->data,delpos,re->cursorpos-delpos,NULL);
672
-                        re->cursorpos=delpos;
679
+                        redata_op_del(re->data,delpos,cursorpos-delpos,NULL);
680
+                        cursorpos=delpos;
673 681
                 }
674
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
682
+                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
675 683
                 /* if cursor at end of line and there are trailing spaces at the end, delete them too */
676
-                if(re_rtrim(re,re->cursorpos,&trimmed))
677
-                        re->cursorpos-=trimmed;
684
+                if(re_rtrim(re,cursorpos,&trimmed))
685
+                        cursorpos-=trimmed;
678 686
                 /* end of deletion */
679 687
                 redata_undo_groupcommit(re->data,NULL);
680 688
                 re->headerdirty=1;
... ...
@@ -699,23 +707,25 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
699 707
                 long newpos;
700 708
                 if(redata_op_undo(re->data,&newpos))
701 709
                         return(-1);
702
-                re->cursorpos=newpos;
703
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
710
+                redata_pos2linecol(re->data,newpos,&(re->curline),&(re->curcol));
704 711
                 re_fixorigin(re);
705 712
                 re->headerdirty=1;
706 713
                 re->contentsdirty=1;
707 714
         } else if(event->key.keysym.sym==SDLK_l && (SDL_GetModState()&KMOD_CTRL)!=0 && re->cachelastsearch[0]!='\0') {
708 715
                 long newpos;
716
+                long cursorpos;
717
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
718
+                        return(-1); /* error obtaining position */
709 719
                 /* search next (forward) */
710
-                if((newpos=redata_searchforward(re->data,re->cursorpos+1,re->cachelastsearch,strlen(re->cachelastsearch)))==-1) {
720
+                if((newpos=redata_searchforward(re->data,cursorpos+1,re->cachelastsearch,strlen(re->cachelastsearch)))==-1) {
711 721
                         re->command=COMMAND_WARNING;
712 722
                         snprintf(re->commandbuf,sizeof(re->commandbuf),"String not found");
713 723
                         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
714 724
                         re->headerdirty=1;
715 725
                         return(-1);
716 726
                 }
717
-                re->cursorpos=newpos;
718
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
727
+                cursorpos=newpos;
728
+                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
719 729
                 re_fixorigin_center(re);
720 730
                 re->headerdirty=1;
721 731
                 re->contentsdirty=1;
... ...
@@ -742,8 +752,7 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
742 752
                                 redata_undo_groupinit(re->data,NULL);
743 753
                                 redata_op_del(re->data,frompos,topos-frompos,NULL);
744 754
                                 redata_undo_groupcommit(re->data,NULL);
745
-                                re->cursorpos=frompos;
746
-                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
755
+                                redata_pos2linecol(re->data,frompos,&(re->curline),&(re->curcol));
747 756
                                 re_fixorigin(re);
748 757
                                 re->headerdirty=1;
749 758
                         }
... ...
@@ -752,18 +761,20 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
752 761
                 }
753 762
                 re->ignorenkeys++;
754 763
         } else if(event->key.keysym.sym==SDLK_v && (SDL_GetModState()&KMOD_CTRL)!=0) {
755
-fprintf(stderr,"re_processkey(): received Control+v\n");
764
+                long cursorpos;
756 765
                 /* Mac-HIG/OpenLook-style paste (ctrl+v)*/
766
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
767
+                        return(-1); /* error obtaining position */
757 768
                 if(re->selactive)
758 769
                         re_sel_toggle(re);
759 770
                 if(SDL_HasClipboardText())
760 771
                         re_selectbuf_replace(re,SDL_GetClipboardText());
761 772
                 if(re->usedselectbuf>0) {
762 773
                         redata_undo_groupinit(re->data,NULL);
763
-                        redata_op_add(re->data,re->cursorpos,re->selectbuf,re->usedselectbuf,NULL);
774
+                        redata_op_add(re->data,cursorpos,re->selectbuf,re->usedselectbuf,NULL);
764 775
                         redata_undo_groupcommit(re->data,NULL);
765
-                        re->cursorpos+=re->usedselectbuf;
766
-                        redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
776
+                        cursorpos+=re->usedselectbuf;
777
+                        redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
767 778
                         re_fixorigin(re);
768 779
                         re->headerdirty=1;
769 780
                         re->contentsdirty=1;
... ...
@@ -815,7 +826,10 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
815 826
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_y) {
816 827
                 long frompos,topos;
817 828
                 int coldone;
829
+                long cursorpos;
818 830
                 /* wordstar-style blockdel (ctrl+k+y) */
831
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
832
+                        return(-1); /* error obtaining position */
819 833
                 if(re->selactive
820 834
                   && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
821 835
                   && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
... ...
@@ -823,9 +837,9 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
823 837
                         redata_undo_groupinit(re->data,NULL);
824 838
                         redata_op_del(re->data,frompos,topos-frompos,NULL);
825 839
                         redata_undo_groupcommit(re->data,NULL);
826
-                        if(re->cursorpos>frompos) {
827
-                                re->cursorpos=frompos;
828
-                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
840
+                        if(cursorpos>frompos) {
841
+                                cursorpos=frompos;
842
+                                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
829 843
                                 re_fixorigin(re);
830 844
                         }
831 845
                         re->headerdirty=1;
... ...
@@ -857,17 +871,19 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
857 871
                                 insertpos+=re->curcol-coldone;
858 872
                         }
859 873
                         if(is_move) {
874
+                                long cursorpos;
860 875
                                 redata_op_del(re->data,frompos,re->usedselectbuf,NULL);
861 876
                                 redata_op_add(re->data,insertpos-((insertpos>frompos)?re->usedselectbuf:0),re->selectbuf,re->usedselectbuf,NULL);
862
-                                re->cursorpos=insertpos-((insertpos>frompos)?re->usedselectbuf:0)+re->usedselectbuf;
863
-                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
864
-                                redata_pos2linecol(re->data,re->cursorpos-re->usedselectbuf,&(re->sellinefrom),&(re->selcolfrom));
877
+                                cursorpos=insertpos-((insertpos>frompos)?re->usedselectbuf:0)+re->usedselectbuf;
878
+                                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
879
+                                redata_pos2linecol(re->data,cursorpos-re->usedselectbuf,&(re->sellinefrom),&(re->selcolfrom));
865 880
                                 re->sellineto=re->curline;
866 881
                                 re->selcolto=re->curcol;
867 882
                         } else {
883
+                                long cursorpos;
868 884
                                 redata_op_add(re->data,insertpos,re->selectbuf,re->usedselectbuf,NULL);
869
-                                re->cursorpos=insertpos+re->usedselectbuf;
870
-                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
885
+                                cursorpos=insertpos+re->usedselectbuf;
886
+                                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
871 887
                                 redata_pos2linecol(re->data,insertpos,&(re->sellinefrom),&(re->selcolfrom));
872 888
                                 re->sellineto=re->curline;
873 889
                                 re->selcolto=re->curcol;
... ...
@@ -948,7 +964,6 @@ re_processcommand(re_t *re)
948 964
                         re->headerdirty=1;
949 965
                         return(-1);
950 966
                 }
951
-                re->cursorpos=pos;
952 967
                 re->curline=line;
953 968
                 /* position the line in the center of viewport */
954 969
                 re->originline=line-(re->maxrow/2);
... ...
@@ -956,7 +971,10 @@ re_processcommand(re_t *re)
956 971
                 re->contentsdirty=1;
957 972
         } else if(strcmp(re->command,COMMAND_SEARCHFORWARD)==0) {
958 973
                 long newpos;
959
-                if((newpos=redata_searchforward(re->data,re->cursorpos,re->commandbuf,strlen(re->commandbuf)))==-1) {
974
+                long cursorpos;
975
+                if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
976
+                        return(-1); /* error obtaining position */
977
+                if((newpos=redata_searchforward(re->data,cursorpos,re->commandbuf,strlen(re->commandbuf)))==-1) {
960 978
                         re->command=COMMAND_WARNING;
961 979
                         snprintf(re->commandbuf,sizeof(re->commandbuf),"String not found");
962 980
                         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
... ...
@@ -965,8 +983,8 @@ re_processcommand(re_t *re)
965 983
                 }
966 984
                 strncpy(re->cachelastsearch,re->commandbuf,sizeof(re->cachelastsearch));
967 985
                 re->cachelastsearch[sizeof(re->cachelastsearch)-1]='\0';
968
-                re->cursorpos=newpos;
969
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
986
+                cursorpos=newpos;
987
+                redata_pos2linecol(re->data,cursorpos,&(re->curline),&(re->curcol));
970 988
                 re_fixorigin_center(re);
971 989
                 re->headerdirty=1;
972 990
                 re->contentsdirty=1;
... ...
@@ -1027,8 +1045,7 @@ re_processcommand(re_t *re)
1027 1045
                         redata_op_add(re->data,newpos,re->cachelastreplacewith,rlen,NULL);
1028 1046
                 }
1029 1047
                 redata_undo_groupcommit(re->data,NULL);
1030
-                re->cursorpos=oldpos;
1031
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
1048
+                redata_pos2linecol(re->data,oldpos,&(re->curline),&(re->curcol));
1032 1049
                 re_fixorigin_center(re);
1033 1050
                 re->headerdirty=1;
1034 1051
                 re->contentsdirty=1;
... ...
@@ -1061,31 +1078,34 @@ re_moveupdown(re_t *re, int totalinc)
1061 1078
         int inc,doneinc;
1062 1079
         long realstart;
1063 1080
         int needs_inccol;
1081
+        long cursorpos;
1064 1082
         if(re==NULL)
1065 1083
                 return(-1); /* sanity check failed */
1066 1084
         if(totalinc==0)
1067 1085
                 return(0); /* nothing to do */
1068 1086
         inc=(totalinc<0)?-1:1;
1069
-        newpos=re->cursorpos; /* get rid of compiler warning (will be overwitten in the loop as totalinc never is 0) */
1087
+        if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1088
+                return(-1); /* error obtaining position */
1089
+        newpos=cursorpos; /* get rid of compiler warning (will be overwitten in the loop as totalinc never is 0) */
1070 1090
         needs_inccol=0;
1071 1091
         for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
1072 1092
 #if 0
1073
-fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
1093
+fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",cursorpos,re->curline,re->curcol);
1074 1094
 #endif
1075
-                if((inc==-1 && redata_line_prevrealstart(re->data,re->cursorpos,&realstart)==-1)
1076
-                   || (inc==1 && redata_line_nextrealstart(re->data,re->cursorpos,&realstart)==-1)) {
1095
+                if((inc==-1 && redata_line_prevrealstart(re->data,cursorpos,&realstart)==-1)
1096
+                   || (inc==1 && redata_line_nextrealstart(re->data,cursorpos,&realstart)==-1)) {
1077 1097
                         break; /* couldn't get current line data, we are at start/end */
1078 1098
                 }
1079
-                re->cursorpos=realstart;
1099
+                cursorpos=realstart;
1080 1100
                 needs_inccol=1;
1081 1101
                 re->curline+=inc;
1082 1102
 #if 0
1083
-fprintf(stderr,"MOVING   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
1103
+fprintf(stderr,"MOVING   to cursorpos:%li line:%i col:%i\n",cursorpos,re->curline,re->curcol);
1084 1104
 #endif
1085 1105
         }
1086 1106
         if(!needs_inccol)
1087 1107
                 return(-1);
1088
-        if(redata_line_inccol(re->data,re->cursorpos,re->curcol,&newpos2,NULL)==-1) {
1108
+        if(redata_line_inccol(re->data,cursorpos,re->curcol,&newpos2,NULL)==-1) {
1089 1109
                 /* error advancing cursor, "emergency" repositioning */
1090 1110
 #if 0
1091 1111
 fprintf(stderr,"SETTING COLUMN ERROR\n");
... ...
@@ -1094,11 +1114,11 @@ fprintf(stderr,"SETTING COLUMN ERROR\n");
1094 1114
                 newpos2=newpos;
1095 1115
         }
1096 1116
 #if 0
1097
-fprintf(stderr,"COLUMN from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
1117
+fprintf(stderr,"COLUMN from cursorpos:%li line:%i col:%i\n",cursorpos,re->curline,re->curcol);
1098 1118
 #endif
1099
-        re->cursorpos=newpos2;
1119
+        cursorpos=newpos2;
1100 1120
 #if 0
1101
-fprintf(stderr,"COLUMN   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
1121
+fprintf(stderr,"COLUMN   to cursorpos:%li line:%i col:%i\n",cursorpos,re->curline,re->curcol);
1102 1122
 #endif
1103 1123
         re_fixorigin(re);
1104 1124
         re->contentsdirty=1;
... ...
@@ -1115,30 +1135,33 @@ re_moveleftright(re_t *re, int totalinc)
1115 1135
         int len;
1116 1136
         long start;
1117 1137
         int tmpcol,oldcol;
1138
+        long cursorpos;
1118 1139
         if(re==NULL)
1119 1140
                 return(-1); /* sanity check failed */
1120 1141
         if(totalinc==0)
1121 1142
                 return(0); /* nothing to do */
1143
+        if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1144
+                return(-1); /* error obtaining position */
1122 1145
         oldcol=re->curcol;
1123 1146
         if(totalinc<0 && (re->curcol+totalinc)<=0) {
1124 1147
                 /* we'll land on the start of the line -- do it trivially */
1125
-                if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
1148
+                if(redata_line_realstart(re->data,cursorpos,&realstart)==-1)
1126 1149
                         return(-1); /* couldn't get current pos */
1127 1150
                 re->curcol=0;
1128
-                re->cursorpos=realstart;
1151
+                cursorpos=realstart;
1129 1152
         } else {
1130 1153
                 /* move a char at a time */
1131
-                if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
1154
+                if(redata_line_realstart(re->data,cursorpos,&realstart)==-1)
1132 1155
                         return(-1); /* couldn't get current pos */
1133 1156
                 inc=(totalinc<0)?-1:1;
1134 1157
                 doneinc=0;
1135
-                if(redata_pos2linecol(re->data,re->cursorpos,NULL,&tmpcol)==-1)
1158
+                if(redata_pos2linecol(re->data,cursorpos,NULL,&tmpcol)==-1)
1136 1159
                         return(-1); /* couldn't get current pos */
1137 1160
                 /* special case: we're just over the '\n' going right, we have to move 1 to enable the generic case to work */
1138 1161
                 if(tmpcol==re->curcol && inc>0) {
1139
-                        if(redata_line_rawinfo(re->data,re->cursorpos,&start,&ptr,&len,NULL)==-1)
1162
+                        if(redata_line_rawinfo(re->data,cursorpos,&start,&ptr,&len,NULL)==-1)
1140 1163
                                 return(-1); /* couldn't get line data */
1141
-                        if(ptr[re->cursorpos-start]=='\n') {
1164
+                        if(ptr[cursorpos-start]=='\n') {
1142 1165
                                 tmpcol++;
1143 1166
                                 totalinc--;
1144 1167
                                 re->curcol++;
... ...
@@ -1155,7 +1178,7 @@ re_moveleftright(re_t *re, int totalinc)
1155 1178
                         }
1156 1179
                 }
1157 1180
                 /* generic case: move one char at a time */
1158
-                for(ptr=NULL,len=0,start=0,newpos=re->cursorpos;doneinc!=totalinc;) {
1181
+                for(ptr=NULL,len=0,start=0,newpos=cursorpos;doneinc!=totalinc;) {
1159 1182
                         if((newpos+inc)<realstart)
1160 1183
                                 break;
1161 1184
                         newpos+=inc;
... ...
@@ -1168,7 +1191,7 @@ re_moveleftright(re_t *re, int totalinc)
1168 1191
                         if(ptr[newpos-start]=='\n')
1169 1192
                                 break;
1170 1193
                 }
1171
-                re->cursorpos=newpos;
1194
+                cursorpos=newpos;
1172 1195
                 re->curcol+=doneinc;
1173 1196
                 if(inc>0 && doneinc<totalinc && ptr!=NULL && ptr[newpos-start]=='\n')
1174 1197
                         re->curcol+=(totalinc-doneinc);
... ...
@@ -1440,11 +1463,6 @@ re_rtrim(re_t *re, long curpos, int *trimmed)
1440 1463
                         n++;
1441 1464
                 /* delete the counted number of spaces at end of line */
1442 1465
                 redata_op_del(re->data,startpos+len-1-n,n,NULL);
1443
-                /* fix cursorpos if it is after the deleted characters or over one of the deleted characters */
1444
-                if(re->cursorpos>=(startpos+len-1))
1445
-                        re->cursorpos-=n;
1446
-                else if(re->cursorpos>=(startpos+len-1-n))
1447
-                        re->cursorpos=(startpos+len-1-n);
1448 1466
                 if(trimmed!=NULL)
1449 1467
                         *trimmed=n;
1450 1468
         }
... ...
@@ -1518,15 +1536,15 @@ re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingcha
1518 1536
 int
1519 1537
 re_drawheader_editing(re_t *re)
1520 1538
 {
1521
-        int line,col;
1539
+        long cursorpos;
1522 1540
         if(re==NULL)
1523 1541
                 return(-1);
1524
-        if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
1525
-                line=col=-1;
1542
+        if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1543
+                return(0); /* error obtaining position */
1526 1544
         reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG);
1527 1545
         /* for the user, lines start at 0 (internally they start at 0) */
1528
-        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li Size:%li %s"
1529
-          ,re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos,redata_getused(re->data)
1546
+        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i Col:%i Pos:%li Size:%li %s"
1547
+          ,re->filename,re->curline+1,re->curcol+1,cursorpos,redata_getused(re->data)
1530 1548
           ,"");
1531 1549
 #warning #error MAKE THE PREVIOUS LINE LAST %s print: "CHANGED" when unsaved&not-in-reu, "changed" when unsaved but is in reu, "saved" when it is saved.
1532 1550
         re->headerdirty=0;
... ...
@@ -1595,11 +1613,14 @@ re_drawcontents(re_t *re)
1595 1613
         int matchingpos;
1596 1614
         char matchingchar;
1597 1615
         int mline,mcol;
1616
+        long cursorpos;
1598 1617
         const char *hint;
1599 1618
         const char selcolornormal[]={"\xde\xcf\x7f\xff"};
1600 1619
         const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
1601 1620
         if(re==NULL)
1602 1621
                 return(-1);
1622
+        if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
1623
+                return(0); /* error obtaining position */
1603 1624
 #if 0
1604 1625
 fprintf(stderr,"re_drawcontents: pre  reuifill1\n");
1605 1626
 #endif
... ...
@@ -1608,7 +1629,7 @@ fprintf(stderr,"re_drawcontents: pre  reuifill1\n");
1608 1629
 fprintf(stderr,"re_drawcontents: post reuifill1\n");
1609 1630
 #endif
1610 1631
         row=re->curline-re->originline;
1611
-        pos=re->cursorpos;
1632
+        pos=cursorpos;
1612 1633
         while(row>0 && pos>0) {
1613 1634
                 if(redata_line_rawinfo(re->data,pos,&newpos,NULL,NULL,&is_continuation)==-1)
1614 1635
                         return(-1);
... ...
@@ -1719,7 +1740,7 @@ fprintf(stderr,"\n");
1719 1740
                                         reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,utf8charlen);
1720 1741
                                         /* get matching braces/parens/anglebracket/curlybraces for highlighting */
1721 1742
                                         if(utf8charlen==1 && strchr("[]{}<>()",*curptr)!=NULL)
1722
-                                                matchingpos=re_getmatchingbracket(re,re->cursorpos,*curptr,&matchingchar);
1743
+                                                matchingpos=re_getmatchingbracket(re,cursorpos,*curptr,&matchingchar);
1723 1744
                                 }
1724 1745
                         }
1725 1746
                 }
... ...
@@ -1751,7 +1772,7 @@ fprintf(stderr,"\n");
1751 1772
                         reui_balloon(re->ui, '\0', x,y, fg, bg, &matchingchar,1);
1752 1773
         }
1753 1774
         /* display prototypes info if applicable */
1754
-        hint=redata_prototypes_get(re->data, re->cursorpos);
1775
+        hint=redata_prototypes_get(re->data, cursorpos);
1755 1776
         if(hint!=NULL) {
1756 1777
                 if((re->curline-re->originline)>=(re->maxrow/2))
1757 1778
                         reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
Browse code

Connect save to F2 and to Control+S

Dario Rodriguez authored on 30/11/2020 18:09:55
Showing 1 changed files
... ...
@@ -680,18 +680,23 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
680 680
                 re->headerdirty=1;
681 681
                 re->contentsdirty=1;
682 682
         } else if(event->key.keysym.sym==SDLK_q && (SDL_GetModState()&KMOD_CTRL)!=0) {
683
-fprintf(stderr,"re_processkey(): received Control+q\n");
684 683
                 re->command="";
685 684
                 re->command_first_key='q';
686 685
                 re->headerdirty=1;
686
+        } else if(event->key.keysym.sym==SDLK_F2 || (event->key.keysym.sym==SDLK_s && (SDL_GetModState()&KMOD_CTRL)!=0)) {
687
+                char *errormsg=NULL;
688
+                if(redata_save(re->data,re->filename,&errormsg)!=-1)
689
+                        errormsg="File saved";
690
+                re->command=COMMAND_WARNING;
691
+                snprintf(re->commandbuf,sizeof(re->commandbuf),errormsg);
692
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
693
+                re->headerdirty=1;
687 694
         } else if(event->key.keysym.sym==SDLK_k && (SDL_GetModState()&KMOD_CTRL)!=0) {
688
-fprintf(stderr,"re_processkey(): received Control+k\n");
689 695
                 re->command="";
690 696
                 re->command_first_key='k';
691 697
                 re->headerdirty=1;
692 698
         } else if(event->key.keysym.sym==SDLK_z && (SDL_GetModState()&KMOD_CTRL)!=0) {
693 699
                 long newpos;
694
-fprintf(stderr,"re_processkey(): received Control+z\n");
695 700
                 if(redata_op_undo(re->data,&newpos))
696 701
                         return(-1);
697 702
                 re->cursorpos=newpos;
... ...
@@ -701,7 +706,6 @@ fprintf(stderr,"re_processkey(): received Control+z\n");
701 706
                 re->contentsdirty=1;
702 707
         } else if(event->key.keysym.sym==SDLK_l && (SDL_GetModState()&KMOD_CTRL)!=0 && re->cachelastsearch[0]!='\0') {
703 708
                 long newpos;
704
-fprintf(stderr,"re_processkey(): received Control+l\n");
705 709
                 /* search next (forward) */
706 710
                 if((newpos=redata_searchforward(re->data,re->cursorpos+1,re->cachelastsearch,strlen(re->cachelastsearch)))==-1) {
707 711
                         re->command=COMMAND_WARNING;
... ...
@@ -716,23 +720,19 @@ fprintf(stderr,"re_processkey(): received Control+l\n");
716 720
                 re->headerdirty=1;
717 721
                 re->contentsdirty=1;
718 722
         } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
719
-fprintf(stderr,"re_processkey(): received Control+'+'\n");
720 723
                 re_changefontsize(re, 1);
721 724
                 re->ignorenkeys++;
722 725
         } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
723
-fprintf(stderr,"re_processkey(): received Control+'-'\n");
724 726
                 re_changefontsize(re, -1);
725 727
                 re->ignorenkeys++;
726 728
         } else if(event->key.keysym.sym==SDLK_0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
727
-fprintf(stderr,"re_processkey(): received Control+'0'\n");
728 729
                 re_changefontsize(re, 0);
729 730
                 re->ignorenkeys++;
730 731
         } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
731 732
                 long frompos,topos;
732 733
                 int coldone;
733 734
                 int is_cut=(event->key.keysym.sym==SDLK_x)?1:0;
734
-fprintf(stderr,"re_processkey(): received Control+%c\n",is_cut?'x':'c');
735
-                /* CUA92-style copy (ctrl+c) / cut (ctrl+x) */
735
+                /* Mac-HIG/OpenLook-style copy (ctrl+c) / cut (ctrl+x) */
736 736
                 if(re->selactive
737 737
                   && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
738 738
                   && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
... ...
@@ -753,7 +753,7 @@ fprintf(stderr,"re_processkey(): received Control+%c\n",is_cut?'x':'c');
753 753
                 re->ignorenkeys++;
754 754
         } else if(event->key.keysym.sym==SDLK_v && (SDL_GetModState()&KMOD_CTRL)!=0) {
755 755
 fprintf(stderr,"re_processkey(): received Control+v\n");
756
-                /* CUA92-style paste (ctrl+v)*/
756
+                /* Mac-HIG/OpenLook-style paste (ctrl+v)*/
757 757
                 if(re->selactive)
758 758
                         re_sel_toggle(re);
759 759
                 if(SDL_HasClipboardText())
... ...
@@ -1023,16 +1023,10 @@ re_processcommand(re_t *re)
1023 1023
                   ;(oldpos+slen)<endpos && (newpos=redata_searchforward(re->data,oldpos,re->cachelastsearch,slen))!=-1
1024 1024
                     && (newpos+slen)<=endpos
1025 1025
                   ;total++,oldpos=newpos+rlen) {
1026
-#if 1
1027
-fprintf(stderr,"substituting %i bytes for %i bytes ar position:%li\n",slen,rlen,newpos);
1028
-#endif
1029 1026
                         redata_op_del(re->data,newpos,slen,NULL);
1030 1027
                         redata_op_add(re->data,newpos,re->cachelastreplacewith,rlen,NULL);
1031 1028
                 }
1032 1029
                 redata_undo_groupcommit(re->data,NULL);
1033
-#if 1
1034
-fprintf(stderr,"oldpos:%li\n",oldpos);
1035
-#endif
1036 1030
                 re->cursorpos=oldpos;
1037 1031
                 redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
1038 1032
                 re_fixorigin_center(re);
... ...
@@ -1531,7 +1525,10 @@ re_drawheader_editing(re_t *re)
1531 1525
                 line=col=-1;
1532 1526
         reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG);
1533 1527
         /* for the user, lines start at 0 (internally they start at 0) */
1534
-        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li Size:%li",re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos,redata_getused(re->data));
1528
+        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li Size:%li %s"
1529
+          ,re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos,redata_getused(re->data)
1530
+          ,"");
1531
+#warning #error MAKE THE PREVIOUS LINE LAST %s print: "CHANGED" when unsaved&not-in-reu, "changed" when unsaved but is in reu, "saved" when it is saved.
1535 1532
         re->headerdirty=0;
1536 1533
         re->ui->rendererdirty=1;
1537 1534
         return(0);
Browse code

Implement search-and-replace

Dario Rodriguez authored on 29/11/2020 22:22:12
Showing 1 changed files
... ...
@@ -73,6 +73,7 @@ typedef struct re_t {
73 73
         char *command;
74 74
         char commandbuf[COMMANDBUFSIZE];
75 75
         char cachelastsearch[COMMANDBUFSIZE];
76
+        char cachelastreplacewith[COMMANDBUFSIZE];
76 77
         question_t *question;
77 78
         int showingwarning;
78 79
         int ignorenkeys;
... ...
@@ -85,6 +86,7 @@ volatile int flag_sigpipe;
85 86
 static int setsignal(int num, void (*sighandler)(int));
86 87
 static void sighandler_sigint(int num);
87 88
 static void sighandler_sigpipe(int num);
89
+static int mystricmp(const char *s1, const char *s2);
88 90
 
89 91
 
90 92
 re_t *re_init(void);
... ...
@@ -324,6 +326,23 @@ sighandler_sigpipe(int num)
324 326
         flag_sigpipe=1;
325 327
 }
326 328
 
329
+static int
330
+mystricmp(const char *s1, const char *s2)
331
+{
332
+        int c1,c2;
333
+        for(;*s1!='\0' && *s2!='\0';s1++,s2++) {
334
+                if(*s1==*s2)
335
+                        continue;
336
+                c1=*((unsigned char *)s1);
337
+                c2=*((unsigned char *)s2);
338
+                c1=(c1>='A' && c1<='Z')?c1-'A'+'a':c1;
339
+                c2=(c2>='A' && c2<='Z')?c2-'A'+'a':c2;
340
+                if(c1==c2)
341
+                        continue;
342
+                return(c1-c2);
343
+        }
344
+        return(((int) (*((unsigned char *)s1)))-((int) (*((unsigned char *)s2))));
345
+}
327 346
 
328 347
 re_t *
329 348
 re_init(void)
... ...
@@ -772,7 +791,11 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
772 791
                 strncpy(re->commandbuf,re->cachelastsearch,sizeof(re->commandbuf));
773 792
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
774 793
                 re->headerdirty=1;
775
-#warning TODO: Search and replace (control+q+a)
794
+        } else if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_a) {
795
+                re->command=COMMAND_REPLACEWHAT;
796
+                strncpy(re->commandbuf,re->cachelastsearch,sizeof(re->commandbuf));
797
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
798
+                re->headerdirty=1;
776 799
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
777 800
                 re->command=COMMAND_EXIT;
778 801
                 re->commandbuf[0]='\0';
... ...
@@ -947,6 +970,79 @@ re_processcommand(re_t *re)
947 970
                 re_fixorigin_center(re);
948 971
                 re->headerdirty=1;
949 972
                 re->contentsdirty=1;
973
+        } else if(strcmp(re->command,COMMAND_REPLACEWHAT)==0) {
974
+                re->command=COMMAND_REPLACEWITH;
975
+                strncpy(re->cachelastsearch,re->commandbuf,sizeof(re->cachelastsearch));
976
+                re->cachelastsearch[sizeof(re->cachelastsearch)-1]='\0';
977
+                strncpy(re->commandbuf,re->cachelastreplacewith,sizeof(re->commandbuf));
978
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
979
+                re->headerdirty=1;
980
+                return(0);
981
+        } else if(strcmp(re->command,COMMAND_REPLACEWITH)==0) {
982
+                re->command=COMMAND_REPLACEHOW;
983
+                strncpy(re->cachelastreplacewith,re->commandbuf,sizeof(re->cachelastreplacewith));
984
+                re->cachelastreplacewith[sizeof(re->cachelastreplacewith)-1]='\0';
985
+                re->commandbuf[0]='\0';
986
+                re->headerdirty=1;
987
+                return(0);
988
+        } else if(strcmp(re->command,COMMAND_REPLACEHOW)==0) {
989
+                int is_all;
990
+                int slen,rlen;
991
+                long oldpos,newpos,endpos;
992
+                long total;
993
+                is_all=(mystricmp(re->commandbuf,"ean")==0)?1:(mystricmp(re->commandbuf,"san")==0)?0:-1;
994
+                if(is_all==-1) {
995
+                        re->command=COMMAND_WARNING;
996
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"Sorry, unimplemented. For now use only EAN or SAN options.");
997
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
998
+                        re->headerdirty=1;
999
+                        return(-1);
1000
+                }
1001
+                if(is_all==0 && !re->selactive) {
1002
+                        re->command=COMMAND_WARNING;
1003
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"No active selection, nothing changed.");
1004
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1005
+                        re->headerdirty=1;
1006
+                        return(-1);
1007
+                }
1008
+                oldpos=0;
1009
+                endpos=redata_getused(re->data);
1010
+                if(!is_all
1011
+                  && (redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&oldpos,NULL)!=0
1012
+                  || redata_linecol2pos(re->data,re->sellineto,re->selcolto,&endpos,NULL)!=0)) {
1013
+                        re->command=COMMAND_WARNING;
1014
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"Invalid selection.");
1015
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1016
+                        re->headerdirty=1;
1017
+                        return(-1);
1018
+                }
1019
+                slen=strlen(re->cachelastsearch);
1020
+                rlen=strlen(re->cachelastreplacewith);
1021
+                redata_undo_groupinit(re->data,NULL);
1022
+                for(total=0
1023
+                  ;(oldpos+slen)<endpos && (newpos=redata_searchforward(re->data,oldpos,re->cachelastsearch,slen))!=-1
1024
+                    && (newpos+slen)<=endpos
1025
+                  ;total++,oldpos=newpos+rlen) {
1026
+#if 1
1027
+fprintf(stderr,"substituting %i bytes for %i bytes ar position:%li\n",slen,rlen,newpos);
1028
+#endif
1029
+                        redata_op_del(re->data,newpos,slen,NULL);
1030
+                        redata_op_add(re->data,newpos,re->cachelastreplacewith,rlen,NULL);
1031
+                }
1032
+                redata_undo_groupcommit(re->data,NULL);
1033
+#if 1
1034
+fprintf(stderr,"oldpos:%li\n",oldpos);
1035
+#endif
1036
+                re->cursorpos=oldpos;
1037
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
1038
+                re_fixorigin_center(re);
1039
+                re->headerdirty=1;
1040
+                re->contentsdirty=1;
1041
+                re->command=COMMAND_WARNING;
1042
+                snprintf(re->commandbuf,sizeof(re->commandbuf),"%li subst",total);
1043
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
1044
+                re->headerdirty=1;
1045
+                return(0);
950 1046
         } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
951 1047
                 /* validate reply */
952 1048
                 if(!(atoi(re->commandbuf)>0 && atoi(re->commandbuf)<=re->question->nopts)) {
Browse code

indent/unindent selection with ALT+RIGHT/ALT+LEFT

Dario Rodriguez authored on 28/11/2020 22:16:21
Showing 1 changed files
... ...
@@ -103,10 +103,12 @@ int re_moveleftright(re_t *re, int totalinc);
103 103
 int re_changefontsize(re_t *re, int direction);
104 104
 int re_sel_setstart(re_t *re, int line, int col);
105 105
 int re_sel_setend(re_t *re, int line, int col);
106
+int re_sel_resize(re_t *re,int oldcol,int oldline,int direction);
106 107
 int re_sel_toggle(re_t *re);
107 108
 int re_sel_lincolisinside(re_t *re, int line, int col);
108 109
 int re_sel_lincolisbefore(re_t *re, int line, int col);
109 110
 int re_sel_lincolisafter(re_t *re, int line, int col);
111
+int re_sel_lincolisend(re_t *re, int line, int col);
110 112
 int re_selectbuf_resize(re_t *re,long size);
111 113
 int re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces);
112 114
 int re_selectbuf_replace(re_t *re,char *newdata);
... ...
@@ -356,7 +358,7 @@ re_free(re_t *re)
356 358
         if(re->data!=NULL)
357 359
                 redata_free(re->data),re->data=NULL;
358 360
         if(re->selectbuf!=NULL)
359
-                free(re->selectbuf),re->selectbuf=NULL,re->usedselectbuf=re->sizeselectbuf=NULL;
361
+                free(re->selectbuf),re->selectbuf=NULL,re->usedselectbuf=re->sizeselectbuf=0;
360 362
         free(re),re=NULL;
361 363
         return;
362 364
 }
... ...
@@ -547,32 +549,37 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed
547 549
 #if 0
548 550
 fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
549 551
 #endif
550
-        if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
551
-#warning #error BUG: Played with selections a bit, resized font twice, go down a lot of lines, when after about last line previously displayed it segfaulted
552
-                int oldcol=re->curline,oldline=re->curcol;
552
+        if((SDL_GetModState()&KMOD_ALT)!=0 && re->selactive && (event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT)) {
553
+                int l;
554
+                int is_del;
555
+                int tolinefix;
556
+                long pos,pos2;
557
+                is_del=(event->key.keysym.sym==SDLK_LEFT)?1:0;
558
+                redata_undo_groupinit(re->data,NULL);
559
+                tolinefix=(re->selcolto==0)?1:0;
560
+                for(l=re->sellinefrom;l<=(re->sellineto-tolinefix);l++) {
561
+                        if(redata_linecol2pos(re->data,l,0,&pos,NULL)!=0)
562
+                                continue;
563
+                        if(is_del==1 && redata_linecol2pos(re->data,l,1,&pos2,NULL)!=0)
564
+                                continue;
565
+                        if(!is_del)
566
+                                redata_op_add(re->data,pos," ",1,NULL);
567
+                        else if(pos!=pos2)
568
+                                redata_op_del(re->data,pos,pos2-pos,NULL);
569
+                }
570
+                redata_undo_groupcommit(re->data,NULL);
571
+                redata_linecol2pos(re->data,re->curline,re->curcol,&(re->cursorpos),NULL);
572
+                re->headerdirty=1;
573
+                re->contentsdirty=1;
574
+        } else if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
575
+                int oldcol=re->curcol,oldline=re->curline;
553 576
                 if(re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
554
-                        if(event->key.keysym.sym==SDLK_UP) {
555
-                                if(re->selactive==0 || re_sel_lincolisafter(re,oldcol,oldline))
556
-                                        re_sel_setend(re,oldcol,oldline);
557
-                                re_sel_setstart(re,re->curline,re->curcol);
558
-                        } else {
559
-                                if(re->selactive==0 || re_sel_lincolisbefore(re,oldcol,oldline))
560
-                                        re_sel_setstart(re,oldcol,oldline);
561
-                                re_sel_setend(re,re->curline,re->curcol);
562
-                        }
577
+                        re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_UP)?-1:1);
563 578
                 }
564 579
         } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
565
-                int oldcol=re->curline,oldline=re->curcol;
580
+                int oldcol=re->curcol,oldline=re->curline;
566 581
                 if(re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
567
-                        if(event->key.keysym.sym==SDLK_LEFT) {
568
-                                if(re->selactive==0 || re_sel_lincolisafter(re,oldcol,oldline))
569
-                                        re_sel_setend(re,oldcol,oldline);
570
-                                re_sel_setstart(re,re->curline,re->curcol);
571
-                        } else {
572
-                                if(re->selactive==0 || re_sel_lincolisbefore(re,oldcol,oldline))
573
-                                        re_sel_setstart(re,oldcol,oldline);
574
-                                re_sel_setend(re,re->curline,re->curcol);
575
-                        }
582
+                        re_sel_resize(re,oldcol,oldline,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
576 583
                 }
577 584
         } else if((SDL_GetModState()&KMOD_CTRL)!=0 && (event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP)) {
578 585
                 re->cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
... ...
@@ -702,7 +709,8 @@ fprintf(stderr,"re_processkey(): received Control+'0'\n");
702 709
                 re_changefontsize(re, 0);
703 710
                 re->ignorenkeys++;
704 711
         } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
705
-                long frompos,topos,coldone;
712
+                long frompos,topos;
713
+                int coldone;
706 714
                 int is_cut=(event->key.keysym.sym==SDLK_x)?1:0;
707 715
 fprintf(stderr,"re_processkey(): received Control+%c\n",is_cut?'x':'c');
708 716
                 /* CUA92-style copy (ctrl+c) / cut (ctrl+x) */
... ...
@@ -782,7 +790,8 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
782 790
                 re->command=NULL;
783 791
                 re->headerdirty=1;
784 792
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_y) {
785
-                long frompos,topos,coldone;
793
+                long frompos,topos;
794
+                int coldone;
786 795
                 /* wordstar-style blockdel (ctrl+k+y) */
787 796
                 if(re->selactive
788 797
                   && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
... ...
@@ -1163,6 +1172,35 @@ re_sel_setend(re_t *re, int line, int col)
1163 1172
         return(0);
1164 1173
 }
1165 1174
 
1175
+int
1176
+re_sel_resize(re_t *re,int oldcol,int oldline,int direction)
1177
+{
1178
+        if(re==NULL || oldcol<0 || oldline<0 || (direction!=-1 && direction!=1))
1179
+                return(-1);
1180
+        if(direction==-1) {
1181
+                if(re->selactive==0) {
1182
+                        re_sel_setstart(re,re->curline,re->curcol);
1183
+                        re_sel_setend(re,oldline,oldcol);
1184
+                } else if(re_sel_lincolisafter(re,re->curline,re->curcol) || re_sel_lincolisinside(re,re->curline,re->curcol)) {
1185
+                        re_sel_setend(re,re->curline,re->curcol);
1186
+                } else {
1187
+                        re_sel_setstart(re,re->curline,re->curcol);
1188
+                }
1189
+        } else {
1190
+                if(re->selactive==0 || re_sel_lincolisbefore(re,oldline,oldcol)) {
1191
+                        re_sel_setstart(re,oldline,oldcol);
1192
+                        re_sel_setend(re,re->curline,re->curcol);
1193
+                } else if(re_sel_lincolisinside(re,oldline,oldcol)) {
1194
+                        re_sel_setstart(re,re->curline,re->curcol);
1195
+                } else {
1196
+                        re_sel_setend(re,re->curline,re->curcol);
1197
+                }
1198
+        }
1199
+        if(re->sellinefrom==re->sellineto && re->selcolfrom==re->selcolto)
1200
+                re->selactive=0;
1201
+        return(0);
1202
+}
1203
+
1166 1204
 int
1167 1205
 re_sel_toggle(re_t *re)
1168 1206
 {
... ...
@@ -1216,6 +1254,17 @@ re_sel_lincolisafter(re_t *re, int line, int col)
1216 1254
         return(0);
1217 1255
 }
1218 1256
 
1257
+int
1258
+re_sel_lincolisend(re_t *re, int line, int col)
1259
+{
1260
+        if(re==NULL || line<0 || col<0)
1261
+                return(0);
1262
+        if(line==re->sellineto && col==re->selcolto)
1263
+                return(1);
1264
+        return(0);
1265
+}
1266
+
1267
+
1219 1268
 int
1220 1269
 re_selectbuf_resize(re_t *re,long size)
1221 1270
 {
Browse code

Make Control+C/X/V to use the clipboard

Dario Rodriguez authored on 25/11/2020 22:13:13
Showing 1 changed files
... ...
@@ -107,7 +107,9 @@ int re_sel_toggle(re_t *re);
107 107
 int re_sel_lincolisinside(re_t *re, int line, int col);
108 108
 int re_sel_lincolisbefore(re_t *re, int line, int col);
109 109
 int re_sel_lincolisafter(re_t *re, int line, int col);
110
+int re_selectbuf_resize(re_t *re,long size);
110 111
 int re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces);
112
+int re_selectbuf_replace(re_t *re,char *newdata);
111 113
 int re_rtrim(re_t *re, long curpos, int *trimmed);
112 114
 long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
113 115
 int re_drawheader_editing(re_t *re);
... ...
@@ -708,6 +710,7 @@ fprintf(stderr,"re_processkey(): received Control+%c\n",is_cut?'x':'c');
708 710
                   && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
709 711
                   && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
710 712
                         re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
713
+                        SDL_SetClipboardText(re->selectbuf);
711 714
                         if(is_cut) {
712 715
                                 redata_undo_groupinit(re->data,NULL);
713 716
                                 redata_op_del(re->data,frompos,topos-frompos,NULL);
... ...
@@ -726,6 +729,8 @@ fprintf(stderr,"re_processkey(): received Control+v\n");
726 729
                 /* CUA92-style paste (ctrl+v)*/
727 730
                 if(re->selactive)
728 731
                         re_sel_toggle(re);
732
+                if(SDL_HasClipboardText())
733
+                        re_selectbuf_replace(re,SDL_GetClipboardText());
729 734
                 if(re->usedselectbuf>0) {
730 735
                         redata_undo_groupinit(re->data,NULL);
731 736
                         redata_op_add(re->data,re->cursorpos,re->selectbuf,re->usedselectbuf,NULL);
... ...
@@ -765,9 +770,6 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
765 770
                 re->commandbuf[0]='\0';
766 771
                 re->headerdirty=1;
767 772
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_h) {
768
-#warning #error TODO: IF Ctrl+C, get a buffer of the right size into re (re->selectbuf), use redata_extract() to get those bytes into the buffer
769
-#warning #error TODO: IF Ctrl+X, do as in Ctrl+X, but delete the bytes from redata afterwards
770
-#warning #error TODO: IF Ctrl+V, insert the bytes in re->selectbuf into the curent cursor pos
771 773
                 re_sel_toggle(re);
772 774
                 re->command=NULL;
773 775
                 re->headerdirty=1;
... ...
@@ -1214,6 +1216,24 @@ re_sel_lincolisafter(re_t *re, int line, int col)
1214 1216
         return(0);
1215 1217
 }
1216 1218
 
1219
+int
1220
+re_selectbuf_resize(re_t *re,long size)
1221
+{
1222
+        long newsize;
1223
+        char *newptr;
1224
+        if(re==NULL || size<0)
1225
+                return(-1); /* sanity check failed */
1226
+        if(size==0)
1227
+                return(0); /* nothing to do */
1228
+        newsize=(size+SELECTBUFBLOCK-1)/SELECTBUFBLOCK;
1229
+        newsize*=SELECTBUFBLOCK;
1230
+        if((newptr=realloc(re->selectbuf,newsize))==NULL)
1231
+                return(-1);
1232
+        re->selectbuf=newptr;
1233
+        re->sizeselectbuf=newsize;
1234
+        return(0);
1235
+}
1236
+
1217 1237
 int
1218 1238
 re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces)
1219 1239
 {
... ...
@@ -1222,15 +1242,9 @@ re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces)
1222 1242
         if(re==NULL || size<0 || nadditionalspaces<0 || (frompos+size)>redata_getused(re->data) || redata_getposptr(re->data,frompos,&nchunk,&off)!=0)
1223 1243
                 return(-1); /* sanity check failed */
1224 1244
         re->usedselectbuf=0;
1225
-        if((size+nadditionalspaces)>re->sizeselectbuf) {
1226
-                long newsize;
1227
-                char *newptr;
1228
-                newsize=(size+nadditionalspaces+SELECTBUFBLOCK-1)/SELECTBUFBLOCK;
1229
-                newsize*=SELECTBUFBLOCK;
1230
-                if((newptr=realloc(re->selectbuf,newsize))==NULL)
1231
-                        return(-1);
1232
-                re->selectbuf=newptr;
1233
-                re->sizeselectbuf=newsize;
1245
+        if((size+nadditionalspaces+1)>re->sizeselectbuf
1246
+          && re_selectbuf_resize(re,size+nadditionalspaces+1)!=0) {
1247
+                return(-1); /* insuf. mem. */
1234 1248
         }
1235 1249
         for(n=0;n<size && nchunk<re->data->sizechunks;nchunk++,off=0) {
1236 1250
                 avail=re->data->chunks[nchunk]->useddata-off;
... ...
@@ -1246,6 +1260,24 @@ re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces)
1246 1260
                 memset(re->selectbuf+re->usedselectbuf,' ',nadditionalspaces);
1247 1261
                 re->usedselectbuf+=nadditionalspaces;
1248 1262
         }
1263
+        re->selectbuf[re->usedselectbuf]='\0';
1264
+        return(0);
1265
+}
1266
+
1267
+int
1268
+re_selectbuf_replace(re_t *re,char *newdata)
1269
+{
1270
+        long size;
1271
+        if(re==NULL || newdata==NULL)
1272
+                return(-1);
1273
+        size=strlen(newdata);
1274
+        if((size+1)>re->sizeselectbuf
1275
+          && re_selectbuf_resize(re,size+1)!=0) {
1276
+                return(-1); /* insuf. mem. */
1277
+        }
1278
+        memcpy(re->selectbuf,newdata,size);
1279
+        re->usedselectbuf=size;
1280
+        re->selectbuf[re->usedselectbuf]='\0';
1249 1281
         return(0);
1250 1282
 }
1251 1283
 
... ...
@@ -1547,7 +1579,6 @@ fprintf(stderr,"\n");
1547 1579
                                         if(utf8charlen==1 && strchr("[]{}<>()",*curptr)!=NULL)
1548 1580
                                                 matchingpos=re_getmatchingbracket(re,re->cursorpos,*curptr,&matchingchar);
1549 1581
                                 }
1550
-#warning TODO: Select(control+k+b/control+k+k/...)
1551 1582
                         }
1552 1583
                 }
1553 1584
                 if(row==(re->curline-re->originline) && !drawn_cursor)
Browse code

implement CUA92-style copy/cut/paste

Dario Rodriguez authored on 23/11/2020 22:59:53
Showing 1 changed files
... ...
@@ -699,6 +699,44 @@ fprintf(stderr,"re_processkey(): received Control+'-'\n");
699 699
 fprintf(stderr,"re_processkey(): received Control+'0'\n");
700 700
                 re_changefontsize(re, 0);
701 701
                 re->ignorenkeys++;
702
+        } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
703
+                long frompos,topos,coldone;
704
+                int is_cut=(event->key.keysym.sym==SDLK_x)?1:0;
705
+fprintf(stderr,"re_processkey(): received Control+%c\n",is_cut?'x':'c');
706
+                /* CUA92-style copy (ctrl+c) / cut (ctrl+x) */
707
+                if(re->selactive
708
+                  && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
709
+                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
710
+                        re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
711
+                        if(is_cut) {
712
+                                redata_undo_groupinit(re->data,NULL);
713
+                                redata_op_del(re->data,frompos,topos-frompos,NULL);
714
+                                redata_undo_groupcommit(re->data,NULL);
715
+                                re->cursorpos=frompos;
716
+                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
717
+                                re_fixorigin(re);
718
+                                re->headerdirty=1;
719
+                        }
720
+                        re_sel_toggle(re);
721
+                        re->contentsdirty=1;
722
+                }
723
+                re->ignorenkeys++;
724
+        } else if(event->key.keysym.sym==SDLK_v && (SDL_GetModState()&KMOD_CTRL)!=0) {
725
+fprintf(stderr,"re_processkey(): received Control+v\n");
726
+                /* CUA92-style paste (ctrl+v)*/
727
+                if(re->selactive)
728
+                        re_sel_toggle(re);
729
+                if(re->usedselectbuf>0) {
730
+                        redata_undo_groupinit(re->data,NULL);
731
+                        redata_op_add(re->data,re->cursorpos,re->selectbuf,re->usedselectbuf,NULL);
732
+                        redata_undo_groupcommit(re->data,NULL);
733
+                        re->cursorpos+=re->usedselectbuf;
734
+                        redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
735
+                        re_fixorigin(re);
736
+                        re->headerdirty=1;
737
+                        re->contentsdirty=1;
738
+                }
739
+                re->ignorenkeys++;
702 740
         }
703 741
         return(0);
704 742
 }
Browse code

implement selections and wordstar-style cut/copy/move of selection

Dario Rodriguez authored on 22/11/2020 23:17:44
Showing 1 changed files
... ...
@@ -28,7 +28,8 @@
28 28
 #define IDLETIMEOUTSECONDS 10
29 29
 
30 30
 #define COMMANDBUFSIZE 1024
31
-#define DEFAULTFONTHEIGHT 16
31
+#define DEFAULTFONTHEIGHT 14
32
+#define SELECTBUFBLOCK 16384
32 33
 
33 34
 #define COMMAND_WARNING "(!)"
34 35
 #define COMMAND_GOTOLINE "Go to line:"
... ...
@@ -63,6 +64,12 @@ typedef struct re_t {
63 64
         int headerdirty;
64 65
         int contentsdirty;
65 66
         int command_first_key;
67
+        int selactive;
68
+        int sellinefrom,sellineto;
69
+        int selcolfrom,selcolto;
70
+        long sizeselectbuf;
71
+        long usedselectbuf;
72
+        char *selectbuf;
66 73
         char *command;
67 74
         char commandbuf[COMMANDBUFSIZE];
68 75
         char cachelastsearch[COMMANDBUFSIZE];
... ...
@@ -94,13 +101,19 @@ int re_processcommand(re_t *re);
94 101
 int re_moveupdown(re_t *re, int totalinc);
95 102
 int re_moveleftright(re_t *re, int totalinc);
96 103
 int re_changefontsize(re_t *re, int direction);
104
+int re_sel_setstart(re_t *re, int line, int col);
105
+int re_sel_setend(re_t *re, int line, int col);
106
+int re_sel_toggle(re_t *re);
107
+int re_sel_lincolisinside(re_t *re, int line, int col);
108
+int re_sel_lincolisbefore(re_t *re, int line, int col);
109
+int re_sel_lincolisafter(re_t *re, int line, int col);
110
+int re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces);
97 111
 int re_rtrim(re_t *re, long curpos, int *trimmed);
98 112
 long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
99 113
 int re_drawheader_editing(re_t *re);
100 114
 int re_drawheader_command(re_t *re);
101 115
 int re_drawcontents(re_t *re);
102 116
 
103
-
104 117
 int
105 118
 main(int argc, char *argv[])
106 119
 {
... ...
@@ -340,6 +353,8 @@ re_free(re_t *re)
340 353
                 reui_free(re->ui),re->ui=NULL;
341 354
         if(re->data!=NULL)
342 355
                 redata_free(re->data),re->data=NULL;
356
+        if(re->selectbuf!=NULL)
357
+                free(re->selectbuf),re->selectbuf=NULL,re->usedselectbuf=re->sizeselectbuf=NULL;
343 358
         free(re),re=NULL;
344 359
         return;
345 360
 }
... ...
@@ -531,9 +546,32 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed
531 546
 fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
532 547
 #endif
533 548
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
534
-                re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1);
549
+#warning #error BUG: Played with selections a bit, resized font twice, go down a lot of lines, when after about last line previously displayed it segfaulted
550
+                int oldcol=re->curline,oldline=re->curcol;
551
+                if(re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
552
+                        if(event->key.keysym.sym==SDLK_UP) {
553
+                                if(re->selactive==0 || re_sel_lincolisafter(re,oldcol,oldline))
554
+                                        re_sel_setend(re,oldcol,oldline);
555
+                                re_sel_setstart(re,re->curline,re->curcol);
556
+                        } else {
557
+                                if(re->selactive==0 || re_sel_lincolisbefore(re,oldcol,oldline))
558
+                                        re_sel_setstart(re,oldcol,oldline);
559
+                                re_sel_setend(re,re->curline,re->curcol);
560
+                        }
561
+                }
535 562
         } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
536
-                re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
563
+                int oldcol=re->curline,oldline=re->curcol;
564
+                if(re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1)==0 && (SDL_GetModState()&KMOD_SHIFT)!=0 && (re->curcol!=oldcol || re->curline!=oldline)) {
565
+                        if(event->key.keysym.sym==SDLK_LEFT) {
566
+                                if(re->selactive==0 || re_sel_lincolisafter(re,oldcol,oldline))
567
+                                        re_sel_setend(re,oldcol,oldline);
568
+                                re_sel_setstart(re,re->curline,re->curcol);
569
+                        } else {
570
+                                if(re->selactive==0 || re_sel_lincolisbefore(re,oldcol,oldline))
571
+                                        re_sel_setstart(re,oldcol,oldline);
572
+                                re_sel_setend(re,re->curline,re->curcol);
573
+                        }
574
+                }
537 575
         } else if((SDL_GetModState()&KMOD_CTRL)!=0 && (event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP)) {
538 576
                 re->cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
539 577
                 re->cursorpos=(re->cursorpos<0)?0:re->cursorpos;
... ...
@@ -688,6 +726,87 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
688 726
                 re->command=COMMAND_EXIT;
689 727
                 re->commandbuf[0]='\0';
690 728
                 re->headerdirty=1;
729
+        } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_h) {
730
+#warning #error TODO: IF Ctrl+C, get a buffer of the right size into re (re->selectbuf), use redata_extract() to get those bytes into the buffer
731
+#warning #error TODO: IF Ctrl+X, do as in Ctrl+X, but delete the bytes from redata afterwards
732
+#warning #error TODO: IF Ctrl+V, insert the bytes in re->selectbuf into the curent cursor pos
733
+                re_sel_toggle(re);
734
+                re->command=NULL;
735
+                re->headerdirty=1;
736
+        } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_b) {
737
+                re_sel_setstart(re,re->curline,re->curcol);
738
+                re->command=NULL;
739
+                re->headerdirty=1;
740
+        } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_k) {
741
+                re_sel_setend(re,re->curline,re->curcol);
742
+                re->command=NULL;
743
+                re->headerdirty=1;
744
+        } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_y) {
745
+                long frompos,topos,coldone;
746
+                /* wordstar-style blockdel (ctrl+k+y) */
747
+                if(re->selactive
748
+                  && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
749
+                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&coldone)==0) {
750
+                        re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-coldone);
751
+                        redata_undo_groupinit(re->data,NULL);
752
+                        redata_op_del(re->data,frompos,topos-frompos,NULL);
753
+                        redata_undo_groupcommit(re->data,NULL);
754
+                        if(re->cursorpos>frompos) {
755
+                                re->cursorpos=frompos;
756
+                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
757
+                                re_fixorigin(re);
758
+                        }
759
+                        re->headerdirty=1;
760
+                        re->contentsdirty=1;
761
+                }
762
+                if(re->selactive)
763
+                        re_sel_toggle(re);
764
+                re->command=NULL;
765
+                re->headerdirty=1;
766
+        } else if(re->command_first_key=='k' && (event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_v)) {
767
+                long frompos,topos,insertpos;
768
+                int tocoldone,coldone;
769
+                /* wordstar-style blockcopy (ctrl+k+c) or move (ctrl+k+v)*/
770
+                int is_move=(event->key.keysym.sym==SDLK_v)?1:0;
771
+                if(re->selactive
772
+                  && redata_linecol2pos(re->data,re->sellinefrom,re->selcolfrom,&frompos,NULL)==0
773
+                  && redata_linecol2pos(re->data,re->sellineto,re->selcolto,&topos,&tocoldone)==0
774
+                  && redata_linecol2pos(re->data,re->curline,re->curcol,&insertpos,&coldone)==0
775
+                  && re_selectbuf_fill(re,frompos,topos-frompos,re->selcolto-tocoldone)==0
776
+                  && redata_preallocate(re->data,redata_getused(re->data)+(re->curcol-coldone)+(is_move?0:re->usedselectbuf))==0) {
777
+                        if(is_move && insertpos>=frompos && insertpos<topos) {
778
+                                re->curline=re->sellinefrom;
779
+                                re->curcol=re->selcolfrom;
780
+                                redata_linecol2pos(re->data,re->curline,re->curcol,&insertpos,&coldone);
781
+                        }
782
+                        redata_undo_groupinit(re->data,NULL);
783
+                        if(coldone<re->curcol
784
+                          && redata_op_addn(re->data,insertpos,' ',re->curcol-coldone,NULL)==0) {
785
+                                insertpos+=re->curcol-coldone;
786
+                        }
787
+                        if(is_move) {
788
+                                redata_op_del(re->data,frompos,re->usedselectbuf,NULL);
789
+                                redata_op_add(re->data,insertpos-((insertpos>frompos)?re->usedselectbuf:0),re->selectbuf,re->usedselectbuf,NULL);
790
+                                re->cursorpos=insertpos-((insertpos>frompos)?re->usedselectbuf:0)+re->usedselectbuf;
791
+                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
792
+                                redata_pos2linecol(re->data,re->cursorpos-re->usedselectbuf,&(re->sellinefrom),&(re->selcolfrom));
793
+                                re->sellineto=re->curline;
794
+                                re->selcolto=re->curcol;
795
+                        } else {
796
+                                redata_op_add(re->data,insertpos,re->selectbuf,re->usedselectbuf,NULL);
797
+                                re->cursorpos=insertpos+re->usedselectbuf;
798
+                                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
799
+                                redata_pos2linecol(re->data,insertpos,&(re->sellinefrom),&(re->selcolfrom));
800
+                                re->sellineto=re->curline;
801
+                                re->selcolto=re->curcol;
802
+                        }
803
+                        redata_undo_groupcommit(re->data,NULL);
804
+                        re_fixorigin(re);
805
+                        re->headerdirty=1;
806
+                        re->contentsdirty=1;
807
+                }
808
+                re->command=NULL;
809
+                re->headerdirty=1;
691 810
         } else {
692 811
                 re->command=NULL;
693 812
                 re->headerdirty=1;
... ...
@@ -968,6 +1087,130 @@ re_changefontsize(re_t *re, int direction)
968 1087
         return(0);
969 1088
 }
970 1089
 
1090
+int
1091
+re_sel_setstart(re_t *re, int line, int col)
1092
+{
1093
+        if(re==NULL || line<0 || col<0)
1094
+                return(-1);
1095
+        re->sellinefrom=line;
1096
+        re->selcolfrom=col;
1097
+        if(re->selactive==0
1098
+          || (re->sellineto<re->sellinefrom)
1099
+          || (re->sellineto==re->sellinefrom && re->selcolto<re->selcolfrom)) {
1100
+              re->sellineto=re->sellinefrom;
1101
+              re->selcolto=re->selcolfrom;
1102
+        }
1103
+        re->selactive=1;
1104
+        re->contentsdirty=1;
1105
+        return(0);
1106
+}
1107
+
1108
+int
1109
+re_sel_setend(re_t *re, int line, int col)
1110
+{
1111
+        if(re==NULL || line<0 || col<0)
1112
+                return(-1);
1113
+        re->sellineto=line;
1114
+        re->selcolto=col;
1115
+        if(re->selactive==0
1116
+          || (re->sellineto<re->sellinefrom)
1117
+          || (re->sellineto==re->sellinefrom && re->selcolto<re->selcolfrom)) {
1118
+              re->sellinefrom=re->sellineto;
1119
+              re->selcolfrom=re->selcolto;
1120
+        }
1121
+        re->selactive=1;
1122
+        re->contentsdirty=1;
1123
+        return(0);
1124
+}
1125
+
1126
+int
1127
+re_sel_toggle(re_t *re)
1128
+{
1129
+        if(re==NULL)
1130
+                return(-1);
1131
+        re->selactive=1-re->selactive;
1132
+        re->contentsdirty=1;
1133
+        return(0);
1134
+}
1135
+
1136
+int
1137
+re_sel_lincolisinside(re_t *re, int line, int col)
1138
+{
1139
+        if(re==NULL || line<0 || col<0)
1140
+                return(0);
1141
+        if(line==re->sellinefrom && line==re->sellineto) {
1142
+                if(col>=re->selcolfrom && col<re->selcolto)
1143
+                        return(1);
1144
+                return(0);
1145
+        } else if(line==re->sellinefrom) {
1146
+                if(col>=re->selcolfrom)
1147
+                        return(1);
1148
+                return(0);
1149
+        } else if(line>re->sellinefrom && line<re->sellineto) {
1150
+                return(1);
1151
+        } else if(line==re->sellineto) {
1152
+                if(col<re->selcolto)
1153
+                        return(1);
1154
+                return(0);
1155
+        }
1156
+        return(0);
1157
+}
1158
+
1159
+int
1160
+re_sel_lincolisbefore(re_t *re, int line, int col)
1161
+{
1162
+        if(re==NULL || line<0 || col<0)
1163
+                return(0);
1164
+        if(line<re->sellinefrom || (line==re->sellinefrom && col<re->selcolfrom))
1165
+                return(1);
1166
+        return(0);
1167
+}
1168
+
1169
+int
1170
+re_sel_lincolisafter(re_t *re, int line, int col)
1171
+{
1172
+        if(re==NULL || line<0 || col<0)
1173
+                return(0);
1174
+        if(line>re->sellineto || (line==re->sellineto && col>=re->selcolto))
1175
+                return(1);
1176
+        return(0);
1177
+}
1178
+
1179
+int
1180
+re_selectbuf_fill(re_t *re,long frompos,long size, int nadditionalspaces)
1181
+{
1182
+        int nchunk,off,avail;
1183
+        long n;
1184
+        if(re==NULL || size<0 || nadditionalspaces<0 || (frompos+size)>redata_getused(re->data) || redata_getposptr(re->data,frompos,&nchunk,&off)!=0)
1185
+                return(-1); /* sanity check failed */
1186
+        re->usedselectbuf=0;
1187
+        if((size+nadditionalspaces)>re->sizeselectbuf) {
1188
+                long newsize;
1189
+                char *newptr;
1190
+                newsize=(size+nadditionalspaces+SELECTBUFBLOCK-1)/SELECTBUFBLOCK;
1191
+                newsize*=SELECTBUFBLOCK;
1192
+                if((newptr=realloc(re->selectbuf,newsize))==NULL)
1193
+                        return(-1);
1194
+                re->selectbuf=newptr;
1195
+                re->sizeselectbuf=newsize;
1196
+        }
1197
+        for(n=0;n<size && nchunk<re->data->sizechunks;nchunk++,off=0) {
1198
+                avail=re->data->chunks[nchunk]->useddata-off;
1199
+                if(avail<=0)
1200
+                        continue;
1201
+                if(avail>(size-n))
1202
+                        avail=size-n;
1203
+                memcpy(re->selectbuf+n,re->data->chunks[nchunk]->data+off,avail);
1204
+                n+=avail;
1205
+        }
1206
+        re->usedselectbuf=n;
1207
+        if(nadditionalspaces>0) {
1208
+                memset(re->selectbuf+re->usedselectbuf,' ',nadditionalspaces);
1209
+                re->usedselectbuf+=nadditionalspaces;
1210
+        }
1211
+        return(0);
1212
+}
1213
+
971 1214
 
972 1215
 int
973 1216
 re_rtrim(re_t *re, long curpos, int *trimmed)
... ...
@@ -1124,7 +1367,7 @@ re_drawcontents(re_t *re)
1124 1367
         long pos,newpos;
1125 1368
         char *ptr;
1126 1369
         int len;
1127
-        int y,row;
1370
+        int y,row,tmprow;
1128 1371
         char *curptr;
1129 1372
         int curptrlen;
1130 1373
         int has_nl;
... ...
@@ -1141,9 +1384,17 @@ re_drawcontents(re_t *re)
1141 1384
         char matchingchar;
1142 1385
         int mline,mcol;
1143 1386
         const char *hint;
1387
+        const char selcolornormal[]={"\xde\xcf\x7f\xff"};
1388
+        const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
1144 1389
         if(re==NULL)
1145 1390
                 return(-1);
1391
+#if 0
1392
+fprintf(stderr,"re_drawcontents: pre  reuifill1\n");
1393
+#endif
1146 1394
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
1395
+#if 0
1396
+fprintf(stderr,"re_drawcontents: post reuifill1\n");
1397
+#endif
1147 1398
         row=re->curline-re->originline;
1148 1399
         pos=re->cursorpos;
1149 1400
         while(row>0 && pos>0) {
... ...
@@ -1154,7 +1405,50 @@ re_drawcontents(re_t *re)
1154 1405
                         row--;
1155 1406
         }
1156 1407
         /* highlight current line */
1408
+#if 0
1409
+fprintf(stderr,"re_drawcontents: pre  reuifill2\n");
1410
+#endif
1157 1411
         reui_fill(re->ui,re->x,re->y+(re->curline-re->originline)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
1412
+#if 0
1413
+fprintf(stderr,"re_drawcontents: post reuifill2\n");
1414
+#endif
1415
+        /* highlight the selection */
1416
+        if(re->selactive) {
1417
+                const char *selcolor;
1418
+                tmprow=row;
1419
+#if 0
1420
+fprintf(stderr,"re_drawcontents: reuifill3: ");
1421
+#endif
1422
+                for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1423
+                        selcolor=(row==(re->curline-re->originline))?selcolorcurline:selcolornormal;
1424
+                        if((re->originline+row)==re->sellinefrom && (re->originline+row)==re->sellineto) {
1425
+                                reui_fill(re->ui,re->x+(re->selcolfrom-re->origincol)*re->ui->fontwidth,re->y+row*re->ui->fontheight,(re->selcolto-re->selcolfrom)*re->ui->fontwidth,re->ui->fontheight+1,selcolor);
1426
+                        } else if((re->originline+row)==re->sellinefrom) {
1427
+                                int x1;
1428
+                                x1=re->x+(re->selcolfrom-re->origincol)*re->ui->fontwidth;
1429
+                                if(x1<(re->x+re->w))
1430
+                                        reui_fill(re->ui,x1,re->y+row*re->ui->fontheight,re->w-x1,re->ui->fontheight+1,selcolor);
1431
+                        } else if((re->originline+row)>re->sellinefrom && (re->originline+row)<re->sellineto) {
1432
+#if 0
1433
+fprintf(stderr,"{(ui,%i,%i,%i,%i,#%02X%02X%02X%02X)",re->x,re->y+row*re->ui->fontheight,re->w,re->ui->fontheight+1,((unsigned char *)selcolor)[0],((unsigned char *)selcolor)[1],((unsigned char *)selcolor)[2],((unsigned char *)selcolor)[3]);
1434
+#endif
1435
+                                reui_fill(re->ui,re->x,re->y+row*re->ui->fontheight,re->w,re->ui->fontheight+1,selcolor);
1436
+#if 0
1437
+fprintf(stderr,"}");
1438
+#endif
1439
+                        } else if((re->originline+row)==re->sellineto) {
1440
+                                int x2;
1441
+                                x2=re->x+(re->selcolto-re->origincol)*re->ui->fontwidth;
1442
+                                if(x2>(re->x))
1443
+                                        reui_fill(re->ui,re->x,re->y+row*re->ui->fontheight,x2-re->x,re->ui->fontheight+1,selcolor);
1444
+                        }
1445
+
1446
+                }
1447
+                row=tmprow;
1448
+#if 0
1449
+fprintf(stderr,"\n");
1450
+#endif
1451
+        }
1158 1452
         /* draw the lines */
1159 1453
         drawn_cursor=0;
1160 1454
         colors=redata_highlighter_getcolors(re->data,&ncolors);
... ...
@@ -1164,7 +1458,7 @@ re_drawcontents(re_t *re)
1164 1458
                 /* definition of vars for tracking linecolor usage */
1165 1459
                 int curlinecolor; /* current linecolor */
1166 1460
                 int usedlenlinecolor; /* number of bytes of current linecolor already drawn */
1167
-                /* end of deifinitions */
1461
+                /* end of definitions */
1168 1462
                 if(redata_line_realstart(re->data,pos,&realstart)==-1 || redata_line_realend(re->data,pos,&realend)==-1) {
1169 1463
                         break; /* couldn't get real start/end */
1170 1464
                 }
Browse code

Implement font size change with control+'+'/'-'/'0', as in browsers

Dario Rodriguez authored on 01/11/2020 22:29:06
Showing 1 changed files
... ...
@@ -28,6 +28,7 @@
28 28
 #define IDLETIMEOUTSECONDS 10
29 29
 
30 30
 #define COMMANDBUFSIZE 1024
31
+#define DEFAULTFONTHEIGHT 16
31 32
 
32 33
 #define COMMAND_WARNING "(!)"
33 34
 #define COMMAND_GOTOLINE "Go to line:"
... ...
@@ -54,6 +55,7 @@ typedef struct re_t {
54 55
         int flag_newfile;
55 56
         char filename[PATH_MAX];
56 57
         int x, y, w, h; // contents rect
58
+        int fontheightpercent;
57 59
         long cursorpos;
58 60
         int originline,origincol;
59 61
         int curline,curcol;
... ...
@@ -91,6 +93,7 @@ int re_processkey_commanddata(re_t *re, SDL_Event *event);
91 93
 int re_processcommand(re_t *re);
92 94
 int re_moveupdown(re_t *re, int totalinc);
93 95
 int re_moveleftright(re_t *re, int totalinc);
96
+int re_changefontsize(re_t *re, int direction);
94 97
 int re_rtrim(re_t *re, long curpos, int *trimmed);
95 98
 long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
96 99
 int re_drawheader_editing(re_t *re);
... ...
@@ -320,7 +323,8 @@ re_init(void)
320 323
                 re_free(re),re=NULL;
321 324
                 return(NULL); /* insuf. mem. */
322 325
         }
323
-        if((re->ui=reui_init())==NULL) {
326
+        re->fontheightpercent=100;
327
+        if((re->ui=reui_init(DEFAULTFONTHEIGHT*re->fontheightpercent/100))==NULL) {
324 328
                 re_free(re),re=NULL;
325 329
                 return(NULL); /* video init error */
326 330
         }
... ...
@@ -645,6 +649,18 @@ fprintf(stderr,"re_processkey(): received Control+l\n");
645 649
                 re_fixorigin_center(re);
646 650
                 re->headerdirty=1;
647 651
                 re->contentsdirty=1;
652
+        } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
653
+fprintf(stderr,"re_processkey(): received Control+'+'\n");
654
+                re_changefontsize(re, 1);
655
+                re->ignorenkeys++;
656
+        } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
657
+fprintf(stderr,"re_processkey(): received Control+'-'\n");
658
+                re_changefontsize(re, -1);
659
+                re->ignorenkeys++;
660
+        } else if(event->key.keysym.sym==SDLK_0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
661
+fprintf(stderr,"re_processkey(): received Control+'0'\n");
662
+                re_changefontsize(re, 0);
663
+                re->ignorenkeys++;
648 664
         }
649 665
         return(0);
650 666
 }
... ...
@@ -915,6 +931,44 @@ re_moveleftright(re_t *re, int totalinc)
915 931
         return(0);
916 932
 }
917 933
 
934
+int
935
+re_changefontsize(re_t *re, int direction)
936
+{
937
+        int validpercent[]={30,50,67,80,90,100,110,120,133,150,170,200,240,300};
938
+        int newpercent;
939
+        int i;
940
+        if(re==NULL)
941
+                return(-1); /* sanity check failed */
942
+        if(direction<0) {
943
+                newpercent=validpercent[0];
944
+                for(i=0;i<(sizeof(validpercent)/sizeof(validpercent[0]));i++) {
945
+                        if(validpercent[i]<re->fontheightpercent)
946
+                                newpercent=validpercent[i];
947
+                        else
948
+                                break;
949
+                }
950
+        } else if(direction>0) {
951
+                newpercent=validpercent[(sizeof(validpercent)/sizeof(validpercent[0]))-1];
952
+                for(i=(sizeof(validpercent)/sizeof(validpercent[0]))-1;i>=0;i--) {
953
+                        if(validpercent[i]>re->fontheightpercent)
954
+                                newpercent=validpercent[i];
955
+                        else
956
+                                break;
957
+                }
958
+        } else {
959
+                newpercent=100;
960
+        }
961
+        if(reui_setfontheight(re->ui,DEFAULTFONTHEIGHT*newpercent/100)==-1)
962
+                return(-1); /* couldn't setup new font size */
963
+        re->fontheightpercent=newpercent;
964
+        re_setuidata(re);
965
+        re_fixorigin(re);
966
+        re->contentsdirty=1;
967
+        re->headerdirty=1;
968
+        return(0);
969
+}
970
+
971
+
918 972
 int
919 973
 re_rtrim(re_t *re, long curpos, int *trimmed)
920 974
 {
Browse code

Implement show hint of related prototype (for now only for common C/POSIX functions)

Dario Rodriguez authored on 31/10/2020 21:29:27
Showing 1 changed files
... ...
@@ -18,6 +18,7 @@
18 18
 #include "re_data.h"
19 19
 #include "re_plugin_unsaved.h"
20 20
 #include "re_plugin_highlighter.h"
21
+#include "re_plugin_prototypes.h"
21 22
 #include "re_ui.h"
22 23
 #include "ext/socklib.h"
23 24
 
... ...
@@ -314,6 +315,7 @@ re_init(void)
314 315
         if((re->data=redata_init(
315 316
           redata_unsaved_register,
316 317
           redata_highlighter_register,
318
+          redata_prototypes_register,
317 319
           NULL))==NULL) {
318 320
                 re_free(re),re=NULL;
319 321
                 return(NULL); /* insuf. mem. */
... ...
@@ -1084,6 +1086,7 @@ re_drawcontents(re_t *re)
1084 1086
         int matchingpos;
1085 1087
         char matchingchar;
1086 1088
         int mline,mcol;
1089
+        const char *hint;
1087 1090
         if(re==NULL)
1088 1091
                 return(-1);
1089 1092
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
... ...
@@ -1188,17 +1191,14 @@ re_drawcontents(re_t *re)
1188 1191
                 else
1189 1192
                         reui_balloon(re->ui, '\0', x,y, fg, bg, &matchingchar,1);
1190 1193
         }
1191
-        /* display commonprototypes info if applicable */
1192
-#if 1
1193
-#warning TODO: display commonprototypes info if applicable
1194
-{
1195
-                char sampletextlarge[]={"void *memcpy(void *dest, const void *src, size_t n)"};
1194
+        /* display prototypes info if applicable */
1195
+        hint=redata_prototypes_get(re->data, re->cursorpos);
1196
+        if(hint!=NULL) {
1196 1197
                 if((re->curline-re->originline)>=(re->maxrow/2))
1197
-                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1198
+                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *) hint,strlen(hint));
1198 1199
                 else
1199
-                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1200
-}
1201
-#endif
1200
+                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",(char *)hint,strlen(hint));
1201
+        }
1202 1202
         /* all done */
1203 1203
         re->contentsdirty=0;
1204 1204
         re->ui->rendererdirty=1;
Browse code

Implement highlight matching bracket (parens/curly-braces/square-brackets/angle-brackets)

Dario Rodriguez authored on 23/10/2020 22:51:48
Showing 1 changed files
... ...
@@ -31,6 +31,9 @@
31 31
 #define COMMAND_WARNING "(!)"
32 32
 #define COMMAND_GOTOLINE "Go to line:"
33 33
 #define COMMAND_SEARCHFORWARD "Search:"
34
+#define COMMAND_REPLACEWHAT "Search for:"
35
+#define COMMAND_REPLACEWITH "Replace with:"
36
+#define COMMAND_REPLACEHOW "Replace options (Igncase Selected Backwards Entire All Noconfirm):"
34 37
 #define COMMAND_QUESTION "(?)"
35 38
 #define COMMAND_EXIT "Exit"
36 39
 
... ...
@@ -88,6 +91,7 @@ int re_processcommand(re_t *re);
88 91
 int re_moveupdown(re_t *re, int totalinc);
89 92
 int re_moveleftright(re_t *re, int totalinc);
90 93
 int re_rtrim(re_t *re, long curpos, int *trimmed);
94
+long re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar);
91 95
 int re_drawheader_editing(re_t *re);
92 96
 int re_drawheader_command(re_t *re);
93 97
 int re_drawcontents(re_t *re);
... ...
@@ -661,6 +665,7 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
661 665
                 strncpy(re->commandbuf,re->cachelastsearch,sizeof(re->commandbuf));
662 666
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
663 667
                 re->headerdirty=1;
668
+#warning TODO: Search and replace (control+q+a)
664 669
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
665 670
                 re->command=COMMAND_EXIT;
666 671
                 re->commandbuf[0]='\0';
... ...
@@ -938,6 +943,70 @@ re_rtrim(re_t *re, long curpos, int *trimmed)
938 943
         return(0);
939 944
 }
940 945
 
946
+long
947
+re_getmatchingbracket(re_t *re,long posini, char originalchar, char *matchingchar)
948
+{
949
+        char *ori,*dest;
950
+        char *pairs="[]{}<>()";
951
+        int is_backwards;
952
+        int colorindex,newcolor;
953
+        long realstart;
954
+        int line;
955
+        long pos;
956
+        long posnextori,posnextdest;
957
+        long posnext;
958
+        int counter;
959
+        if(re==NULL)
960
+                return(-1); /* sanity check failed */
961
+        if((ori=strchr(pairs,originalchar))==NULL)
962
+                return(-1); /* unknown char */
963
+        is_backwards=(ori-pairs)%2;
964
+        dest=ori+((is_backwards)?-1:1);
965
+        if(redata_pos2linecol(re->data,posini,&line,NULL)==-1
966
+          || redata_line_realstart(re->data,posini,&realstart)==-1) {
967
+                return(-1); /* couldn't get line number or startpos */
968
+        }
969
+        colorindex=redata_highlighter_getcolorindex(re->data,line,posini-realstart);
970
+        pos=posini;
971
+        counter=1;
972
+        while(1) {
973
+                /* get the next pos */
974
+                if(!is_backwards) {
975
+                        posnextori=redata_searchforward(re->data,pos+1,ori,1);
976
+                        posnextdest=redata_searchforward(re->data,pos+1,dest,1);
977
+                        posnext=(posnextori==-1)?posnextdest:(posnextdest==-1)?posnextori:(posnextori<posnextdest)?posnextori:posnextdest;
978
+                } else {
979
+                        posnextori=redata_searchbackwards(re->data,pos-1,ori,1);
980
+                        posnextdest=redata_searchbackwards(re->data,pos-1,dest,1);
981
+                        posnext=(posnextori==-1)?posnextdest:(posnextdest==-1)?posnextori:(posnextori>posnextdest)?posnextori:posnextdest;
982
+                }
983
+                if(posnext==-1)
984
+                        break; /* search ended and couln't get the counter to zero */
985
+                /* check that the color index is ok */
986
+                if(redata_pos2linecol(re->data,posnext,&line,NULL)==-1
987
+                  || redata_line_realstart(re->data,posnext,&realstart)==-1) {
988
+                        return(-1); /* couldn't get line number or startpos */
989
+                }
990
+                newcolor=redata_highlighter_getcolorindex(re->data,line,posnext-realstart);
991
+                if(colorindex!=newcolor) {
992
+                        pos=posnext;
993
+                        continue; /* it doesn't have the same color */
994
+                }
995
+                /* do the math */
996
+                if(posnext==posnextori)
997
+                        counter++;
998
+                if(posnext==posnextdest)
999
+                        counter--;
1000
+                pos=posnext;
1001
+                if(counter==0) {
1002
+                        if(matchingchar!=NULL)
1003
+                                *matchingchar=*dest;
1004
+                        return(posnext); /* found matching bracket */
1005
+                }
1006
+        }
1007
+        return(-1);
1008
+}
1009
+
941 1010
 int
942 1011
 re_drawheader_editing(re_t *re)
943 1012
 {
... ...
@@ -1012,6 +1081,9 @@ re_drawcontents(re_t *re)
1012 1081
         int ncolors;
1013 1082
         linecolor_t *linecolors;
1014 1083
         int nlinecolors;
1084
+        int matchingpos;
1085
+        char matchingchar;
1086
+        int mline,mcol;
1015 1087
         if(re==NULL)
1016 1088
                 return(-1);
1017 1089
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
... ...
@@ -1029,8 +1101,10 @@ re_drawcontents(re_t *re)
1029 1101
         /* draw the lines */
1030 1102
         drawn_cursor=0;
1031 1103
         colors=redata_highlighter_getcolors(re->data,&ncolors);
1104
+        matchingpos=-1;
1105
+        matchingchar='\0';
1032 1106
         for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1033
-                /* definiciton of vars for teacking linecolor usage */
1107
+                /* definition of vars for tracking linecolor usage */
1034 1108
                 int curlinecolor; /* current linecolor */
1035 1109
                 int usedlenlinecolor; /* number of bytes of current linecolor already drawn */
1036 1110
                 /* end of deifinitions */
... ...
@@ -1072,15 +1146,18 @@ re_drawcontents(re_t *re)
1072 1146
                         }
1073 1147
                         if(row==(re->curline-re->originline)) {
1074 1148
                                 if(re->curcol>=tmpcol && re->curcol<(tmpcol+availcol)) {
1149
+                                        int utf8charlen;
1150
+                                        /* draw cursor */
1075 1151
                                         reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
1076 1152
                                         drawn_cursor=1;
1077 1153
                                         curptr=redata_generic_utf8col(ptr,len-has_nl,re->curcol-tmpcol);
1078 1154
                                         curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
1079
-                                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(curptr,curptrlen));
1155
+                                        utf8charlen=redata_generic_utf8charlen(curptr,curptrlen);
1156
+                                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,utf8charlen);
1157
+                                        /* get matching braces/parens/anglebracket/curlybraces for highlighting */
1158
+                                        if(utf8charlen==1 && strchr("[]{}<>()",*curptr)!=NULL)
1159
+                                                matchingpos=re_getmatchingbracket(re,re->cursorpos,*curptr,&matchingchar);
1080 1160
                                 }
1081
-#warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
1082
-#warning When searching for matching backet/..., count only the ones in the same highlighting color.
1083
-#warning If it is ourside of the visible part of the code, put a comic baloon (with some transparency) in that dir. (up, down or right) at the correct height/position to mark the direction of where it is.
1084 1161
 #warning TODO: Select(control+k+b/control+k+k/...)
1085 1162
                         }
1086 1163
                 }
... ...
@@ -1091,22 +1168,40 @@ re_drawcontents(re_t *re)
1091 1168
                 pos=realend+1;
1092 1169
 /*LONG LINE LEFT FOR DEBUGGING PURPOSES: reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));*/
1093 1170
         }
1094
-        re->contentsdirty=0;
1095
-        re->ui->rendererdirty=1;
1171
+        /* highlight matching parens/brace/... if applicable */
1172
+        if(matchingpos!=-1 && redata_pos2linecol(re->data,matchingpos,&mline,&mcol)!=-1) {
1173
+                int x,y;
1174
+                char *fg="\xff\x00\x00\x80";
1175
+                char *bg="\xff\xff\xff\xaf";
1176
+                x=re->x+(mcol-re->origincol)*re->ui->fontwidth+(re->ui->fontwidth/2);
1177
+                x=(x<re->x)?re->x:(x>=(re->x+re->w))?(re->x+re->w-1):x;
1178
+                y=re->y+(mline-re->originline)*re->ui->fontheight+(re->ui->fontheight/2);
1179
+                y=(y<re->y)?re->y:(y>=(re->y+re->h))?(re->y+re->h-1):y;
1180
+                if(mline<re->originline)
1181
+                        reui_balloon(re->ui, 'n', x, re->y, fg, bg, &matchingchar,1);
1182
+                else if(mline>=(re->originline+re->maxrow))
1183
+                        reui_balloon(re->ui, 's', x, re->y+re->h-1, fg, bg, &matchingchar,1);
1184
+                else if(mcol<re->origincol)
1185
+                        reui_balloon(re->ui, 'w', re->x, y, fg, bg, &matchingchar,1);
1186
+                else if(mcol>=(re->origincol+re->maxcol))
1187
+                        reui_balloon(re->ui, 'e', re->x+re->w-1,y, fg, bg, &matchingchar,1);
1188
+                else
1189
+                        reui_balloon(re->ui, '\0', x,y, fg, bg, &matchingchar,1);
1190
+        }
1191
+        /* display commonprototypes info if applicable */
1096 1192
 #if 1
1193
+#warning TODO: display commonprototypes info if applicable
1097 1194
 {
1098
-char sampletext[]={"Here is the top"};
1099
-char sampletextlarge[]={"void *memcpy(void *dest, const void *src, size_t n)"};
1100
-reui_balloon(re->ui, 'n', re->x+re->w/2, re->y, "\xff\x00\x00\xff", "\x00\x00\xff\x80",sampletext,strlen(sampletext));
1101
-reui_balloon(re->ui, 's', re->x+re->w/2, re->y+re->h-1, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "}",1);
1102
-reui_balloon(re->ui, 'e', re->x+re->w-1,re->y+re->h/2, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "[",1);
1103
-reui_balloon(re->ui, 'w', re->x, re->y+re->h/2, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "]",1);
1104
-if((re->curline-re->originline)>=(re->maxrow/2))
1105
-        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1106
-else
1107
-        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1195
+                char sampletextlarge[]={"void *memcpy(void *dest, const void *src, size_t n)"};
1196
+                if((re->curline-re->originline)>=(re->maxrow/2))
1197
+                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1198
+                else
1199
+                        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1108 1200
 }
1109 1201
 #endif
1202
+        /* all done */
1203
+        re->contentsdirty=0;
1204
+        re->ui->rendererdirty=1;
1110 1205
         return(0);
1111 1206
 }
1112 1207
 
Browse code

Implement Control+q+f (search) and Control+l (search next)

Dario Rodriguez authored on 22/10/2020 21:55:58
Showing 1 changed files
... ...
@@ -29,7 +29,8 @@
29 29
 #define COMMANDBUFSIZE 1024
30 30
 
31 31
 #define COMMAND_WARNING "(!)"
32
-#define COMMAND_GOTOLINE "Go to line: "
32
+#define COMMAND_GOTOLINE "Go to line:"
33
+#define COMMAND_SEARCHFORWARD "Search:"
33 34
 #define COMMAND_QUESTION "(?)"
34 35
 #define COMMAND_EXIT "Exit"
35 36
 
... ...
@@ -58,6 +59,7 @@ typedef struct re_t {
58 59
         int command_first_key;
59 60
         char *command;
60 61
         char commandbuf[COMMANDBUFSIZE];
62
+        char cachelastsearch[COMMANDBUFSIZE];
61 63
         question_t *question;
62 64
         int showingwarning;
63 65
         int ignorenkeys;
... ...
@@ -621,6 +623,22 @@ fprintf(stderr,"re_processkey(): received Control+z\n");
621 623
                 re_fixorigin(re);
622 624
                 re->headerdirty=1;
623 625
                 re->contentsdirty=1;
626
+        } else if(event->key.keysym.sym==SDLK_l && (SDL_GetModState()&KMOD_CTRL)!=0 && re->cachelastsearch[0]!='\0') {
627
+                long newpos;
628
+fprintf(stderr,"re_processkey(): received Control+l\n");
629
+                /* search next (forward) */
630
+                if((newpos=redata_searchforward(re->data,re->cursorpos+1,re->cachelastsearch,strlen(re->cachelastsearch)))==-1) {
631
+                        re->command=COMMAND_WARNING;
632
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"String not found");
633
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
634
+                        re->headerdirty=1;
635
+                        return(-1);
636
+                }
637
+                re->cursorpos=newpos;
638
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
639
+                re_fixorigin_center(re);
640
+                re->headerdirty=1;
641
+                re->contentsdirty=1;
624 642
         }
625 643
         return(0);
626 644
 }
... ...
@@ -638,6 +656,11 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
638 656
                 re->command=COMMAND_GOTOLINE;
639 657
                 re->commandbuf[0]='\0';
640 658
                 re->headerdirty=1;
659
+        } else if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_f) {
660
+                re->command=COMMAND_SEARCHFORWARD;
661
+                strncpy(re->commandbuf,re->cachelastsearch,sizeof(re->commandbuf));
662
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
663
+                re->headerdirty=1;
641 664
         } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
642 665
                 re->command=COMMAND_EXIT;
643 666
                 re->commandbuf[0]='\0';
... ...
@@ -717,6 +740,22 @@ re_processcommand(re_t *re)
717 740
                 re->originline=line-(re->maxrow/2);
718 741
                 re->headerdirty=1;
719 742
                 re->contentsdirty=1;
743
+        } else if(strcmp(re->command,COMMAND_SEARCHFORWARD)==0) {
744
+                long newpos;
745
+                if((newpos=redata_searchforward(re->data,re->cursorpos,re->commandbuf,strlen(re->commandbuf)))==-1) {
746
+                        re->command=COMMAND_WARNING;
747
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"String not found");
748
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
749
+                        re->headerdirty=1;
750
+                        return(-1);
751
+                }
752
+                strncpy(re->cachelastsearch,re->commandbuf,sizeof(re->cachelastsearch));
753
+                re->cachelastsearch[sizeof(re->cachelastsearch)-1]='\0';
754
+                re->cursorpos=newpos;
755
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
756
+                re_fixorigin_center(re);
757
+                re->headerdirty=1;
758
+                re->contentsdirty=1;
720 759
         } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
721 760
                 /* validate reply */
722 761
                 if(!(atoi(re->commandbuf)>0 && atoi(re->commandbuf)<=re->question->nopts)) {
Browse code

UI: add ability to put balloons on screen

Dario Rodriguez authored on 21/10/2020 22:06:25
Showing 1 changed files
... ...
@@ -1040,6 +1040,7 @@ re_drawcontents(re_t *re)
1040 1040
                                         reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(curptr,curptrlen));
1041 1041
                                 }
1042 1042
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
1043
+#warning When searching for matching backet/..., count only the ones in the same highlighting color.
1043 1044
 #warning If it is ourside of the visible part of the code, put a comic baloon (with some transparency) in that dir. (up, down or right) at the correct height/position to mark the direction of where it is.
1044 1045
 #warning TODO: Select(control+k+b/control+k+k/...)
1045 1046
                         }
... ...
@@ -1053,6 +1054,20 @@ re_drawcontents(re_t *re)
1053 1054
         }
1054 1055
         re->contentsdirty=0;
1055 1056
         re->ui->rendererdirty=1;
1057
+#if 1
1058
+{
1059
+char sampletext[]={"Here is the top"};
1060
+char sampletextlarge[]={"void *memcpy(void *dest, const void *src, size_t n)"};
1061
+reui_balloon(re->ui, 'n', re->x+re->w/2, re->y, "\xff\x00\x00\xff", "\x00\x00\xff\x80",sampletext,strlen(sampletext));
1062
+reui_balloon(re->ui, 's', re->x+re->w/2, re->y+re->h-1, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "}",1);
1063
+reui_balloon(re->ui, 'e', re->x+re->w-1,re->y+re->h/2, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "[",1);
1064
+reui_balloon(re->ui, 'w', re->x, re->y+re->h/2, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "]",1);
1065
+if((re->curline-re->originline)>=(re->maxrow/2))
1066
+        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1067
+else
1068
+        reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge));
1069
+}
1070
+#endif
1056 1071
         return(0);
1057 1072
 }
1058 1073
 
Browse code

highlighting: add missing end-of-highlights check when displaying a line with highlighting

Dario Rodriguez authored on 19/10/2020 21:33:48
Showing 1 changed files
... ...
@@ -1014,7 +1014,7 @@ re_drawcontents(re_t *re)
1014 1014
                                 int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */
1015 1015
                                 used=usedcol=0;
1016 1016
                                 /* while the avail text is larger than the linecolor len */
1017
-                                while((len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
1017
+                                while(curlinecolor<nlinecolors && (len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
1018 1018
                                         reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1019 1019
                                         usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1020 1020
                                         used+=linecolors[curlinecolor].len-usedlenlinecolor;
... ...
@@ -1022,7 +1022,7 @@ re_drawcontents(re_t *re)
1022 1022
                                         usedlenlinecolor=0;
1023 1023
                                 }
1024 1024
                                 /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */
1025
-                                if((len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) {
1025
+                                if(curlinecolor<nlinecolors && (len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) {
1026 1026
                                         reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used));
1027 1027
                                         usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-used));
1028 1028
                                         usedlenlinecolor+=(len-has_nl-used);
Browse code

highlighting: remove temp. debug code

Dario Rodriguez authored on 19/10/2020 21:16:06
Showing 1 changed files
... ...
@@ -16,35 +16,6 @@
16 16
 #include <time.h>
17 17
 
18 18
 #include "re_data.h"
19
-#if 0
20
-#define INITIALCHUNK 20
21
-#define MAXDUMP 25
22
-static void
23
-redata_debug_chunkdump(redata_t *redata, char *title)
24
-{
25
-        int m,k;
26
-        char c;
27
-        title=(title==NULL)?"":title;
28
-        fprintf(stderr,"%s:CHUNKDUMP (sizechunks:%i)\n",title,redata->sizechunks);
29
-        for(m=INITIALCHUNK;m<redata->sizechunks && m<MAXDUMP;m++) {
30
-                fprintf(stderr,"%s:chunk[%i] len:%-5i data:\"",title,m,redata->chunks[m]->useddata);
31
-                for(k=0;k<redata->chunks[m]->useddata;k++) {
32
-                        c=redata->chunks[m]->data[k];
33
-                        if(c=='\n' || c=='\0')
34
-                                fprintf(stderr,"\\%c",(c=='\n')?'n':'0');
35
-                        else if(c<' ' || c>'~' || c=='\\')
36
-                                fprintf(stderr,"\\x%02X",((unsigned char *)redata->chunks[m]->data)[k]);
37
-                        else
38
-                                fprintf(stderr,"%c",c);
39
-                }
40
-                fprintf(stderr,"\"\n");
41
-        }
42
-}
43
-#define CHUNKDEBUG(a) redata_debug_chunkdump a
44
-#else
45
-#define CHUNKDEBUG(a)
46
-#endif
47
-
48 19
 #include "re_plugin_unsaved.h"
49 20
 #include "re_plugin_highlighter.h"
50 21
 #include "re_ui.h"
... ...
@@ -1019,9 +990,6 @@ re_drawcontents(re_t *re)
1019 990
         /* draw the lines */
1020 991
         drawn_cursor=0;
1021 992
         colors=redata_highlighter_getcolors(re->data,&ncolors);
1022
-#if 0
1023
-CHUNKDEBUG((re->data,"Pre-display"));
1024
-#endif
1025 993
         for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1026 994
                 /* definiciton of vars for teacking linecolor usage */
1027 995
                 int curlinecolor; /* current linecolor */
... ...
@@ -1032,19 +1000,6 @@ CHUNKDEBUG((re->data,"Pre-display"));
1032 1000
                 }
1033 1001
                 in_error=0;
1034 1002
                 linecolors=(colors==NULL)?NULL:redata_highlighter_getline(re->data,re->originline+row,&nlinecolors);
1035
-#if 0
1036
-#define DEBUGLINE 12
1037
-if((re->origincol+row)==DEBUGLINE) {
1038
-int i,k,l=nlinecolors*sizeof(linecolor_t);
1039
-linecolor_t *lc=linecolors;
1040
-fprintf(stderr,"linecolors for line:%i \"",re->origincol+row);
1041
-for(k=0;k<l;k+=sizeof(linecolor_t),lc++) {
1042
-        for(i=0;i<lc->len;i++)
1043
-                fprintf(stderr,"%x",lc->color);
1044
-}
1045
-fprintf(stderr,"\"\n");
1046
-}
1047
-#endif
1048 1003
                 curlinecolor=0;
1049 1004
                 usedlenlinecolor=0;
1050 1005
                 for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(re->origincol+re->maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
... ...
@@ -1060,16 +1015,6 @@ fprintf(stderr,"\"\n");
1060 1015
                                 used=usedcol=0;
1061 1016
                                 /* while the avail text is larger than the linecolor len */
1062 1017
                                 while((len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
1063
-#if 0
1064
-if((re->origincol+row)==DEBUGLINE) {
1065
-int i,l;
1066
-fprintf(stderr,"ui_write (full) for line:%i curlinecolor:%i color:%i at:%i str:\"",(re->origincol+row),curlinecolor,linecolors[curlinecolor].color,(tmpcol-re->origincol+usedcol));
1067
-l=linecolors[curlinecolor].len-usedlenlinecolor;
1068
-for(i=0;i<l;i++)
1069
-fprintf(stderr,"%c",ptr[used+i]);
1070
-fprintf(stderr,"\" (used:%i)\n",used);
1071
-}
1072
-#endif
1073 1018
                                         reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1074 1019
                                         usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1075 1020
                                         used+=linecolors[curlinecolor].len-usedlenlinecolor;
... ...
@@ -1078,27 +1023,11 @@ fprintf(stderr,"\" (used:%i)\n",used);
1078 1023
                                 }
1079 1024
                                 /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */
1080 1025
                                 if((len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) {
1081
-#if 0
1082
-if((re->origincol+row)==DEBUGLINE) {
1083
-int i,l;
1084
-fprintf(stderr,"ui_write (last) for line:%i curlinecolor:%i color:%i at:%i str:\"",(re->origincol+row),curlinecolor,linecolors[curlinecolor].color,(tmpcol-re->origincol+usedcol));
1085
-l=(len-has_nl-used);
1086
-for(i=0;i<l;i++)
1087
-fprintf(stderr,"%c",ptr[used+i]);
1088
-fprintf(stderr,"\" (used:%i)\n",used);
1089
-}
1090
-#endif
1091 1026
                                         reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used));
1092 1027
                                         usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-used));
1093 1028
                                         usedlenlinecolor+=(len-has_nl-used);
1094 1029
                                         used+=(len-has_nl-used);
1095 1030
                                 }
1096
-#if 0
1097
-if((re->origincol+row)==DEBUGLINE) {
1098
-fprintf(stderr,"AFTER (used:%i)\n",used);
1099
-}
1100
-#endif
1101
-
1102 1031
                         } else {
1103 1032
                                 reui_write(re->ui,re->x+(tmpcol-re->origincol)*re->ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
1104 1033
                         }
... ...
@@ -1111,6 +1040,8 @@ fprintf(stderr,"AFTER (used:%i)\n",used);
1111 1040
                                         reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(curptr,curptrlen));
1112 1041
                                 }
1113 1042
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
1043
+#warning If it is ourside of the visible part of the code, put a comic baloon (with some transparency) in that dir. (up, down or right) at the correct height/position to mark the direction of where it is.
1044
+#warning TODO: Select(control+k+b/control+k+k/...)
1114 1045
                         }
1115 1046
                 }
1116 1047
                 if(row==(re->curline-re->originline) && !drawn_cursor)
Browse code

Add a simple C-language highlighter as a plugin (and lots of temp. debug code; to be cleaned later)

Dario Rodriguez authored on 17/10/2020 22:30:36
Showing 1 changed files
... ...
@@ -16,6 +16,35 @@
16 16
 #include <time.h>
17 17
 
18 18
 #include "re_data.h"
19
+#if 0
20
+#define INITIALCHUNK 20
21
+#define MAXDUMP 25
22
+static void
23
+redata_debug_chunkdump(redata_t *redata, char *title)
24
+{
25
+        int m,k;
26
+        char c;
27
+        title=(title==NULL)?"":title;
28
+        fprintf(stderr,"%s:CHUNKDUMP (sizechunks:%i)\n",title,redata->sizechunks);
29
+        for(m=INITIALCHUNK;m<redata->sizechunks && m<MAXDUMP;m++) {
30
+                fprintf(stderr,"%s:chunk[%i] len:%-5i data:\"",title,m,redata->chunks[m]->useddata);
31
+                for(k=0;k<redata->chunks[m]->useddata;k++) {
32
+                        c=redata->chunks[m]->data[k];
33
+                        if(c=='\n' || c=='\0')
34
+                                fprintf(stderr,"\\%c",(c=='\n')?'n':'0');
35
+                        else if(c<' ' || c>'~' || c=='\\')
36
+                                fprintf(stderr,"\\x%02X",((unsigned char *)redata->chunks[m]->data)[k]);
37
+                        else
38
+                                fprintf(stderr,"%c",c);
39
+                }
40
+                fprintf(stderr,"\"\n");
41
+        }
42
+}
43
+#define CHUNKDEBUG(a) redata_debug_chunkdump a
44
+#else
45
+#define CHUNKDEBUG(a)
46
+#endif
47
+
19 48
 #include "re_plugin_unsaved.h"
20 49
 #include "re_plugin_highlighter.h"
21 50
 #include "re_ui.h"
... ...
@@ -416,7 +445,7 @@ re_processkey_editing(re_t *re, SDL_Event *event)
416 445
                 strncpy(event->text.text,spaces+(re->curcol%8),sizeof(event->text.text));
417 446
                 event->text.text[sizeof(event->text.text)-1]='\0';
418 447
         } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_DELETE) {
419
-#if 1
448
+#if 0
420 449
 fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
421 450
 #endif
422 451
                 long realend;
... ...
@@ -969,6 +998,10 @@ re_drawcontents(re_t *re)
969 998
         int in_error;
970 999
         long realstart,realend;
971 1000
         int drawn_cursor;
1001
+        hcolor_t *colors;
1002
+        int ncolors;
1003
+        linecolor_t *linecolors;
1004
+        int nlinecolors;
972 1005
         if(re==NULL)
973 1006
                 return(-1);
974 1007
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
... ...
@@ -985,11 +1018,35 @@ re_drawcontents(re_t *re)
985 1018
         reui_fill(re->ui,re->x,re->y+(re->curline-re->originline)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
986 1019
         /* draw the lines */
987 1020
         drawn_cursor=0;
1021
+        colors=redata_highlighter_getcolors(re->data,&ncolors);
1022
+#if 0
1023
+CHUNKDEBUG((re->data,"Pre-display"));
1024
+#endif
988 1025
         for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
1026
+                /* definiciton of vars for teacking linecolor usage */
1027
+                int curlinecolor; /* current linecolor */
1028
+                int usedlenlinecolor; /* number of bytes of current linecolor already drawn */
1029
+                /* end of deifinitions */
989 1030
                 if(redata_line_realstart(re->data,pos,&realstart)==-1 || redata_line_realend(re->data,pos,&realend)==-1) {
990 1031
                         break; /* couldn't get real start/end */
991 1032
                 }
992 1033
                 in_error=0;
1034
+                linecolors=(colors==NULL)?NULL:redata_highlighter_getline(re->data,re->originline+row,&nlinecolors);
1035
+#if 0
1036
+#define DEBUGLINE 12
1037
+if((re->origincol+row)==DEBUGLINE) {
1038
+int i,k,l=nlinecolors*sizeof(linecolor_t);
1039
+linecolor_t *lc=linecolors;
1040
+fprintf(stderr,"linecolors for line:%i \"",re->origincol+row);
1041
+for(k=0;k<l;k+=sizeof(linecolor_t),lc++) {
1042
+        for(i=0;i<lc->len;i++)
1043
+                fprintf(stderr,"%x",lc->color);
1044
+}
1045
+fprintf(stderr,"\"\n");
1046
+}
1047
+#endif
1048
+                curlinecolor=0;
1049
+                usedlenlinecolor=0;
993 1050
                 for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(re->origincol+re->maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
994 1051
                         if(redata_line_rawinfo(re->data,pos,&newpos,&ptr,&len,&is_continuation)==-1) {
995 1052
                                 in_error=1;
... ...
@@ -998,7 +1055,53 @@ re_drawcontents(re_t *re)
998 1055
                         has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
999 1056
                         availcol=redata_generic_utf8len(ptr,len-has_nl);
1000 1057
 #warning TODO: consider tabs
1001
-                        reui_write(re->ui,re->x+(tmpcol-re->origincol)*re->ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
1058
+                        if(linecolors!=NULL) {
1059
+                                int used,usedcol; /* number of bytes/columns used of redata chunk (those are already drawn) */
1060
+                                used=usedcol=0;
1061
+                                /* while the avail text is larger than the linecolor len */
1062
+                                while((len-has_nl-used)>=(linecolors[curlinecolor].len-usedlenlinecolor)) {
1063
+#if 0
1064
+if((re->origincol+row)==DEBUGLINE) {
1065
+int i,l;
1066
+fprintf(stderr,"ui_write (full) for line:%i curlinecolor:%i color:%i at:%i str:\"",(re->origincol+row),curlinecolor,linecolors[curlinecolor].color,(tmpcol-re->origincol+usedcol));
1067
+l=linecolors[curlinecolor].len-usedlenlinecolor;
1068
+for(i=0;i<l;i++)
1069
+fprintf(stderr,"%c",ptr[used+i]);
1070
+fprintf(stderr,"\" (used:%i)\n",used);
1071
+}
1072
+#endif
1073
+                                        reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1074
+                                        usedcol+=redata_generic_utf8len(ptr+used,linecolors[curlinecolor].len-usedlenlinecolor);
1075
+                                        used+=linecolors[curlinecolor].len-usedlenlinecolor;
1076
+                                        curlinecolor++;
1077
+                                        usedlenlinecolor=0;
1078
+                                }
1079
+                                /* for the last bytes of avail text, after writing them we save how many bytes we have processed of that linecolor to be able to continue later */
1080
+                                if((len-has_nl-used)>0 && (linecolors[curlinecolor].len-usedlenlinecolor)>(len-has_nl-used)) {
1081
+#if 0
1082
+if((re->origincol+row)==DEBUGLINE) {
1083
+int i,l;
1084
+fprintf(stderr,"ui_write (last) for line:%i curlinecolor:%i color:%i at:%i str:\"",(re->origincol+row),curlinecolor,linecolors[curlinecolor].color,(tmpcol-re->origincol+usedcol));
1085
+l=(len-has_nl-used);
1086
+for(i=0;i<l;i++)
1087
+fprintf(stderr,"%c",ptr[used+i]);
1088
+fprintf(stderr,"\" (used:%i)\n",used);
1089
+}
1090
+#endif
1091
+                                        reui_write(re->ui,re->x+(tmpcol-re->origincol+usedcol)*re->ui->fontwidth,y,colors[linecolors[curlinecolor].color].rgba,ptr+used,(len-has_nl-used));
1092
+                                        usedcol+=redata_generic_utf8len(ptr+used,(len-has_nl-used));
1093
+                                        usedlenlinecolor+=(len-has_nl-used);
1094
+                                        used+=(len-has_nl-used);
1095
+                                }
1096
+#if 0
1097
+if((re->origincol+row)==DEBUGLINE) {
1098
+fprintf(stderr,"AFTER (used:%i)\n",used);
1099
+}
1100
+#endif
1101
+
1102
+                        } else {
1103
+                                reui_write(re->ui,re->x+(tmpcol-re->origincol)*re->ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
1104
+                        }
1002 1105
                         if(row==(re->curline-re->originline)) {
1003 1106
                                 if(re->curcol>=tmpcol && re->curcol<(tmpcol+availcol)) {
1004 1107
                                         reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
Browse code

Add highlighter plugin structs and registration

Dario Rodriguez authored on 12/10/2020 21:55:42
Showing 1 changed files
... ...
@@ -17,6 +17,7 @@
17 17
 
18 18
 #include "re_data.h"
19 19
 #include "re_plugin_unsaved.h"
20
+#include "re_plugin_highlighter.h"
20 21
 #include "re_ui.h"
21 22
 #include "ext/socklib.h"
22 23
 
... ...
@@ -304,7 +305,10 @@ re_init(void)
304 305
         if((re=malloc(sizeof(re_t)))==NULL)
305 306
                 return(NULL); /* insuf. mem. */
306 307
         memset(re,0,sizeof(re_t));
307
-        if((re->data=redata_init(redata_unsaved_register,NULL))==NULL) {
308
+        if((re->data=redata_init(
309
+          redata_unsaved_register,
310
+          redata_highlighter_register,
311
+          NULL))==NULL) {
308 312
                 re_free(re),re=NULL;
309 313
                 return(NULL); /* insuf. mem. */
310 314
         }
Browse code

fix bug with rtrim and moveupdown (sometimes didn't move correctly when at end of file)

Dario Rodriguez authored on 10/10/2020 22:34:34
Showing 1 changed files
... ...
@@ -399,7 +399,6 @@ re_processkey_editing(re_t *re, SDL_Event *event)
399 399
                 return(-1); /* sanity check failed */
400 400
         /* convert RETURN KEYDOWN to TEXTINPUT */
401 401
         if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_RETURN) {
402
-#warning file having two \n at the end, delete the second with DEL staying to the right of the first, if we go down then, it does an scroll but it shouldn't
403 402
                 memset(&fakeevent,0,sizeof(SDL_Event));
404 403
                 event=&fakeevent;
405 404
                 event->type=SDL_TEXTINPUT;
... ...
@@ -413,7 +412,7 @@ re_processkey_editing(re_t *re, SDL_Event *event)
413 412
                 strncpy(event->text.text,spaces+(re->curcol%8),sizeof(event->text.text));
414 413
                 event->text.text[sizeof(event->text.text)-1]='\0';
415 414
         } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_DELETE) {
416
-#if 0
415
+#if 1
417 416
 fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
418 417
 #endif
419 418
                 long realend;
... ...
@@ -488,6 +487,11 @@ fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
488 487
                         int trimmed;
489 488
                         if(re_rtrim(re,re->cursorpos-len,&trimmed))
490 489
                                 re->cursorpos-=trimmed;
490
+#if 1
491
+#if 0
492
+fprintf(stderr,"SDL_TEXTINPUT: Insering newline\n");
493
+#endif
494
+#endif
491 495
                         re->curline++;
492 496
                         re->curcol=0;
493 497
                 } else {
... ...
@@ -732,12 +736,14 @@ re_moveupdown(re_t *re, int totalinc)
732 736
         long newpos,newpos2;
733 737
         int inc,doneinc;
734 738
         long realstart;
739
+        int needs_inccol;
735 740
         if(re==NULL)
736 741
                 return(-1); /* sanity check failed */
737 742
         if(totalinc==0)
738 743
                 return(0); /* nothing to do */
739 744
         inc=(totalinc<0)?-1:1;
740 745
         newpos=re->cursorpos; /* get rid of compiler warning (will be overwitten in the loop as totalinc never is 0) */
746
+        needs_inccol=0;
741 747
         for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
742 748
 #if 0
743 749
 fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
... ...
@@ -747,16 +753,18 @@ fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->cu
747 753
                         break; /* couldn't get current line data, we are at start/end */
748 754
                 }
749 755
                 re->cursorpos=realstart;
756
+                needs_inccol=1;
750 757
                 re->curline+=inc;
751
-                re_fixorigin(re);
752 758
 #if 0
753 759
 fprintf(stderr,"MOVING   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
754 760
 #endif
755 761
         }
762
+        if(!needs_inccol)
763
+                return(-1);
756 764
         if(redata_line_inccol(re->data,re->cursorpos,re->curcol,&newpos2,NULL)==-1) {
757 765
                 /* error advancing cursor, "emergency" repositioning */
758 766
 #if 0
759
-fprintf(stderr,"COLUMN ERROR\n");
767
+fprintf(stderr,"SETTING COLUMN ERROR\n");
760 768
 #endif
761 769
                 re->curcol=0;
762 770
                 newpos2=newpos;
... ...
@@ -768,6 +776,7 @@ fprintf(stderr,"COLUMN from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->cu
768 776
 #if 0
769 777
 fprintf(stderr,"COLUMN   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
770 778
 #endif
779
+        re_fixorigin(re);
771 780
         re->contentsdirty=1;
772 781
         re->headerdirty=1;
773 782
         return(0);
... ...
@@ -869,13 +878,17 @@ re_rtrim(re_t *re, long curpos, int *trimmed)
869 878
                 *trimmed=0;
870 879
         if(redata_line_rawinfo(re->data,curpos,&startpos,&start,&len,NULL)==0 &&
871 880
            len>1 && start[len-1]=='\n' && start[len-2]==' ' && curpos==(startpos+len-1)) {
872
-                for(n=1;(n+1)<(len-1) && start[len-1-n-1]==' ';n++)
873
-                        ;
874
-#if 0
875
-fprintf(stderr,"Trying to DELETE SPACES del %i bytes\n",n);
876
-#endif
877
-                redata_op_del(re->data,curpos-n,n,NULL);
878
-                re->cursorpos-=n;
881
+                /* count the number of spaces at end of line */
882
+                n=0;
883
+                while((len-1-n-1)>=0 && start[len-1-n-1]==' ')
884
+                        n++;
885
+                /* delete the counted number of spaces at end of line */
886
+                redata_op_del(re->data,startpos+len-1-n,n,NULL);
887
+                /* fix cursorpos if it is after the deleted characters or over one of the deleted characters */
888
+                if(re->cursorpos>=(startpos+len-1))
889
+                        re->cursorpos-=n;
890
+                else if(re->cursorpos>=(startpos+len-1-n))
891
+                        re->cursorpos=(startpos+len-1-n);
879 892
                 if(trimmed!=NULL)
880 893
                         *trimmed=n;
881 894
         }
... ...
@@ -892,7 +905,7 @@ re_drawheader_editing(re_t *re)
892 905
                 line=col=-1;
893 906
         reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG);
894 907
         /* for the user, lines start at 0 (internally they start at 0) */
895
-        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos);
908
+        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li Size:%li",re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos,redata_getused(re->data));
896 909
         re->headerdirty=0;
897 910
         re->ui->rendererdirty=1;
898 911
         return(0);
Browse code

Normalize the scroll behaviour by using the same function everywhere instead of multiple instances of ad-hoc code to scroll.

Dario Rodriguez authored on 09/10/2020 22:44:05
Showing 1 changed files
... ...
@@ -77,6 +77,7 @@ int re_setuidata(re_t *re);
77 77
 
78 78
 int re_setfilename(re_t *re, char *filename);
79 79
 int re_fixorigin(re_t *re);
80
+int re_fixorigin_center(re_t *re);
80 81
 int re_processkey_editing(re_t *re, SDL_Event *event);
81 82
 int re_processkey_commandwait(re_t *re, SDL_Event *event);
82 83
 int re_processkey_commanddata(re_t *re, SDL_Event *event);
... ...
@@ -335,11 +336,7 @@ re_setuidata(re_t *re)
335 336
         re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
336 337
         re->maxrow=re->h/re->ui->fontheight-1;
337 338
         re->maxcol=re->w/re->ui->fontwidth-1;
338
-        if(re->curline>=(re->originline+re->maxrow)) {
339
-                re->originline=re->curline-re->maxrow;
340
-                re->originline=(re->originline<0)?0:re->originline;
341
-        }
342
-        re->origincol=(re->curcol>(re->maxcol-COLFORCESCROLL))?(re->curcol-(re->maxcol-COLFORCESCROLL)):0;
339
+        re_fixorigin(re);
343 340
         return(0);
344 341
 }
345 342
 
... ...
@@ -358,6 +355,30 @@ re_setfilename(re_t *re, char *filename)
358 355
 
359 356
 int
360 357
 re_fixorigin(re_t *re)
358
+{
359
+        if(re==NULL)
360
+                return(-1);
361
+        if(re->curline<(re->originline+LINEFORCESCROLL)) {
362
+                re->originline=re->curline-LINEFORCESCROLL;
363
+                re->originline=(re->originline<0)?0:re->originline;
364
+        }
365
+        if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL)) {
366
+                re->originline=re->curline+LINEFORCESCROLL-re->maxrow;
367
+                re->originline=(re->originline<0)?0:(re->originline>re->curline)?re->curline:re->originline;
368
+        }
369
+        if(re->curcol<re->origincol) {
370
+                re->origincol=re->curcol;
371
+                re->origincol=(re->origincol<0)?0:re->origincol;
372
+        }
373
+        if(re->curcol>=(re->origincol+re->maxcol-COLFORCESCROLL)) {
374
+                re->origincol=re->curcol+COLFORCESCROLL-re->maxcol;
375
+                re->origincol=(re->origincol<0)?0:re->origincol;
376
+        }
377
+        return(0);
378
+}
379
+
380
+int
381
+re_fixorigin_center(re_t *re)
361 382
 {
362 383
         if(re==NULL)
363 384
                 return(-1);
... ...
@@ -369,6 +390,7 @@ re_fixorigin(re_t *re)
369 390
         return(0);
370 391
 }
371 392
 
393
+
372 394
 int
373 395
 re_processkey_editing(re_t *re, SDL_Event *event)
374 396
 {
... ...
@@ -376,8 +398,8 @@ re_processkey_editing(re_t *re, SDL_Event *event)
376 398
         if(re==NULL || event==NULL)
377 399
                 return(-1); /* sanity check failed */
378 400
         /* convert RETURN KEYDOWN to TEXTINPUT */
379
-#warning XXX TODO: If the "\n" of end-of-file is deleted using DEL, the editor bugs
380 401
         if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_RETURN) {
402
+#warning file having two \n at the end, delete the second with DEL staying to the right of the first, if we go down then, it does an scroll but it shouldn't
381 403
                 memset(&fakeevent,0,sizeof(SDL_Event));
382 404
                 event=&fakeevent;
383 405
                 event->type=SDL_TEXTINPUT;
... ...
@@ -496,7 +518,7 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
496 518
                 re->cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
497 519
                 re->cursorpos=(re->cursorpos<0)?0:re->cursorpos;
498 520
                 redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
499
-                re_fixorigin(re);
521
+                re_fixorigin_center(re);
500 522
                 re->headerdirty=1;
501 523
                 re->contentsdirty=1;
502 524
         } else if(event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP) {
... ...
@@ -510,14 +532,7 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
510 532
                 re->cursorpos=newpos;
511 533
                 if(redata_pos2linecol(re->data,re->cursorpos,NULL,&(re->curcol))==-1)
512 534
                         return(-1); /* couldn't get col of current pos */;
513
-                if(re->curcol<re->origincol) {
514
-                        re->origincol=re->curcol;
515
-                        re->origincol=(re->origincol<0)?0:re->origincol;
516
-                }
517
-                if(re->curcol>(re->origincol+re->maxcol-COLFORCESCROLL)) {
518
-                        re->origincol=re->curcol+COLFORCESCROLL-re->maxcol;
519
-                        re->origincol=(re->origincol<0)?0:re->origincol;
520
-                }
535
+                re_fixorigin(re);
521 536
                 re->headerdirty=1;
522 537
                 re->contentsdirty=1;
523 538
         } else if(event->key.keysym.sym==SDLK_BACKSPACE && re->cursorpos>0) {
... ...
@@ -733,12 +748,7 @@ fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->cu
733 748
                 }
734 749
                 re->cursorpos=realstart;
735 750
                 re->curline+=inc;
736
-                if(re->curline<(re->originline+LINEFORCESCROLL)) {
737
-                        re->originline-=LINEFORCESCROLL;
738
-                        re->originline=(re->originline<0)?0:re->originline;
739
-                }
740
-                if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL))
741
-                        re->originline+=LINEFORCESCROLL;
751
+                re_fixorigin(re);
742 752
 #if 0
743 753
 fprintf(stderr,"MOVING   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
744 754
 #endif
Browse code

Remove superfluous initialization

Dario Rodriguez authored on 09/10/2020 21:55:37
Showing 1 changed files
... ...
@@ -122,11 +122,6 @@ main(int argc, char *argv[])
122 122
         setsignal(SIGINT,sighandler_sigint);
123 123
         setsignal(SIGPIPE,sighandler_sigpipe);
124 124
         do_exit=0;
125
-        if((ssel=sselect_init())==NULL) {
126
-                fprintf(stderr,"ERROR: filename too long.\n");
127
-                re_free(re),re=NULL;
128
-                return(2);
129
-        }
130 125
         reui_scr2renderer(re->ui,0,0,re->ui->w,re->ui->h);
131 126
         re_setuidata(re);
132 127
         re->headerdirty=1;
Browse code

fix bug: when loading a file, was not recognizing correctly if file ended in a newline or not

Dario Rodriguez authored on 09/10/2020 21:50:11
Showing 1 changed files
... ...
@@ -163,7 +163,7 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
163 163
                                 /* check if last character of file is '\n', if not, add it */
164 164
                                 if(redata_getused(re->data)==0
165 165
                                   || (redata_line_rawinfo(re->data,redata_getused(re->data)-1,&startpos,&startptr,&len,NULL)!=-1
166
-                                    && len>0 && startptr[len-1]!='\0')) {
166
+                                    && len>0 && startptr[len-1]!='\n')) {
167 167
                                         redata_op_add(re->data,redata_getused(re->data),"\n",1,NULL);
168 168
                                         re->command=COMMAND_WARNING;
169 169
                                         snprintf(re->commandbuf,sizeof(re->commandbuf),"Added missing \\n at end of file");
... ...
@@ -866,7 +866,9 @@ re_rtrim(re_t *re, long curpos, int *trimmed)
866 866
            len>1 && start[len-1]=='\n' && start[len-2]==' ' && curpos==(startpos+len-1)) {
867 867
                 for(n=1;(n+1)<(len-1) && start[len-1-n-1]==' ';n++)
868 868
                         ;
869
+#if 0
869 870
 fprintf(stderr,"Trying to DELETE SPACES del %i bytes\n",n);
871
+#endif
870 872
                 redata_op_del(re->data,curpos-n,n,NULL);
871 873
                 re->cursorpos-=n;
872 874
                 if(trimmed!=NULL)
Browse code

Implement Control+PageUp (go to first character in file) and Control+PageDown (go to last character in file). Fix corner cases with the last newline in file when loading and when using DEL.

Dario Rodriguez authored on 08/10/2020 21:18:18
Showing 1 changed files
... ...
@@ -58,6 +58,7 @@ typedef struct re_t {
58 58
         char *command;
59 59
         char commandbuf[COMMANDBUFSIZE];
60 60
         question_t *question;
61
+        int showingwarning;
61 62
         int ignorenkeys;
62 63
 } re_t;
63 64
 
... ...
@@ -75,6 +76,7 @@ void re_free(re_t *re);
75 76
 int re_setuidata(re_t *re);
76 77
 
77 78
 int re_setfilename(re_t *re, char *filename);
79
+int re_fixorigin(re_t *re);
78 80
 int re_processkey_editing(re_t *re, SDL_Event *event);
79 81
 int re_processkey_commandwait(re_t *re, SDL_Event *event);
80 82
 int re_processkey_commanddata(re_t *re, SDL_Event *event);
... ...
@@ -145,6 +147,9 @@ main(int argc, char *argv[])
145 147
 fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body);
146 148
 #endif
147 149
                         } else {
150
+                                long startpos;
151
+                                char *startptr;
152
+                                int len;
148 153
                                 if(redata_load(re->data,re->filename,NULL)==-1)
149 154
                                         re->flag_newfile=1;
150 155
                                 else
... ...
@@ -155,6 +160,15 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
155 160
                                 load_pending=0;
156 161
                                 re->headerdirty=1;
157 162
                                 re->contentsdirty=1;
163
+                                /* check if last character of file is '\n', if not, add it */
164
+                                if(redata_getused(re->data)==0
165
+                                  || (redata_line_rawinfo(re->data,redata_getused(re->data)-1,&startpos,&startptr,&len,NULL)!=-1
166
+                                    && len>0 && startptr[len-1]!='\0')) {
167
+                                        redata_op_add(re->data,redata_getused(re->data),"\n",1,NULL);
168
+                                        re->command=COMMAND_WARNING;
169
+                                        snprintf(re->commandbuf,sizeof(re->commandbuf),"Added missing \\n at end of file");
170
+                                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
171
+                                }
158 172
                         }
159 173
                 }
160 174
                 if(re->headerdirty) {
... ...
@@ -163,6 +177,7 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
163 177
 fprintf(stderr,"REDRAW Header (editing)\n");
164 178
 #endif
165 179
                                 re_drawheader_editing(re);
180
+                                re->showingwarning=0;
166 181
                         } else {
167 182
 #if 0
168 183
 fprintf(stderr,"REDRAW Header (command)\n");
... ...
@@ -172,6 +187,9 @@ fprintf(stderr,"REDRAW Header (command)\n");
172 187
                                         /* the warnings only get shown once, remove it */
173 188
                                         re->command=NULL;
174 189
                                         re->commandbuf[0]='\0';
190
+                                        re->showingwarning=1;
191
+                                } else {
192
+                                        re->showingwarning=0;
175 193
                                 }
176 194
                         }
177 195
                 }
... ...
@@ -224,9 +242,9 @@ fprintf(stderr,"WINDOWEVENT: %s(%li) data1:%li data2:%li\n",
224 242
 #endif
225 243
                                         if(event.window.event==SDL_WINDOWEVENT_SHOWN
226 244
                                           || event.window.event==SDL_WINDOWEVENT_EXPOSED) {
227
-                                                re->headerdirty=1;
245
+                                                if(!re->showingwarning)
246
+                                                        re->headerdirty=1;
228 247
                                                 re->contentsdirty=1;
229
-                                                re->ui->rendererdirty=1;
230 248
                                         } else if((event.window.event==SDL_WINDOWEVENT_RESIZED
231 249
                                           || event.window.event==SDL_WINDOWEVENT_SIZE_CHANGED)
232 250
                                           && (event.window.data1!=re->ui->w || event.window.data2!=re->ui->h)) {
... ...
@@ -238,7 +256,6 @@ fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)even
238 256
                                                 re_setuidata(re);
239 257
                                                 re->headerdirty=1;
240 258
                                                 re->contentsdirty=1;
241
-                                                re->ui->rendererdirty=1;
242 259
                                         }
243 260
                                         break;
244 261
                                 default:
... ...
@@ -344,6 +361,19 @@ re_setfilename(re_t *re, char *filename)
344 361
         return(0);
345 362
 }
346 363
 
364
+int
365
+re_fixorigin(re_t *re)
366
+{
367
+        if(re==NULL)
368
+                return(-1);
369
+        if(re->curline<re->originline || re->curline>=(re->originline+re->maxrow)) {
370
+                re->originline=re->curline-(re->maxrow/2);
371
+                re->originline=(re->originline<0)?0:re->originline;
372
+        }
373
+        re->origincol=(re->curcol>(re->maxcol-COLFORCESCROLL))?(re->curcol-(re->maxcol-COLFORCESCROLL)):0;
374
+        return(0);
375
+}
376
+
347 377
 int
348 378
 re_processkey_editing(re_t *re, SDL_Event *event)
349 379
 {
... ...
@@ -366,7 +396,7 @@ re_processkey_editing(re_t *re, SDL_Event *event)
366 396
                 strncpy(event->text.text,spaces+(re->curcol%8),sizeof(event->text.text));
367 397
                 event->text.text[sizeof(event->text.text)-1]='\0';
368 398
         } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_DELETE) {
369
-#if 1
399
+#if 0
370 400
 fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
371 401
 #endif
372 402
                 long realend;
... ...
@@ -376,6 +406,8 @@ fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
376 406
                 if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
377 407
                         return(-1); /* couldn't get current line info */
378 408
                 at_end=(re->cursorpos==realend)?1:0;
409
+                if(at_end && (re->cursorpos+1)==redata_getused(re->data))
410
+                        return(-1); /* we shouldn't erase the final '\n' */
379 411
                 memset(&fakeevent,0,sizeof(SDL_Event));
380 412
                 event=&fakeevent;
381 413
                 event->type=SDL_KEYDOWN;
... ...
@@ -394,7 +426,7 @@ fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
394 426
                 } else {
395 427
                         re_moveleftright(re,1);
396 428
                 }
397
-#if 1
429
+#if 0
398 430
 fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
399 431
 #endif
400 432
         }
... ...
@@ -408,7 +440,7 @@ fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
408 440
                         re->ignorenkeys--;
409 441
                         return(0); /* this is an already processed key, ignore it */
410 442
                 }
411
-#if 1
443
+#if 0
412 444
 fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
413 445
 #endif
414 446
                 if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
... ...
@@ -458,13 +490,20 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed
458 490
         /* default case: keydown event */
459 491
         if(event->type!=SDL_KEYDOWN)
460 492
                 return(0); /* Ignore other possible events */
461
-#if 1
493
+#if 0
462 494
 fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
463 495
 #endif
464 496
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
465 497
                 re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1);
466 498
         } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
467 499
                 re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
500
+        } else if((SDL_GetModState()&KMOD_CTRL)!=0 && (event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP)) {
501
+                re->cursorpos=(event->key.keysym.sym==SDLK_PAGEDOWN)?(redata_getused(re->data)-1):0;
502
+                re->cursorpos=(re->cursorpos<0)?0:re->cursorpos;
503
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
504
+                re_fixorigin(re);
505
+                re->headerdirty=1;
506
+                re->contentsdirty=1;
468 507
         } else if(event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP) {
469 508
                 re_moveupdown(re,(event->key.keysym.sym==SDLK_PAGEUP)?-(re->maxrow):re->maxrow);
470 509
         } else if(event->key.keysym.sym==SDLK_HOME || event->key.keysym.sym==SDLK_END) {
... ...
@@ -561,17 +600,14 @@ fprintf(stderr,"re_processkey(): received Control+z\n");
561 600
                         return(-1);
562 601
                 re->cursorpos=newpos;
563 602
                 redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
564
-                if(re->curline<re->originline || re->curline>=(re->originline+re->maxrow)) {
565
-                        re->originline=re->curline-(re->maxrow/2);
566
-                        re->originline=(re->originline<0)?0:re->originline;
567
-                }
568
-                re->origincol=(re->curcol>(re->maxcol-COLFORCESCROLL))?(re->curcol-(re->maxcol-COLFORCESCROLL)):0;
603
+                re_fixorigin(re);
569 604
                 re->headerdirty=1;
570 605
                 re->contentsdirty=1;
571 606
         }
572 607
         return(0);
573 608
 }
574 609
 
610
+
575 611
 int
576 612
 re_processkey_commandwait(re_t *re, SDL_Event *event)
577 613
 {
Browse code

Implement window resizizing

Dario Rodriguez authored on 08/10/2020 19:52:50
Showing 1 changed files
... ...
@@ -72,6 +72,7 @@ static void sighandler_sigpipe(int num);
72 72
 
73 73
 re_t *re_init(void);
74 74
 void re_free(re_t *re);
75
+int re_setuidata(re_t *re);
75 76
 
76 77
 int re_setfilename(re_t *re, char *filename);
77 78
 int re_processkey_editing(re_t *re, SDL_Event *event);
... ...
@@ -125,9 +126,7 @@ main(int argc, char *argv[])
125 126
                 return(2);
126 127
         }
127 128
         reui_scr2renderer(re->ui,0,0,re->ui->w,re->ui->h);
128
-        re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
129
-        re->maxrow=re->h/re->ui->fontheight-1;
130
-        re->maxcol=re->w/re->ui->fontwidth-1;
129
+        re_setuidata(re);
131 130
         re->headerdirty=1;
132 131
         re->contentsdirty=1;
133 132
         flag_had_events=0;
... ...
@@ -150,7 +149,6 @@ fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body)
150 149
                                         re->flag_newfile=1;
151 150
                                 else
152 151
                                         re->flag_newfile=0;
153
-#warning XXX TODO: NO PARECE FUNCIONAR EL PLUGIN_UNSAVED (pregunta pero no carga los cambios)
154 152
                                 re->originline=re->origincol=0;
155 153
                                 re->curline=re->curcol=0;
156 154
                                 re->cursorpos=0;
... ...
@@ -179,8 +177,12 @@ fprintf(stderr,"REDRAW Header (command)\n");
179 177
                 }
180 178
                 if(re->contentsdirty)
181 179
                         re_drawcontents(re);
182
-                if(re->ui->rendererdirty)
180
+                if(re->ui->rendererdirty) {
181
+#if 0
182
+fprintf(stderr,"RENDER\n");
183
+#endif
183 184
                         reui_present(re->ui);
185
+                }
184 186
                 sselect_wait(ssel,(flag_had_events)?10:100);
185 187
                 flag_had_events=(flag_had_events>0)?flag_had_events-1:0;
186 188
                 SDL_PumpEvents();
... ...
@@ -201,8 +203,41 @@ fprintf(stderr,"REDRAW Header (command)\n");
201 203
                                                 re_processkey_commanddata(re,&event);
202 204
                                         break;
203 205
                                 case SDL_WINDOWEVENT:
206
+#if 0
207
+fprintf(stderr,"WINDOWEVENT: %s(%li) data1:%li data2:%li\n",
208
+(event.window.event==SDL_WINDOWEVENT_NONE)?"NONE":
209
+(event.window.event==SDL_WINDOWEVENT_SHOWN)?"SHOWN":
210
+(event.window.event==SDL_WINDOWEVENT_HIDDEN)?"HIDDEN":
211
+(event.window.event==SDL_WINDOWEVENT_EXPOSED)?"EXPOSED":
212
+(event.window.event==SDL_WINDOWEVENT_MOVED)?"MOVED":
213
+(event.window.event==SDL_WINDOWEVENT_RESIZED)?"RESIZED":
214
+(event.window.event==SDL_WINDOWEVENT_SIZE_CHANGED)?"SIZE_CHANGED":
215
+(event.window.event==SDL_WINDOWEVENT_MINIMIZED)?"MINIMIZED":
216
+(event.window.event==SDL_WINDOWEVENT_MAXIMIZED)?"MAXIMIZED":
217
+(event.window.event==SDL_WINDOWEVENT_RESTORED)?"RESTORED":
218
+(event.window.event==SDL_WINDOWEVENT_FOCUS_GAINED)?"FOCUS_GAINED":
219
+(event.window.event==SDL_WINDOWEVENT_FOCUS_LOST)?"FOCUS_LOST":
220
+(event.window.event==SDL_WINDOWEVENT_CLOSE)?"CLOSE":
221
+(event.window.event==SDL_WINDOWEVENT_TAKE_FOCUS)?"TAKE_FOCUS":
222
+"UNKNOWN",
223
+(long) event.window.event,(long)event.window.data1,(long)event.window.data2);
224
+#endif
204 225
                                         if(event.window.event==SDL_WINDOWEVENT_SHOWN
205 226
                                           || event.window.event==SDL_WINDOWEVENT_EXPOSED) {
227
+                                                re->headerdirty=1;
228
+                                                re->contentsdirty=1;
229
+                                                re->ui->rendererdirty=1;
230
+                                        } else if((event.window.event==SDL_WINDOWEVENT_RESIZED
231
+                                          || event.window.event==SDL_WINDOWEVENT_SIZE_CHANGED)
232
+                                          && (event.window.data1!=re->ui->w || event.window.data2!=re->ui->h)) {
233
+#if 0
234
+fprintf(stderr,"Resizing from %ix%i to %ix%i...\n",re->ui->w,re->ui->h,(int)event.window.data1,(int)event.window.data2);
235
+#endif
236
+                                                reui_resize(re->ui,event.window.data1,event.window.data2);
237
+
238
+                                                re_setuidata(re);
239
+                                                re->headerdirty=1;
240
+                                                re->contentsdirty=1;
206 241
                                                 re->ui->rendererdirty=1;
207 242
                                         }
208 243
                                         break;
... ...
@@ -280,6 +315,23 @@ re_free(re_t *re)
280 315
         return;
281 316
 }
282 317
 
318
+int
319
+re_setuidata(re_t *re)
320
+{
321
+        if(re==NULL)
322
+                return(-1);
323
+        re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
324
+        re->maxrow=re->h/re->ui->fontheight-1;
325
+        re->maxcol=re->w/re->ui->fontwidth-1;
326
+        if(re->curline>=(re->originline+re->maxrow)) {
327
+                re->originline=re->curline-re->maxrow;
328
+                re->originline=(re->originline<0)?0:re->originline;
329
+        }
330
+        re->origincol=(re->curcol>(re->maxcol-COLFORCESCROLL))?(re->curcol-(re->maxcol-COLFORCESCROLL)):0;
331
+        return(0);
332
+}
333
+
334
+
283 335
 int
284 336
 re_setfilename(re_t *re, char *filename)
285 337
 {
... ...
@@ -755,8 +807,8 @@ re_moveleftright(re_t *re, int totalinc)
755 807
                         re->origincol=re->origincol*COLFORCESCROLL;
756 808
                         re->origincol=(re->origincol<0)?0:re->origincol;
757 809
                 }
758
-                if(re->curcol>(re->origincol+re->maxrow-COLFORCESCROLL)) {
759
-                        re->origincol=re->curcol+COLFORCESCROLL-re->maxrow-(re->curcol%COLFORCESCROLL);
810
+                if(re->curcol>(re->origincol+re->maxcol-COLFORCESCROLL)) {
811
+                        re->origincol=re->curcol+COLFORCESCROLL-re->maxcol-(re->curcol%COLFORCESCROLL);
760 812
                         re->origincol=(re->origincol<0)?0:re->origincol;
761 813
                 }
762 814
         }
Browse code

Implement TAB: insert spaces until next tabstop. Implement DEL: erase to the right.

Dario Rodriguez authored on 07/10/2020 21:08:18
Showing 1 changed files
... ...
@@ -295,22 +295,63 @@ re_setfilename(re_t *re, char *filename)
295 295
 int
296 296
 re_processkey_editing(re_t *re, SDL_Event *event)
297 297
 {
298
-        SDL_Event returnevent;
298
+        SDL_Event fakeevent;
299 299
         if(re==NULL || event==NULL)
300 300
                 return(-1); /* sanity check failed */
301 301
         /* convert RETURN KEYDOWN to TEXTINPUT */
302
+#warning XXX TODO: If the "\n" of end-of-file is deleted using DEL, the editor bugs
302 303
         if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_RETURN) {
303
-                memset(&returnevent,0,sizeof(SDL_Event));
304
-                event=&returnevent;
304
+                memset(&fakeevent,0,sizeof(SDL_Event));
305
+                event=&fakeevent;
305 306
                 event->type=SDL_TEXTINPUT;
306 307
                 strncpy(event->text.text,"\n",sizeof(event->text.text));
307 308
                 event->text.text[sizeof(event->text.text)-1]='\0';
309
+        } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_TAB) {
310
+                static char spaces[8]={"        "};
311
+                memset(&fakeevent,0,sizeof(SDL_Event));
312
+                event=&fakeevent;
313
+                event->type=SDL_TEXTINPUT;
314
+                strncpy(event->text.text,spaces+(re->curcol%8),sizeof(event->text.text));
315
+                event->text.text[sizeof(event->text.text)-1]='\0';
316
+        } else if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_DELETE) {
317
+#if 1
318
+fprintf(stderr,"SDL_KEYDOWN: DELETE\n");
319
+#endif
320
+                long realend;
321
+                int at_end;
322
+                if(re->cursorpos==redata_getused(re->data))
323
+                        return(0); /* already at end, nothing to delete */
324
+                if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
325
+                        return(-1); /* couldn't get current line info */
326
+                at_end=(re->cursorpos==realend)?1:0;
327
+                memset(&fakeevent,0,sizeof(SDL_Event));
328
+                event=&fakeevent;
329
+                event->type=SDL_KEYDOWN;
330
+                event->key.keysym.sym=SDLK_BACKSPACE;
331
+                redata_undo_groupinit(re->data,NULL);
332
+                if(at_end) {
333
+                        int col;
334
+                        if(redata_pos2linecol(re->data,re->cursorpos,NULL,&col)==-1)
335
+                                return(-1); /* couldn't get line info */
336
+                        if(redata_op_addn(re->data,re->cursorpos,' ',re->curcol-col,NULL)!=0)
337
+                                return(-1); /* couldn't add spaces up to current displayed pos */
338
+                        re->cursorpos+=re->curcol-col;
339
+                        re->cursorpos++;
340
+                        re->curline++;
341
+                        re->curcol=0;
342
+                } else {
343
+                        re_moveleftright(re,1);
344
+                }
345
+#if 1
346
+fprintf(stderr,"SDL_KEYDOWN: fake setup ok\n");
347
+#endif
308 348
         }
309 349
         /* special case: text editing event */
310 350
         if(event->type==SDL_TEXTINPUT) {
311 351
                 int len;
312 352
                 long realend;
313 353
                 int at_end;
354
+                int nspaces;
314 355
                 if(re->ignorenkeys>0) {
315 356
                         re->ignorenkeys--;
316 357
                         return(0); /* this is an already processed key, ignore it */
... ...
@@ -321,13 +362,15 @@ fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
321 362
                 if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
322 363
                         return(-1); /* couldn't get current line info */
323 364
                 at_end=(re->cursorpos==realend)?1:0;
324
-                if(event->text.text[0]==' ' && event->text.text[1]=='\0' && at_end) {
325
-                        /* instead of adding a space at the end of the line, we move the cursor to the right */
326
-                        re_moveleftright(re,1);
365
+                for(nspaces=0;event->text.text[nspaces]==' ';nspaces++)
366
+                        ;
367
+                if(nspaces>0 && event->text.text[nspaces]=='\0' && at_end) {
368
+                        /* instead of adding spaces at the end of the line, we move the cursor to the right */
369
+                        re_moveleftright(re,nspaces);
327 370
                         return(0); /* no need to add spaces at the end of the line */
328 371
                 }
329 372
                 redata_undo_groupinit(re->data,NULL);
330
-                if(event!=&returnevent && at_end) {
373
+                if(!(event->text.text[0]=='\n' && event->text.text[1]=='\0') && at_end) {
331 374
                         int col;
332 375
                         if(redata_pos2linecol(re->data,re->cursorpos,NULL,&col)==-1)
333 376
                                 return(-1); /* couldn't get line info */
... ...
@@ -340,7 +383,7 @@ fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
340 383
                 if(redata_op_add(re->data,re->cursorpos,event->text.text,len,NULL)!=0)
341 384
                         return(-1); /* couldn't add requested text */
342 385
                 re->cursorpos+=len;
343
-                if(event==&returnevent) {
386
+                if(event->text.text[0]=='\n' && event->text.text[1]=='\0') {
344 387
                         int trimmed;
345 388
                         if(re_rtrim(re,re->cursorpos-len,&trimmed))
346 389
                                 re->cursorpos-=trimmed;
... ...
@@ -363,7 +406,7 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed
363 406
         /* default case: keydown event */
364 407
         if(event->type!=SDL_KEYDOWN)
365 408
                 return(0); /* Ignore other possible events */
366
-#if 0
409
+#if 1
367 410
 fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
368 411
 #endif
369 412
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
... ...
@@ -398,13 +441,17 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
398 441
                 int len;
399 442
                 int trimmed;
400 443
                 int doneinc;
444
+#if 0
445
+fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
446
+#endif
401 447
                 if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
402 448
                         return(-1); /* couldn't get current line data */
403 449
                 if(col<re->curcol) {
404 450
                         re_moveleftright(re,-1);
405 451
                         return(0); /* were hovering to the right of last char, only had to move left */
406 452
                 }
407
-                redata_undo_groupinit(re->data,NULL);
453
+                if(event!=&fakeevent)
454
+                        redata_undo_groupinit(re->data,NULL);
408 455
                 /* delete the last character */
409 456
                 if(col>0) {
410 457
                         if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
... ...
@@ -846,7 +893,7 @@ re_drawcontents(re_t *re)
846 893
                                         drawn_cursor=1;
847 894
                                         curptr=redata_generic_utf8col(ptr,len-has_nl,re->curcol-tmpcol);
848 895
                                         curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
849
-                                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));
896
+                                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(curptr,curptrlen));
850 897
                                 }
851 898
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
852 899
                         }
Browse code

Support the unsaved data recovery plugin from redata. Rework the question interface.

Dario Rodriguez authored on 05/10/2020 21:42:19
Showing 1 changed files
... ...
@@ -13,18 +13,24 @@
13 13
 #include <string.h>
14 14
 #include <limits.h>
15 15
 #include <signal.h>
16
+#include <time.h>
16 17
 
17 18
 #include "re_data.h"
19
+#include "re_plugin_unsaved.h"
18 20
 #include "re_ui.h"
19 21
 #include "ext/socklib.h"
20 22
 
21 23
 #define LINEFORCESCROLL 1
22 24
 #define COLFORCESCROLL 5
23 25
 
26
+#define IDLETIMEOUTSECONDS 10
27
+
24 28
 #define COMMANDBUFSIZE 1024
25 29
 
26 30
 #define COMMAND_WARNING "(!)"
27 31
 #define COMMAND_GOTOLINE "Go to line: "
32
+#define COMMAND_QUESTION "(?)"
33
+#define COMMAND_EXIT "Exit"
28 34
 
29 35
 #define COLOR_STATUSBG "\x00\x00\xff\xff"
30 36
 #define COLOR_STATUSFG "\xff\xff\x00\xff"
... ...
@@ -48,8 +54,10 @@ typedef struct re_t {
48 54
         int maxrow,maxcol;
49 55
         int headerdirty;
50 56
         int contentsdirty;
57
+        int command_first_key;
51 58
         char *command;
52 59
         char commandbuf[COMMANDBUFSIZE];
60
+        question_t *question;
53 61
         int ignorenkeys;
54 62
 } re_t;
55 63
 
... ...
@@ -86,6 +94,8 @@ main(int argc, char *argv[])
86 94
         SDL_Event event;
87 95
         sselect *ssel;
88 96
         int flag_had_events;
97
+        time_t lastidle,now;
98
+        int load_pending;
89 99
         if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
90 100
                 fprintf(stderr,"Syntax: %s filename\n",argv[0]);
91 101
                 return(1);
... ...
@@ -104,18 +114,6 @@ main(int argc, char *argv[])
104 114
                 re_free(re),re=NULL;
105 115
                 return(2);
106 116
         }
107
-        if((redata_load(re->data,re->filename,NULL,NULL))!=0)
108
-                re->flag_newfile=1;
109
-        else
110
-                re->flag_newfile=0;
111
-#if 0
112
-#warning TESTS
113
-        {
114
-                char buf[129];
115
-                redata_hash(re->data,buf);
116
-                fprintf(stderr,"%s %s\n",buf,re->filename);
117
-        }
118
-#endif
119 117
         reui_title(re->ui,re->filename);
120 118
         flag_sigint=flag_sigpipe=0;
121 119
         setsignal(SIGINT,sighandler_sigint);
... ...
@@ -134,13 +132,43 @@ main(int argc, char *argv[])
134 132
         re->contentsdirty=1;
135 133
         flag_had_events=0;
136 134
         SDL_StartTextInput();
135
+        lastidle=0;
136
+        load_pending=1;
137
+        redata_loadquestions_setup(re->data, re->filename);
137 138
         while(do_exit==0 && flag_sigint==0) {
139
+                /* load file (or ask pre-load questions), if pending */
140
+                if(load_pending && re->command==NULL) {
141
+                        question_t *question;
142
+                        if((question=redata_loadquestions_getnext(re->data))!=NULL) {
143
+                                re->command=COMMAND_QUESTION;
144
+                                re->question=question;
145
+#if 0
146
+fprintf(stderr,"QUESTION INIT: %s: %s\n",re->question->title,re->question->body);
147
+#endif
148
+                        } else {
149
+                                if(redata_load(re->data,re->filename,NULL)==-1)
150
+                                        re->flag_newfile=1;
151
+                                else
152
+                                        re->flag_newfile=0;
153
+#warning XXX TODO: NO PARECE FUNCIONAR EL PLUGIN_UNSAVED (pregunta pero no carga los cambios)
154
+                                re->originline=re->origincol=0;
155
+                                re->curline=re->curcol=0;
156
+                                re->cursorpos=0;
157
+                                load_pending=0;
158
+                                re->headerdirty=1;
159
+                                re->contentsdirty=1;
160
+                        }
161
+                }
138 162
                 if(re->headerdirty) {
139 163
                         if(re->command==NULL) {
164
+#if 0
140 165
 fprintf(stderr,"REDRAW Header (editing)\n");
166
+#endif
141 167
                                 re_drawheader_editing(re);
142 168
                         } else {
169
+#if 0
143 170
 fprintf(stderr,"REDRAW Header (command)\n");
171
+#endif
144 172
                                 re_drawheader_command(re);
145 173
                                 if(strcmp(re->command,COMMAND_WARNING)==0) {
146 174
                                         /* the warnings only get shown once, remove it */
... ...
@@ -182,6 +210,15 @@ fprintf(stderr,"REDRAW Header (command)\n");
182 210
                                         break;
183 211
                         }
184 212
                 }
213
+                /* additional processing of global commands */
214
+                if(re->command!=NULL && strcmp(re->command,COMMAND_EXIT)==0)
215
+                        do_exit=1;
216
+                /* timeouts */
217
+                now=time(NULL);
218
+                if((lastidle+IDLETIMEOUTSECONDS)<now || (lastidle-IDLETIMEOUTSECONDS)>now) {
219
+                        lastidle=now;
220
+                        redata_idleproc(re->data,re->filename);
221
+                }
185 222
         }
186 223
         SDL_StopTextInput();
187 224
         sselect_free(ssel),ssel=NULL;
... ...
@@ -219,7 +256,7 @@ re_init(void)
219 256
         if((re=malloc(sizeof(re_t)))==NULL)
220 257
                 return(NULL); /* insuf. mem. */
221 258
         memset(re,0,sizeof(re_t));
222
-        if((re->data=redata_init(NULL))==NULL) {
259
+        if((re->data=redata_init(redata_unsaved_register,NULL))==NULL) {
223 260
                 re_free(re),re=NULL;
224 261
                 return(NULL); /* insuf. mem. */
225 262
         }
... ...
@@ -326,7 +363,7 @@ fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->ed
326 363
         /* default case: keydown event */
327 364
         if(event->type!=SDL_KEYDOWN)
328 365
                 return(0); /* Ignore other possible events */
329
-#if 1
366
+#if 0
330 367
 fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
331 368
 #endif
332 369
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
... ...
@@ -411,10 +448,15 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
411 448
         } else if(event->key.keysym.sym==SDLK_q && (SDL_GetModState()&KMOD_CTRL)!=0) {
412 449
 fprintf(stderr,"re_processkey(): received Control+q\n");
413 450
                 re->command="";
451
+                re->command_first_key='q';
452
+                re->headerdirty=1;
453
+        } else if(event->key.keysym.sym==SDLK_k && (SDL_GetModState()&KMOD_CTRL)!=0) {
454
+fprintf(stderr,"re_processkey(): received Control+k\n");
455
+                re->command="";
456
+                re->command_first_key='k';
414 457
                 re->headerdirty=1;
415 458
         } else if(event->key.keysym.sym==SDLK_z && (SDL_GetModState()&KMOD_CTRL)!=0) {
416 459
                 long newpos;
417
-                int oldline;
418 460
 fprintf(stderr,"re_processkey(): received Control+z\n");
419 461
                 if(redata_op_undo(re->data,&newpos))
420 462
                         return(-1);
... ...
@@ -439,10 +481,14 @@ re_processkey_commandwait(re_t *re, SDL_Event *event)
439 481
         /* default case: keydown event */
440 482
         if(event->type!=SDL_KEYDOWN)
441 483
                 return(0); /* Ignore other possible events */
442
-        if(event->key.keysym.sym==SDLK_l) {
484
+        if(re->command_first_key=='q' && event->key.keysym.sym==SDLK_l) {
443 485
                 re->command=COMMAND_GOTOLINE;
444 486
                 re->commandbuf[0]='\0';
445 487
                 re->headerdirty=1;
488
+        } else if(re->command_first_key=='k' && event->key.keysym.sym==SDLK_q) {
489
+                re->command=COMMAND_EXIT;
490
+                re->commandbuf[0]='\0';
491
+                re->headerdirty=1;
446 492
         } else {
447 493
                 re->command=NULL;
448 494
                 re->headerdirty=1;
... ...
@@ -478,6 +524,7 @@ re_processkey_commanddata(re_t *re, SDL_Event *event)
478 524
                 re->command=NULL;
479 525
                 re->commandbuf[0]='\0';
480 526
                 re->headerdirty=1;
527
+#warning XXX: TODO: re->question: Make cursor change option, make numbers change option
481 528
         } else if(event->key.keysym.sym==SDLK_BACKSPACE && re->commandbuf[0]!='\0') {
482 529
                 int nchar;
483 530
                 char *ptr;
... ...
@@ -517,6 +564,17 @@ re_processcommand(re_t *re)
517 564
                 re->originline=line-(re->maxrow/2);
518 565
                 re->headerdirty=1;
519 566
                 re->contentsdirty=1;
567
+        } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
568
+                /* validate reply */
569
+                if(!(atoi(re->commandbuf)>0 && atoi(re->commandbuf)<=re->question->nopts)) {
570
+                        /* invalid reply: reset buf */
571
+                        re->commandbuf[0]=0;
572
+                        re->headerdirty=1;
573
+                        return(-1);
574
+                }
575
+                /* send reply */
576
+                redata_loadquestions_reply(re->data,re->question,atoi(re->commandbuf)-1);
577
+                re->headerdirty=1;
520 578
         }
521 579
         re->command=NULL;
522 580
         re->commandbuf[0]='\0';
... ...
@@ -536,7 +594,9 @@ re_moveupdown(re_t *re, int totalinc)
536 594
         inc=(totalinc<0)?-1:1;
537 595
         newpos=re->cursorpos; /* get rid of compiler warning (will be overwitten in the loop as totalinc never is 0) */
538 596
         for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
597
+#if 0
539 598
 fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
599
+#endif
540 600
                 if((inc==-1 && redata_line_prevrealstart(re->data,re->cursorpos,&realstart)==-1)
541 601
                    || (inc==1 && redata_line_nextrealstart(re->data,re->cursorpos,&realstart)==-1)) {
542 602
                         break; /* couldn't get current line data, we are at start/end */
... ...
@@ -549,17 +609,25 @@ fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->cu
549 609
                 }
550 610
                 if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL))
551 611
                         re->originline+=LINEFORCESCROLL;
612
+#if 0
552 613
 fprintf(stderr,"MOVING   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
614
+#endif
553 615
         }
554 616
         if(redata_line_inccol(re->data,re->cursorpos,re->curcol,&newpos2,NULL)==-1) {
555 617
                 /* error advancing cursor, "emergency" repositioning */
618
+#if 0
556 619
 fprintf(stderr,"COLUMN ERROR\n");
620
+#endif
557 621
                 re->curcol=0;
558 622
                 newpos2=newpos;
559 623
         }
624
+#if 0
560 625
 fprintf(stderr,"COLUMN from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
626
+#endif
561 627
         re->cursorpos=newpos2;
628
+#if 0
562 629
 fprintf(stderr,"COLUMN   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
630
+#endif
563 631
         re->contentsdirty=1;
564 632
         re->headerdirty=1;
565 633
         return(0);
... ...
@@ -701,6 +769,21 @@ re_drawheader_command(re_t *re)
701 769
         } else if(strcmp(re->command,COMMAND_WARNING)==0) {
702 770
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG);
703 771
                 reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf);
772
+        } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
773
+                question_t *q;
774
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
775
+#warning XXX TODO: suppont arbitrary number of options, highlight current option
776
+                q=re->question;
777
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
778
+                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s %s: %s %s%s%s%s%s%s%s%s: %s"
779
+                   ,re->command
780
+                   ,(q->titleshort!=NULL)?q->titleshort:q->title
781
+                   ,(q->bodyshort!=NULL)?q->bodyshort:q->body
782
+                   ,(q->nopts>0)?"1.":"",(q->nopts>0)?(q->optsshort!=NULL)?q->optsshort[0]:q->opts[0]:""
783
+                   ,(q->nopts>1)?" 2.":"",(q->nopts>1)?(q->optsshort!=NULL)?q->optsshort[1]:q->opts[1]:""
784
+                   ,(q->nopts>2)?" 3.":"",(q->nopts>2)?(q->optsshort!=NULL)?q->optsshort[2]:q->opts[2]:""
785
+                   ,(q->nopts>3)?" 4.":"",(q->nopts>4)?(q->optsshort!=NULL)?q->optsshort[3]:q->opts[3]:""
786
+                   ,re->commandbuf);
704 787
         } else {
705 788
                 reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
706 789
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
Browse code

Have the UI use the undo facilities of re_data.c when Ctrl-Z is pressed

Dario Rodriguez authored on 26/09/2020 21:23:03
Showing 1 changed files
... ...
@@ -412,6 +412,21 @@ fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
412 412
 fprintf(stderr,"re_processkey(): received Control+q\n");
413 413
                 re->command="";
414 414
                 re->headerdirty=1;
415
+        } else if(event->key.keysym.sym==SDLK_z && (SDL_GetModState()&KMOD_CTRL)!=0) {
416
+                long newpos;
417
+                int oldline;
418
+fprintf(stderr,"re_processkey(): received Control+z\n");
419
+                if(redata_op_undo(re->data,&newpos))
420
+                        return(-1);
421
+                re->cursorpos=newpos;
422
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
423
+                if(re->curline<re->originline || re->curline>=(re->originline+re->maxrow)) {
424
+                        re->originline=re->curline-(re->maxrow/2);
425
+                        re->originline=(re->originline<0)?0:re->originline;
426
+                }
427
+                re->origincol=(re->curcol>(re->maxcol-COLFORCESCROLL))?(re->curcol-(re->maxcol-COLFORCESCROLL)):0;
428
+                re->headerdirty=1;
429
+                re->contentsdirty=1;
415 430
         }
416 431
         return(0);
417 432
 }
Browse code

Implement redata_linecol2pos() so that 'Go To Line' can do its thing

Dario Rodriguez authored on 25/09/2020 20:49:13
Showing 1 changed files
... ...
@@ -487,8 +487,9 @@ re_processcommand(re_t *re)
487 487
         if(strcmp(re->command,COMMAND_GOTOLINE)==0) {
488 488
                 int line;
489 489
                 long pos;
490
-                line=atoi(re->commandbuf);
491
-                if(redata_linecol2pos(re->data,line,0,&pos,NULL)==-1) {
490
+                line=atoi(re->commandbuf)-1;
491
+                line=(line<0)?0:line;
492
+                if(redata_linecol2pos(re->data,line,re->curcol,&pos,NULL)==-1) {
492 493
                         re->command=COMMAND_WARNING;
493 494
                         snprintf(re->commandbuf,sizeof(re->commandbuf),"Unknown line");
494 495
                         re->commandbuf[sizeof(re->commandbuf)-1]='\0';
... ...
@@ -496,13 +497,9 @@ re_processcommand(re_t *re)
496 497
                         return(-1);
497 498
                 }
498 499
                 re->cursorpos=pos;
499
-                re->curcol=0;
500 500
                 re->curline=line;
501
-                re->origincol=0;
502
-                if((re->originline+re->maxrow)<line)
503
-                        re->originline=line-re->maxrow;
504
-                if(line<re->originline)
505
-                        re->originline=line;
501
+                /* position the line in the center of viewport */
502
+                re->originline=line-(re->maxrow/2);
506 503
                 re->headerdirty=1;
507 504
                 re->contentsdirty=1;
508 505
         }
... ...
@@ -669,7 +666,8 @@ re_drawheader_editing(re_t *re)
669 666
         if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
670 667
                 line=col=-1;
671 668
         reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG);
672
-        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline,line,re->curcol,col,re->cursorpos);
669
+        /* for the user, lines start at 0 (internally they start at 0) */
670
+        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos);
673 671
         re->headerdirty=0;
674 672
         re->ui->rendererdirty=1;
675 673
         return(0);
Browse code

Improve implementation so it can edit lines longer than a chunk

Dario Rodriguez authored on 24/09/2020 21:40:49
Showing 1 changed files
... ...
@@ -21,6 +21,21 @@
21 21
 #define LINEFORCESCROLL 1
22 22
 #define COLFORCESCROLL 5
23 23
 
24
+#define COMMANDBUFSIZE 1024
25
+
26
+#define COMMAND_WARNING "(!)"
27
+#define COMMAND_GOTOLINE "Go to line: "
28
+
29
+#define COLOR_STATUSBG "\x00\x00\xff\xff"
30
+#define COLOR_STATUSFG "\xff\xff\x00\xff"
31
+
32
+#define COLOR_QUERYBG "\xc0\xff\x00\xff"
33
+#define COLOR_QUERYFG "\x3f\x00\xff\xff"
34
+
35
+#define COLOR_WARNINGBG "\xff\x00\x00\xff"
36
+#define COLOR_WARNINGFG "\xff\xff\x00\xff"
37
+
38
+
24 39
 typedef struct re_t {
25 40
         redata_t *data;
26 41
         reui_t *ui;
... ...
@@ -31,7 +46,11 @@ typedef struct re_t {
31 46
         int originline,origincol;
32 47
         int curline,curcol;
33 48
         int maxrow,maxcol;
49
+        int headerdirty;
34 50
         int contentsdirty;
51
+        char *command;
52
+        char commandbuf[COMMANDBUFSIZE];
53
+        int ignorenkeys;
35 54
 } re_t;
36 55
 
37 56
 volatile int flag_sigint;
... ...
@@ -47,10 +66,15 @@ re_t *re_init(void);
47 66
 void re_free(re_t *re);
48 67
 
49 68
 int re_setfilename(re_t *re, char *filename);
50
-int re_processkey(re_t *re, SDL_Event *event);
69
+int re_processkey_editing(re_t *re, SDL_Event *event);
70
+int re_processkey_commandwait(re_t *re, SDL_Event *event);
71
+int re_processkey_commanddata(re_t *re, SDL_Event *event);
72
+int re_processcommand(re_t *re);
51 73
 int re_moveupdown(re_t *re, int totalinc);
52 74
 int re_moveleftright(re_t *re, int totalinc);
53
-int re_drawheader(re_t *re);
75
+int re_rtrim(re_t *re, long curpos, int *trimmed);
76
+int re_drawheader_editing(re_t *re);
77
+int re_drawheader_command(re_t *re);
54 78
 int re_drawcontents(re_t *re);
55 79
 
56 80
 
... ...
@@ -106,10 +130,25 @@ main(int argc, char *argv[])
106 130
         re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
107 131
         re->maxrow=re->h/re->ui->fontheight-1;
108 132
         re->maxcol=re->w/re->ui->fontwidth-1;
109
-        re_drawheader(re);
110
-        re_drawcontents(re);
133
+        re->headerdirty=1;
134
+        re->contentsdirty=1;
111 135
         flag_had_events=0;
136
+        SDL_StartTextInput();
112 137
         while(do_exit==0 && flag_sigint==0) {
138
+                if(re->headerdirty) {
139
+                        if(re->command==NULL) {
140
+fprintf(stderr,"REDRAW Header (editing)\n");
141
+                                re_drawheader_editing(re);
142
+                        } else {
143
+fprintf(stderr,"REDRAW Header (command)\n");
144
+                                re_drawheader_command(re);
145
+                                if(strcmp(re->command,COMMAND_WARNING)==0) {
146
+                                        /* the warnings only get shown once, remove it */
147
+                                        re->command=NULL;
148
+                                        re->commandbuf[0]='\0';
149
+                                }
150
+                        }
151
+                }
113 152
                 if(re->contentsdirty)
114 153
                         re_drawcontents(re);
115 154
                 if(re->ui->rendererdirty)
... ...
@@ -124,7 +163,14 @@ main(int argc, char *argv[])
124 163
                                         do_exit=1;
125 164
                                         break;
126 165
                                 case SDL_KEYDOWN:
127
-                                        re_processkey(re,&event);
166
+                                case SDL_TEXTINPUT:
167
+                                case SDL_TEXTEDITING:
168
+                                        if(re->command==NULL || strcmp(re->command,COMMAND_WARNING)==0)
169
+                                                re_processkey_editing(re,&event);
170
+                                        else if(re->command[0]=='\0')
171
+                                                re_processkey_commandwait(re,&event);
172
+                                        else
173
+                                                re_processkey_commanddata(re,&event);
128 174
                                         break;
129 175
                                 case SDL_WINDOWEVENT:
130 176
                                         if(event.window.event==SDL_WINDOWEVENT_SHOWN
... ...
@@ -137,6 +183,7 @@ main(int argc, char *argv[])
137 183
                         }
138 184
                 }
139 185
         }
186
+        SDL_StopTextInput();
140 187
         sselect_free(ssel),ssel=NULL;
141 188
         re_free(re),re=NULL;
142 189
         return(0);
... ...
@@ -209,14 +256,79 @@ re_setfilename(re_t *re, char *filename)
209 256
 }
210 257
 
211 258
 int
212
-re_processkey(re_t *re, SDL_Event *event)
259
+re_processkey_editing(re_t *re, SDL_Event *event)
213 260
 {
214
-        long newpos;
215
-        char *ptr;
216
-        int len;
217
-        int has_nl;
218
-        if(re==NULL || event==NULL || event->type!=SDL_KEYDOWN)
261
+        SDL_Event returnevent;
262
+        if(re==NULL || event==NULL)
219 263
                 return(-1); /* sanity check failed */
264
+        /* convert RETURN KEYDOWN to TEXTINPUT */
265
+        if(event->type==SDL_KEYDOWN && event->key.keysym.sym==SDLK_RETURN) {
266
+                memset(&returnevent,0,sizeof(SDL_Event));
267
+                event=&returnevent;
268
+                event->type=SDL_TEXTINPUT;
269
+                strncpy(event->text.text,"\n",sizeof(event->text.text));
270
+                event->text.text[sizeof(event->text.text)-1]='\0';
271
+        }
272
+        /* special case: text editing event */
273
+        if(event->type==SDL_TEXTINPUT) {
274
+                int len;
275
+                long realend;
276
+                int at_end;
277
+                if(re->ignorenkeys>0) {
278
+                        re->ignorenkeys--;
279
+                        return(0); /* this is an already processed key, ignore it */
280
+                }
281
+#if 1
282
+fprintf(stderr,"SDL_TEXTINPUT:\"%s\"\n",event->text.text);
283
+#endif
284
+                if(redata_line_realend(re->data,re->cursorpos,&realend)==-1)
285
+                        return(-1); /* couldn't get current line info */
286
+                at_end=(re->cursorpos==realend)?1:0;
287
+                if(event->text.text[0]==' ' && event->text.text[1]=='\0' && at_end) {
288
+                        /* instead of adding a space at the end of the line, we move the cursor to the right */
289
+                        re_moveleftright(re,1);
290
+                        return(0); /* no need to add spaces at the end of the line */
291
+                }
292
+                redata_undo_groupinit(re->data,NULL);
293
+                if(event!=&returnevent && at_end) {
294
+                        int col;
295
+                        if(redata_pos2linecol(re->data,re->cursorpos,NULL,&col)==-1)
296
+                                return(-1); /* couldn't get line info */
297
+                        if(redata_op_addn(re->data,re->cursorpos,' ',re->curcol-col,NULL)!=0)
298
+                                return(-1); /* couldn't add spaces up to current displayed pos */
299
+                        /* increment cursorpos; spaces are 1 byte, so the number of columns advanced is the number of bytes advanced */
300
+                        re->cursorpos+=re->curcol-col;
301
+                }
302
+                len=strlen(event->text.text);
303
+                if(redata_op_add(re->data,re->cursorpos,event->text.text,len,NULL)!=0)
304
+                        return(-1); /* couldn't add requested text */
305
+                re->cursorpos+=len;
306
+                if(event==&returnevent) {
307
+                        int trimmed;
308
+                        if(re_rtrim(re,re->cursorpos-len,&trimmed))
309
+                                re->cursorpos-=trimmed;
310
+                        re->curline++;
311
+                        re->curcol=0;
312
+                } else {
313
+                        re->curcol+=redata_generic_utf8len(event->text.text,len);
314
+                }
315
+                redata_undo_groupcommit(re->data,NULL);
316
+                re->headerdirty=1;
317
+                re->contentsdirty=1;
318
+        }
319
+#if 0
320
+        else if(event->type==SDL_TEXTEDITING) {
321
+                /* NOTE: on window enter events we cam also receive this event (!) */
322
+#warning TODO: CJK support
323
+fprintf(stderr,"SDL_TEXTEDITING: composition:\"%s\" start:%i len:%i\n",event->edit.text,event->edit.start,event->edit.length);
324
+        }
325
+#endif
326
+        /* default case: keydown event */
327
+        if(event->type!=SDL_KEYDOWN)
328
+                return(0); /* Ignore other possible events */
329
+#if 1
330
+fprintf(stderr,"SDL_KEYDOWN: sym:%i\n",event->key.keysym.sym);
331
+#endif
220 332
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
221 333
                 re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1);
222 334
         } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
... ...
@@ -224,11 +336,14 @@ re_processkey(re_t *re, SDL_Event *event)
224 336
         } else if(event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP) {
225 337
                 re_moveupdown(re,(event->key.keysym.sym==SDLK_PAGEUP)?-(re->maxrow):re->maxrow);
226 338
         } else if(event->key.keysym.sym==SDLK_HOME || event->key.keysym.sym==SDLK_END) {
227
-                if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
228
-                        return(-1); /* couldn't get current line data */
229
-                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
230
-                re->cursorpos=(event->key.keysym.sym==SDLK_HOME)?newpos:newpos+len-has_nl;
231
-                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
339
+                long newpos;
340
+                if((event->key.keysym.sym==SDLK_HOME && redata_line_realstart(re->data,re->cursorpos,&newpos)==-1)
341
+                  || (event->key.keysym.sym==SDLK_END && redata_line_realend(re->data,re->cursorpos,&newpos)==-1)) {
342
+                        return(-1); /* couldn't get destination pos data */
343
+                }
344
+                re->cursorpos=newpos;
345
+                if(redata_pos2linecol(re->data,re->cursorpos,NULL,&(re->curcol))==-1)
346
+                        return(-1); /* couldn't get col of current pos */;
232 347
                 if(re->curcol<re->origincol) {
233 348
                         re->origincol=re->curcol;
234 349
                         re->origincol=(re->origincol<0)?0:re->origincol;
... ...
@@ -237,42 +352,184 @@ re_processkey(re_t *re, SDL_Event *event)
237 352
                         re->origincol=re->curcol+COLFORCESCROLL-re->maxcol;
238 353
                         re->origincol=(re->origincol<0)?0:re->origincol;
239 354
                 }
355
+                re->headerdirty=1;
356
+                re->contentsdirty=1;
357
+        } else if(event->key.keysym.sym==SDLK_BACKSPACE && re->cursorpos>0) {
358
+                int line,col;
359
+                long startpos,newpos,realstart,start;
360
+                char *ptr;
361
+                int len;
362
+                int trimmed;
363
+                int doneinc;
364
+                if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
365
+                        return(-1); /* couldn't get current line data */
366
+                if(col<re->curcol) {
367
+                        re_moveleftright(re,-1);
368
+                        return(0); /* were hovering to the right of last char, only had to move left */
369
+                }
370
+                redata_undo_groupinit(re->data,NULL);
371
+                /* delete the last character */
372
+                if(col>0) {
373
+                        if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
374
+                                return(-1); /* couldn't get line info */
375
+                        /* get the start of the part to delete */
376
+                        doneinc=0;
377
+                        for(ptr=NULL,len=0,start=0,newpos=re->cursorpos;doneinc!=1;) {
378
+                                if((newpos-1)<realstart)
379
+                                        break;
380
+                                newpos--;
381
+                                if(ptr==NULL || (start+len)<=newpos || newpos<start) {
382
+                                        if(redata_line_rawinfo(re->data,newpos,&start,&ptr,&len,NULL)==-1)
383
+                                                return(-1); /* couldn't get line data */
384
+                                }
385
+                                if(redata_generic_utf8isstartbyte(ptr[newpos-start]))
386
+                                        doneinc++;
387
+                        }
388
+                        /* delete */
389
+                        redata_op_del(re->data,newpos,re->cursorpos-newpos,NULL);
390
+                        re->cursorpos=newpos;
391
+                } else {
392
+                        long delpos;
393
+                        /* to make the code trivial, we're being lazy on '\n' deletion: we call ...rawinfo() for each byte in the multibyte utf-8 sequence */
394
+                        for(delpos=re->cursorpos-1
395
+                          ;delpos>0
396
+                          && redata_line_rawinfo(re->data,delpos,&startpos,&ptr,&len,NULL)==0;) {
397
+                                if(redata_generic_utf8isstartbyte(ptr[delpos-startpos]))
398
+                                        break;
399
+                        }
400
+                        redata_op_del(re->data,delpos,re->cursorpos-delpos,NULL);
401
+                        re->cursorpos=delpos;
402
+                }
403
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
404
+                /* if cursor at end of line and there are trailing spaces at the end, delete them too */
405
+                if(re_rtrim(re,re->cursorpos,&trimmed))
406
+                        re->cursorpos-=trimmed;
407
+                /* end of deletion */
408
+                redata_undo_groupcommit(re->data,NULL);
409
+                re->headerdirty=1;
240 410
                 re->contentsdirty=1;
241
-                re_drawheader(re);
242
-        } else if(event->key.keysym.sym==SDLK_a) {
243
-                ;
411
+        } else if(event->key.keysym.sym==SDLK_q && (SDL_GetModState()&KMOD_CTRL)!=0) {
412
+fprintf(stderr,"re_processkey(): received Control+q\n");
413
+                re->command="";
414
+                re->headerdirty=1;
244 415
         }
245
-        return(-1);
416
+        return(0);
417
+}
418
+
419
+int
420
+re_processkey_commandwait(re_t *re, SDL_Event *event)
421
+{
422
+        if(re==NULL || event==NULL)
423
+                return(-1); /* sanity check failed */
424
+        /* default case: keydown event */
425
+        if(event->type!=SDL_KEYDOWN)
426
+                return(0); /* Ignore other possible events */
427
+        if(event->key.keysym.sym==SDLK_l) {
428
+                re->command=COMMAND_GOTOLINE;
429
+                re->commandbuf[0]='\0';
430
+                re->headerdirty=1;
431
+        } else {
432
+                re->command=NULL;
433
+                re->headerdirty=1;
434
+        }
435
+        if(!(SDL_GetModState()&KMOD_CTRL))
436
+                re->ignorenkeys=1; /* control was not pressed, we will receive again this key as SDL_TEXTINPUT */
437
+        return(0);
438
+}
439
+
440
+int
441
+re_processkey_commanddata(re_t *re, SDL_Event *event)
442
+{
443
+        if(re==NULL || event==NULL)
444
+                return(-1); /* sanity check failed */
445
+        /* special case: text editing event */
446
+        if(event->type==SDL_TEXTINPUT) {
447
+                int len;
448
+                if(re->ignorenkeys>0) {
449
+                        re->ignorenkeys--;
450
+                        return(0); /* this is an already processed key, ignore it */
451
+                }
452
+                len=strlen(event->text.text);
453
+                if((strlen(re->commandbuf)+len+1)>=sizeof(re->commandbuf))
454
+                        return(-1); /* No space for text */
455
+                memcpy(re->commandbuf+strlen(re->commandbuf),event->text.text,len+1);
456
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
457
+                re->headerdirty=1;
458
+        }
459
+        /* default case: keydown event */
460
+        if(event->type!=SDL_KEYDOWN)
461
+                return(0); /* Ignore other possible events */
462
+        if(event->key.keysym.sym==SDLK_ESCAPE) {
463
+                re->command=NULL;
464
+                re->commandbuf[0]='\0';
465
+                re->headerdirty=1;
466
+        } else if(event->key.keysym.sym==SDLK_BACKSPACE && re->commandbuf[0]!='\0') {
467
+                int nchar;
468
+                char *ptr;
469
+                if((nchar=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf)))<=0)
470
+                        return(-1); /* error parsing commandbuf */
471
+                if((ptr=redata_generic_utf8col(re->commandbuf,strlen(re->commandbuf),nchar-1))==NULL)
472
+                        return(-1); /* error positioning in commandbuf */
473
+                *ptr='\0';
474
+                re->headerdirty=1;
475
+        } else if(event->key.keysym.sym==SDLK_RETURN) {
476
+                re_processcommand(re);
477
+        }
478
+        return(0);
479
+}
480
+
481
+int
482
+re_processcommand(re_t *re)
483
+{
484
+        if(re==NULL || re->command==NULL)
485
+                return(-1);
486
+        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
487
+        if(strcmp(re->command,COMMAND_GOTOLINE)==0) {
488
+                int line;
489
+                long pos;
490
+                line=atoi(re->commandbuf);
491
+                if(redata_linecol2pos(re->data,line,0,&pos,NULL)==-1) {
492
+                        re->command=COMMAND_WARNING;
493
+                        snprintf(re->commandbuf,sizeof(re->commandbuf),"Unknown line");
494
+                        re->commandbuf[sizeof(re->commandbuf)-1]='\0';
495
+                        re->headerdirty=1;
496
+                        return(-1);
497
+                }
498
+                re->cursorpos=pos;
499
+                re->curcol=0;
500
+                re->curline=line;
501
+                re->origincol=0;
502
+                if((re->originline+re->maxrow)<line)
503
+                        re->originline=line-re->maxrow;
504
+                if(line<re->originline)
505
+                        re->originline=line;
506
+                re->headerdirty=1;
507
+                re->contentsdirty=1;
508
+        }
509
+        re->command=NULL;
510
+        re->commandbuf[0]='\0';
511
+        return(0);
246 512
 }
247 513
 
248 514
 int
249 515
 re_moveupdown(re_t *re, int totalinc)
250 516
 {
251 517
         long newpos,newpos2;
252
-        char *ptr;
253
-        int len;
254
-        int has_nl;
255
-        int maxcol;
256 518
         int inc,doneinc;
257
-
519
+        long realstart;
258 520
         if(re==NULL)
259 521
                 return(-1); /* sanity check failed */
260 522
         if(totalinc==0)
261 523
                 return(0); /* nothing to do */
262 524
         inc=(totalinc<0)?-1:1;
525
+        newpos=re->cursorpos; /* get rid of compiler warning (will be overwitten in the loop as totalinc never is 0) */
263 526
         for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
264
-                if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
265
-                        return(-1); /* couldn't get current line data */
266
-                if(inc==-1 && newpos==0)
267
-                        return(0); /* going up but already at top; nothing to do */
268
-                if(redata_line_info(re->data,(inc==1)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
269
-                        return(-1); /* couldn't get next line data */
270
-                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
271
-                maxcol=redata_generic_utf8len(ptr,len)-has_nl;
272
-                if(maxcol<re->curcol)
273
-                        re->cursorpos=newpos2+len-has_nl;
274
-                else
275
-                        re->cursorpos=newpos2+(redata_generic_utf8col(ptr,len,re->curcol)-ptr);
527
+fprintf(stderr,"MOVING from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
528
+                if((inc==-1 && redata_line_prevrealstart(re->data,re->cursorpos,&realstart)==-1)
529
+                   || (inc==1 && redata_line_nextrealstart(re->data,re->cursorpos,&realstart)==-1)) {
530
+                        break; /* couldn't get current line data, we are at start/end */
531
+                }
532
+                re->cursorpos=realstart;
276 533
                 re->curline+=inc;
277 534
                 if(re->curline<(re->originline+LINEFORCESCROLL)) {
278 535
                         re->originline-=LINEFORCESCROLL;
... ...
@@ -280,110 +537,230 @@ re_moveupdown(re_t *re, int totalinc)
280 537
                 }
281 538
                 if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL))
282 539
                         re->originline+=LINEFORCESCROLL;
283
-                re->contentsdirty=1;
540
+fprintf(stderr,"MOVING   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
541
+        }
542
+        if(redata_line_inccol(re->data,re->cursorpos,re->curcol,&newpos2,NULL)==-1) {
543
+                /* error advancing cursor, "emergency" repositioning */
544
+fprintf(stderr,"COLUMN ERROR\n");
545
+                re->curcol=0;
546
+                newpos2=newpos;
284 547
         }
285
-        re_drawheader(re);
548
+fprintf(stderr,"COLUMN from cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
549
+        re->cursorpos=newpos2;
550
+fprintf(stderr,"COLUMN   to cursorpos:%li line:%i col:%i\n",re->cursorpos,re->curline,re->curcol);
551
+        re->contentsdirty=1;
552
+        re->headerdirty=1;
286 553
         return(0);
287 554
 }
288 555
 
289 556
 int
290 557
 re_moveleftright(re_t *re, int totalinc)
291 558
 {
292
-        long newpos;
293
-        char *ptr,*ptr2;
294
-        int len;
295
-        int has_nl;
296
-        int maxcol;
559
+        long newpos,realstart;
297 560
         int inc,doneinc;
298
-
561
+        char *ptr;
562
+        int len;
563
+        long start;
564
+        int tmpcol,oldcol;
299 565
         if(re==NULL)
300 566
                 return(-1); /* sanity check failed */
301 567
         if(totalinc==0)
302 568
                 return(0); /* nothing to do */
303
-        inc=(totalinc<0)?-1:1;
304
-        for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
305
-                if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
306
-                        return(-1); /* couldn't get current line data */
307
-                if(inc==-1 && re->cursorpos==0)
308
-                        return(-1); /* going left but already at leftmost char */
309
-                maxcol=redata_generic_utf8len(ptr,len);
310
-                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
311
-                if(re->curcol<=maxcol)
312
-                        ptr2=redata_generic_utf8col(ptr,len,re->curcol+inc);
313
-                else
314
-                        ptr2=NULL;
315
-                if(ptr2!=NULL)
316
-                        re->cursorpos=newpos+(ptr2-ptr);
317
-                else
318
-                        re->cursorpos=newpos+(len-has_nl); /* we're past the last col, set cursor to last pos in line */
319
-                if((re->curcol+inc)>=0)
320
-                        re->curcol+=inc;
321
-                if(re->curcol<(re->origincol+COLFORCESCROLL)) {
322
-                        re->origincol-=COLFORCESCROLL;
323
-                        re->origincol=(re->origincol<0)?0:re->origincol;
569
+        oldcol=re->curcol;
570
+        if(totalinc<0 && (re->curcol+totalinc)<=0) {
571
+                /* we'll land on the start of the line -- do it trivially */
572
+                if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
573
+                        return(-1); /* couldn't get current pos */
574
+                re->curcol=0;
575
+                re->cursorpos=realstart;
576
+        } else {
577
+                /* move a char at a time */
578
+                if(redata_line_realstart(re->data,re->cursorpos,&realstart)==-1)
579
+                        return(-1); /* couldn't get current pos */
580
+                inc=(totalinc<0)?-1:1;
581
+                doneinc=0;
582
+                if(redata_pos2linecol(re->data,re->cursorpos,NULL,&tmpcol)==-1)
583
+                        return(-1); /* couldn't get current pos */
584
+                /* special case: we're just over the '\n' going right, we have to move 1 to enable the generic case to work */
585
+                if(tmpcol==re->curcol && inc>0) {
586
+                        if(redata_line_rawinfo(re->data,re->cursorpos,&start,&ptr,&len,NULL)==-1)
587
+                                return(-1); /* couldn't get line data */
588
+                        if(ptr[re->cursorpos-start]=='\n') {
589
+                                tmpcol++;
590
+                                totalinc--;
591
+                                re->curcol++;
592
+                        }
324 593
                 }
325
-                if(re->curcol>(re->origincol+re->maxcol-COLFORCESCROLL))
326
-                        re->origincol+=COLFORCESCROLL;
594
+                /* generic case: cursor after the \n ("floating") */
595
+                if(tmpcol<re->curcol) {
596
+                        int avail;
597
+                        if(inc>0) {
598
+                                doneinc=totalinc;
599
+                        } else {
600
+                                avail=re->curcol-tmpcol;
601
+                                doneinc=(avail>=totalinc)?totalinc:avail;
602
+                        }
603
+                }
604
+                /* generic case: move one char at a time */
605
+                for(ptr=NULL,len=0,start=0,newpos=re->cursorpos;doneinc!=totalinc;) {
606
+                        if((newpos+inc)<realstart)
607
+                                break;
608
+                        newpos+=inc;
609
+                        if(ptr==NULL || (start+len)<=newpos || newpos<start) {
610
+                                if(redata_line_rawinfo(re->data,newpos,&start,&ptr,&len,NULL)==-1)
611
+                                        return(-1); /* couldn't get line data */
612
+                        }
613
+                        if(redata_generic_utf8isstartbyte(ptr[newpos-start]))
614
+                                doneinc+=inc;
615
+                        if(ptr[newpos-start]=='\n')
616
+                                break;
617
+                }
618
+                re->cursorpos=newpos;
619
+                re->curcol+=doneinc;
620
+                if(inc>0 && doneinc<totalinc && ptr!=NULL && ptr[newpos-start]=='\n')
621
+                        re->curcol+=(totalinc-doneinc);
622
+        }
623
+        if(re->curcol!=oldcol) {
327 624
                 re->contentsdirty=1;
625
+                re->headerdirty=1;
626
+                if(re->curcol<(re->origincol+COLFORCESCROLL) && re->origincol>0) {
627
+                        re->origincol=(re->curcol-COLFORCESCROLL)/COLFORCESCROLL;
628
+                        re->origincol=re->origincol*COLFORCESCROLL;
629
+                        re->origincol=(re->origincol<0)?0:re->origincol;
630
+                }
631
+                if(re->curcol>(re->origincol+re->maxrow-COLFORCESCROLL)) {
632
+                        re->origincol=re->curcol+COLFORCESCROLL-re->maxrow-(re->curcol%COLFORCESCROLL);
633
+                        re->origincol=(re->origincol<0)?0:re->origincol;
634
+                }
635
+        }
636
+        return(0);
637
+}
638
+
639
+int
640
+re_rtrim(re_t *re, long curpos, int *trimmed)
641
+{
642
+        long startpos;
643
+        char *start;
644
+        int len;
645
+        int n;
646
+        if(re==NULL || curpos<0 || curpos>redata_getused(re->data))
647
+                return(-1);
648
+        if(trimmed!=NULL)
649
+                *trimmed=0;
650
+        if(redata_line_rawinfo(re->data,curpos,&startpos,&start,&len,NULL)==0 &&
651
+           len>1 && start[len-1]=='\n' && start[len-2]==' ' && curpos==(startpos+len-1)) {
652
+                for(n=1;(n+1)<(len-1) && start[len-1-n-1]==' ';n++)
653
+                        ;
654
+fprintf(stderr,"Trying to DELETE SPACES del %i bytes\n",n);
655
+                redata_op_del(re->data,curpos-n,n,NULL);
656
+                re->cursorpos-=n;
657
+                if(trimmed!=NULL)
658
+                        *trimmed=n;
328 659
         }
329
-        re_drawheader(re);
330 660
         return(0);
331 661
 }
332 662
 
333 663
 int
334
-re_drawheader(re_t *re)
664
+re_drawheader_editing(re_t *re)
335 665
 {
336 666
         int line,col;
337 667
         if(re==NULL)
338 668
                 return(-1);
339 669
         if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
340 670
                 line=col=-1;
341
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,"\x00\x00\xff\xff");
342
-        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline,line,re->curcol,col,re->cursorpos);
671
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG);
672
+        reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline,line,re->curcol,col,re->cursorpos);
673
+        re->headerdirty=0;
674
+        re->ui->rendererdirty=1;
675
+        return(0);
676
+}
677
+
678
+int
679
+re_drawheader_command(re_t *re)
680
+{
681
+        if(re==NULL)
682
+                return(-1);
683
+        if(re->command==NULL)
684
+                return(-1);
685
+        if(re->command[0]=='\0') {
686
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
687
+                reui_printf(re->ui,0,0,COLOR_QUERYFG,"Command:");
688
+        } else if(strcmp(re->command,COMMAND_WARNING)==0) {
689
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG);
690
+                reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf);
691
+        } else {
692
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
693
+                re->commandbuf[sizeof(re->commandbuf)-1]='\0';
694
+                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s %s",re->command,re->commandbuf);
695
+        }
696
+        re->headerdirty=0;
697
+        re->ui->rendererdirty=1;
343 698
         return(0);
344 699
 }
345 700
 
701
+
346 702
 int
347 703
 re_drawcontents(re_t *re)
348 704
 {
349 705
         long pos,newpos;
350
-        char *ptr,*visibleptr;
706
+        char *ptr;
351 707
         int len;
352 708
         int y,row;
353 709
         char *curptr;
354 710
         int curptrlen;
355 711
         int has_nl;
712
+        int is_continuation;
713
+        int tmpcol,availcol;
714
+        int in_error;
715
+        long realstart,realend;
716
+        int drawn_cursor;
356 717
         if(re==NULL)
357 718
                 return(-1);
358 719
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
359 720
         row=re->curline-re->originline;
360 721
         pos=re->cursorpos;
361
-        while(row>0) {
362
-                if(redata_line_info(re->data,pos,&newpos,NULL,NULL)==-1)
722
+        while(row>0 && pos>0) {
723
+                if(redata_line_rawinfo(re->data,pos,&newpos,NULL,NULL,&is_continuation)==-1)
363 724
                         return(-1);
364 725
                 pos=(newpos>0)?newpos-1:0;
365
-                row--;
726
+                if(!is_continuation)
727
+                        row--;
366 728
         }
367 729
         /* highlight current line */
368 730
         reui_fill(re->ui,re->x,re->y+(re->curline-re->originline)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
369 731
         /* draw the lines */
732
+        drawn_cursor=0;
370 733
         for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
371
-                if(redata_line_info(re->data,pos,&newpos,&ptr,&len)==-1)
372
-                        break; /* couldn't get line start pos */
373
-                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
374
-                visibleptr=redata_generic_utf8col((char *)ptr,len-has_nl,re->origincol);
375
-                if(visibleptr!=NULL)
376
-                        reui_write(re->ui,re->x,y,"\x00\x00\x00\xff",visibleptr,len-has_nl-(visibleptr-ptr));
377
-                if(row==(re->curline-re->originline)) {
378
-#warning DEBUG write of current char
379
-                        reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
734
+                if(redata_line_realstart(re->data,pos,&realstart)==-1 || redata_line_realend(re->data,pos,&realend)==-1) {
735
+                        break; /* couldn't get real start/end */
736
+                }
737
+                in_error=0;
738
+                for(tmpcol=0,pos=realstart,availcol=0;tmpcol<(re->origincol+re->maxcol) && pos<=realend;pos=newpos+len,tmpcol+=availcol) {
739
+                        if(redata_line_rawinfo(re->data,pos,&newpos,&ptr,&len,&is_continuation)==-1) {
740
+                                in_error=1;
741
+                                break; /* couldn't get this line part info */
742
+                        }
743
+                        has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
744
+                        availcol=redata_generic_utf8len(ptr,len-has_nl);
380 745
 #warning TODO: consider tabs
381
-                        curptr=redata_generic_utf8col(ptr,len-has_nl,re->curcol);
382
-                        curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
383
-                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));
746
+                        reui_write(re->ui,re->x+(tmpcol-re->origincol)*re->ui->fontwidth,y,"\x00\x00\x00\xff",ptr,len-has_nl);
747
+                        if(row==(re->curline-re->originline)) {
748
+                                if(re->curcol>=tmpcol && re->curcol<(tmpcol+availcol)) {
749
+                                        reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
750
+                                        drawn_cursor=1;
751
+                                        curptr=redata_generic_utf8col(ptr,len-has_nl,re->curcol-tmpcol);
752
+                                        curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
753
+                                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));
754
+                                }
384 755
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
756
+                        }
385 757
                 }
386
-                pos=newpos+len;
758
+                if(row==(re->curline-re->originline) && !drawn_cursor)
759
+                        reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
760
+                if(in_error)
761
+                        break;
762
+                pos=realend+1;
763
+/*LONG LINE LEFT FOR DEBUGGING PURPOSES: reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));*/
387 764
         }
388 765
         re->contentsdirty=0;
389 766
         re->ui->rendererdirty=1;
Browse code

Process navigation keys: PageUp/PageDown/Home/End.

Dario Rodriguez authored on 07/09/2020 22:13:24
Showing 1 changed files
... ...
@@ -48,6 +48,8 @@ void re_free(re_t *re);
48 48
 
49 49
 int re_setfilename(re_t *re, char *filename);
50 50
 int re_processkey(re_t *re, SDL_Event *event);
51
+int re_moveupdown(re_t *re, int totalinc);
52
+int re_moveleftright(re_t *re, int totalinc);
51 53
 int re_drawheader(re_t *re);
52 54
 int re_drawcontents(re_t *re);
53 55
 
... ...
@@ -209,27 +211,61 @@ re_setfilename(re_t *re, char *filename)
209 211
 int
210 212
 re_processkey(re_t *re, SDL_Event *event)
211 213
 {
212
-        long newpos,newpos2;
213
-        char *ptr,*ptr2;
214
+        long newpos;
215
+        char *ptr;
214 216
         int len;
215 217
         int has_nl;
216
-        int maxcol;
217
-        int inc;
218 218
         if(re==NULL || event==NULL || event->type!=SDL_KEYDOWN)
219 219
                 return(-1); /* sanity check failed */
220 220
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
221
+                re_moveupdown(re,(event->key.keysym.sym==SDLK_UP)?-1:1);
222
+        } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
223
+                re_moveleftright(re,(event->key.keysym.sym==SDLK_LEFT)?-1:1);
224
+        } else if(event->key.keysym.sym==SDLK_PAGEDOWN || event->key.keysym.sym==SDLK_PAGEUP) {
225
+                re_moveupdown(re,(event->key.keysym.sym==SDLK_PAGEUP)?-(re->maxrow):re->maxrow);
226
+        } else if(event->key.keysym.sym==SDLK_HOME || event->key.keysym.sym==SDLK_END) {
221 227
                 if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
222 228
                         return(-1); /* couldn't get current line data */
223
-                if(event->key.keysym.sym==SDLK_UP && newpos==0)
224
-                        return(-1); /* going up but already at top */
225
-#if 0
226
-                maxcol=redata_generic_utf8len(ptr,len);
227
-                if(maxcol<re->curcol)
228
-                        re->cursorpos=newpos+len;
229
-                else
230
-                        re->cursorpos=newpos+(redata_generic_utf8col(ptr,len,re->curcol)-ptr);
231
-#endif
232
-                if(redata_line_info(re->data,(event->key.keysym.sym==SDLK_DOWN)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
229
+                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
230
+                re->cursorpos=(event->key.keysym.sym==SDLK_HOME)?newpos:newpos+len-has_nl;
231
+                redata_pos2linecol(re->data,re->cursorpos,&(re->curline),&(re->curcol));
232
+                if(re->curcol<re->origincol) {
233
+                        re->origincol=re->curcol;
234
+                        re->origincol=(re->origincol<0)?0:re->origincol;
235
+                }
236
+                if(re->curcol>(re->origincol+re->maxcol-COLFORCESCROLL)) {
237
+                        re->origincol=re->curcol+COLFORCESCROLL-re->maxcol;
238
+                        re->origincol=(re->origincol<0)?0:re->origincol;
239
+                }
240
+                re->contentsdirty=1;
241
+                re_drawheader(re);
242
+        } else if(event->key.keysym.sym==SDLK_a) {
243
+                ;
244
+        }
245
+        return(-1);
246
+}
247
+
248
+int
249
+re_moveupdown(re_t *re, int totalinc)
250
+{
251
+        long newpos,newpos2;
252
+        char *ptr;
253
+        int len;
254
+        int has_nl;
255
+        int maxcol;
256
+        int inc,doneinc;
257
+
258
+        if(re==NULL)
259
+                return(-1); /* sanity check failed */
260
+        if(totalinc==0)
261
+                return(0); /* nothing to do */
262
+        inc=(totalinc<0)?-1:1;
263
+        for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
264
+                if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
265
+                        return(-1); /* couldn't get current line data */
266
+                if(inc==-1 && newpos==0)
267
+                        return(0); /* going up but already at top; nothing to do */
268
+                if(redata_line_info(re->data,(inc==1)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
233 269
                         return(-1); /* couldn't get next line data */
234 270
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
235 271
                 maxcol=redata_generic_utf8len(ptr,len)-has_nl;
... ...
@@ -237,22 +273,40 @@ re_processkey(re_t *re, SDL_Event *event)
237 273
                         re->cursorpos=newpos2+len-has_nl;
238 274
                 else
239 275
                         re->cursorpos=newpos2+(redata_generic_utf8col(ptr,len,re->curcol)-ptr);
240
-                re->curline+=(event->key.keysym.sym==SDLK_DOWN)?1:-1;
276
+                re->curline+=inc;
241 277
                 if(re->curline<(re->originline+LINEFORCESCROLL)) {
242 278
                         re->originline-=LINEFORCESCROLL;
243 279
                         re->originline=(re->originline<0)?0:re->originline;
244 280
                 }
245 281
                 if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL))
246 282
                         re->originline+=LINEFORCESCROLL;
247
-                re_drawheader(re);
248 283
                 re->contentsdirty=1;
249
-        } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
284
+        }
285
+        re_drawheader(re);
286
+        return(0);
287
+}
288
+
289
+int
290
+re_moveleftright(re_t *re, int totalinc)
291
+{
292
+        long newpos;
293
+        char *ptr,*ptr2;
294
+        int len;
295
+        int has_nl;
296
+        int maxcol;
297
+        int inc,doneinc;
298
+
299
+        if(re==NULL)
300
+                return(-1); /* sanity check failed */
301
+        if(totalinc==0)
302
+                return(0); /* nothing to do */
303
+        inc=(totalinc<0)?-1:1;
304
+        for(doneinc=0;doneinc!=totalinc;doneinc+=inc) {
250 305
                 if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
251 306
                         return(-1); /* couldn't get current line data */
252
-                if(event->key.keysym.sym==SDLK_LEFT && re->cursorpos==0)
307
+                if(inc==-1 && re->cursorpos==0)
253 308
                         return(-1); /* going left but already at leftmost char */
254 309
                 maxcol=redata_generic_utf8len(ptr,len);
255
-                inc=(event->key.keysym.sym==SDLK_LEFT)?-1:1;
256 310
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
257 311
                 if(re->curcol<=maxcol)
258 312
                         ptr2=redata_generic_utf8col(ptr,len,re->curcol+inc);
... ...
@@ -270,15 +324,12 @@ re_processkey(re_t *re, SDL_Event *event)
270 324
                 }
271 325
                 if(re->curcol>(re->origincol+re->maxcol-COLFORCESCROLL))
272 326
                         re->origincol+=COLFORCESCROLL;
273
-                re_drawheader(re);
274 327
                 re->contentsdirty=1;
275
-        } else if(event->key.keysym.sym==SDLK_a) {
276
-                ;
277 328
         }
278
-        return(-1);
329
+        re_drawheader(re);
330
+        return(0);
279 331
 }
280 332
 
281
-
282 333
 int
283 334
 re_drawheader(re_t *re)
284 335
 {
Browse code

Implement side scroll. Fix vertical scroll. Set window size to something more workable than fullscreen.

Dario Rodriguez authored on 06/09/2020 22:21:40
Showing 1 changed files
... ...
@@ -18,6 +18,9 @@
18 18
 #include "re_ui.h"
19 19
 #include "ext/socklib.h"
20 20
 
21
+#define LINEFORCESCROLL 1
22
+#define COLFORCESCROLL 5
23
+
21 24
 typedef struct re_t {
22 25
         redata_t *data;
23 26
         reui_t *ui;
... ...
@@ -25,7 +28,8 @@ typedef struct re_t {
25 28
         char filename[PATH_MAX];
26 29
         int x, y, w, h; // contents rect
27 30
         long cursorpos;
28
-        int lastcol,lastrow;
31
+        int originline,origincol;
32
+        int curline,curcol;
29 33
         int maxrow,maxcol;
30 34
         int contentsdirty;
31 35
 } re_t;
... ...
@@ -209,8 +213,7 @@ re_processkey(re_t *re, SDL_Event *event)
209 213
         char *ptr,*ptr2;
210 214
         int len;
211 215
         int has_nl;
212
-        int oldcol,maxcol;
213
-        int linecols;
216
+        int maxcol;
214 217
         int inc;
215 218
         if(re==NULL || event==NULL || event->type!=SDL_KEYDOWN)
216 219
                 return(-1); /* sanity check failed */
... ...
@@ -219,23 +222,28 @@ re_processkey(re_t *re, SDL_Event *event)
219 222
                         return(-1); /* couldn't get current line data */
220 223
                 if(event->key.keysym.sym==SDLK_UP && newpos==0)
221 224
                         return(-1); /* going up but already at top */
225
+#if 0
222 226
                 maxcol=redata_generic_utf8len(ptr,len);
223
-                if(maxcol<re->lastcol)
227
+                if(maxcol<re->curcol)
224 228
                         re->cursorpos=newpos+len;
225 229
                 else
226
-                        re->cursorpos=newpos+(redata_generic_utf8col(ptr,len,re->lastcol)-ptr);
230
+                        re->cursorpos=newpos+(redata_generic_utf8col(ptr,len,re->curcol)-ptr);
231
+#endif
227 232
                 if(redata_line_info(re->data,(event->key.keysym.sym==SDLK_DOWN)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
228 233
                         return(-1); /* couldn't get next line data */
229 234
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
230 235
                 maxcol=redata_generic_utf8len(ptr,len)-has_nl;
231
-                if(maxcol<re->lastcol)
236
+                if(maxcol<re->curcol)
232 237
                         re->cursorpos=newpos2+len-has_nl;
233 238
                 else
234
-                        re->cursorpos=newpos2+(redata_generic_utf8col(ptr,len,re->lastcol)-ptr);
235
-                if(event->key.keysym.sym==SDLK_DOWN && re->lastrow<re->maxrow)
236
-                        re->lastrow++;
237
-                else if(event->key.keysym.sym==SDLK_UP && re->lastrow>0)
238
-                        re->lastrow--;
239
+                        re->cursorpos=newpos2+(redata_generic_utf8col(ptr,len,re->curcol)-ptr);
240
+                re->curline+=(event->key.keysym.sym==SDLK_DOWN)?1:-1;
241
+                if(re->curline<(re->originline+LINEFORCESCROLL)) {
242
+                        re->originline-=LINEFORCESCROLL;
243
+                        re->originline=(re->originline<0)?0:re->originline;
244
+                }
245
+                if(re->curline>(re->originline+re->maxrow-LINEFORCESCROLL))
246
+                        re->originline+=LINEFORCESCROLL;
239 247
                 re_drawheader(re);
240 248
                 re->contentsdirty=1;
241 249
         } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
... ...
@@ -243,20 +251,25 @@ re_processkey(re_t *re, SDL_Event *event)
243 251
                         return(-1); /* couldn't get current line data */
244 252
                 if(event->key.keysym.sym==SDLK_LEFT && re->cursorpos==0)
245 253
                         return(-1); /* going left but already at leftmost char */
246
-                linecols=redata_generic_utf8len(ptr,len);
247
-                oldcol=redata_generic_utf8len(ptr,re->cursorpos-newpos);
254
+                maxcol=redata_generic_utf8len(ptr,len);
248 255
                 inc=(event->key.keysym.sym==SDLK_LEFT)?-1:1;
249 256
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
250
-                if(re->lastcol<=linecols) {
251
-                        ptr2=redata_generic_utf8col(ptr,len,re->lastcol+inc);
252
-                } else
257
+                if(re->curcol<=maxcol)
258
+                        ptr2=redata_generic_utf8col(ptr,len,re->curcol+inc);
259
+                else
253 260
                         ptr2=NULL;
254 261
                 if(ptr2!=NULL)
255 262
                         re->cursorpos=newpos+(ptr2-ptr);
256 263
                 else
257 264
                         re->cursorpos=newpos+(len-has_nl); /* we're past the last col, set cursor to last pos in line */
258
-                if((re->lastcol+inc)>=0)
259
-                        re->lastcol+=inc;
265
+                if((re->curcol+inc)>=0)
266
+                        re->curcol+=inc;
267
+                if(re->curcol<(re->origincol+COLFORCESCROLL)) {
268
+                        re->origincol-=COLFORCESCROLL;
269
+                        re->origincol=(re->origincol<0)?0:re->origincol;
270
+                }
271
+                if(re->curcol>(re->origincol+re->maxcol-COLFORCESCROLL))
272
+                        re->origincol+=COLFORCESCROLL;
260 273
                 re_drawheader(re);
261 274
                 re->contentsdirty=1;
262 275
         } else if(event->key.keysym.sym==SDLK_a) {
... ...
@@ -275,7 +288,7 @@ re_drawheader(re_t *re)
275 288
         if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
276 289
                 line=col=-1;
277 290
         reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,"\x00\x00\xff\xff");
278
-        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->lastrow,line,re->lastcol,col,re->cursorpos);
291
+        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline,line,re->curcol,col,re->cursorpos);
279 292
         return(0);
280 293
 }
281 294
 
... ...
@@ -283,7 +296,7 @@ int
283 296
 re_drawcontents(re_t *re)
284 297
 {
285 298
         long pos,newpos;
286
-        char *ptr;
299
+        char *ptr,*visibleptr;
287 300
         int len;
288 301
         int y,row;
289 302
         char *curptr;
... ...
@@ -292,7 +305,7 @@ re_drawcontents(re_t *re)
292 305
         if(re==NULL)
293 306
                 return(-1);
294 307
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
295
-        row=re->lastrow;
308
+        row=re->curline-re->originline;
296 309
         pos=re->cursorpos;
297 310
         while(row>0) {
298 311
                 if(redata_line_info(re->data,pos,&newpos,NULL,NULL)==-1)
... ...
@@ -301,20 +314,22 @@ re_drawcontents(re_t *re)
301 314
                 row--;
302 315
         }
303 316
         /* highlight current line */
304
-        reui_fill(re->ui,re->x,re->y+(re->lastrow)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
317
+        reui_fill(re->ui,re->x,re->y+(re->curline-re->originline)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
305 318
         /* draw the lines */
306 319
         for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
307 320
                 if(redata_line_info(re->data,pos,&newpos,&ptr,&len)==-1)
308 321
                         break; /* couldn't get line start pos */
309 322
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
310
-                reui_write(re->ui,re->x,y,"\x00\x00\x00\xff",(char *)ptr,len-has_nl);
311
-                if(row==re->lastrow) {
323
+                visibleptr=redata_generic_utf8col((char *)ptr,len-has_nl,re->origincol);
324
+                if(visibleptr!=NULL)
325
+                        reui_write(re->ui,re->x,y,"\x00\x00\x00\xff",visibleptr,len-has_nl-(visibleptr-ptr));
326
+                if(row==(re->curline-re->originline)) {
312 327
 #warning DEBUG write of current char
313
-                        reui_fill(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
328
+                        reui_fill(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
314 329
 #warning TODO: consider tabs
315
-                        curptr=redata_generic_utf8col(ptr,len-has_nl,re->lastcol);
330
+                        curptr=redata_generic_utf8col(ptr,len-has_nl,re->curcol);
316 331
                         curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
317
-                        reui_write(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));
332
+                        reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));
318 333
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
319 334
                 }
320 335
                 pos=newpos+len;
Browse code

Add pos2linecol and viceversa. Fix Cursor up/down.

Dario Rodriguez authored on 04/09/2020 17:56:20
Showing 1 changed files
... ...
@@ -209,7 +209,7 @@ re_processkey(re_t *re, SDL_Event *event)
209 209
         char *ptr,*ptr2;
210 210
         int len;
211 211
         int has_nl;
212
-        int oldcol;
212
+        int oldcol,maxcol;
213 213
         int linecols;
214 214
         int inc;
215 215
         if(re==NULL || event==NULL || event->type!=SDL_KEYDOWN)
... ...
@@ -219,15 +219,19 @@ re_processkey(re_t *re, SDL_Event *event)
219 219
                         return(-1); /* couldn't get current line data */
220 220
                 if(event->key.keysym.sym==SDLK_UP && newpos==0)
221 221
                         return(-1); /* going up but already at top */
222
-                oldcol=redata_generic_utf8len(ptr,re->cursorpos-newpos);
222
+                maxcol=redata_generic_utf8len(ptr,len);
223
+                if(maxcol<re->lastcol)
224
+                        re->cursorpos=newpos+len;
225
+                else
226
+                        re->cursorpos=newpos+(redata_generic_utf8col(ptr,len,re->lastcol)-ptr);
223 227
                 if(redata_line_info(re->data,(event->key.keysym.sym==SDLK_DOWN)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
224 228
                         return(-1); /* couldn't get next line data */
225 229
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
226
-                ptr2=redata_generic_utf8col(ptr,len-has_nl,oldcol);
227
-                if(ptr2!=NULL)
228
-                        re->cursorpos=newpos2+(ptr2-ptr);
229
-                else
230
+                maxcol=redata_generic_utf8len(ptr,len)-has_nl;
231
+                if(maxcol<re->lastcol)
230 232
                         re->cursorpos=newpos2+len-has_nl;
233
+                else
234
+                        re->cursorpos=newpos2+(redata_generic_utf8col(ptr,len,re->lastcol)-ptr);
231 235
                 if(event->key.keysym.sym==SDLK_DOWN && re->lastrow<re->maxrow)
232 236
                         re->lastrow++;
233 237
                 else if(event->key.keysym.sym==SDLK_UP && re->lastrow>0)
... ...
@@ -265,10 +269,13 @@ re_processkey(re_t *re, SDL_Event *event)
265 269
 int
266 270
 re_drawheader(re_t *re)
267 271
 {
272
+        int line,col;
268 273
         if(re==NULL)
269 274
                 return(-1);
275
+        if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1)
276
+                line=col=-1;
270 277
         reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,"\x00\x00\xff\xff");
271
-        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","Fichero: %s Col:%i Row:%i Pos:%li",re->filename,re->lastcol,re->lastrow,re->cursorpos);
278
+        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->lastrow,line,re->lastcol,col,re->cursorpos);
272 279
         return(0);
273 280
 }
274 281
 
Browse code

Move utf8 helper functions to re_data. Add redata_op_addn().

Dario Rodriguez authored on 02/09/2020 22:07:13
Showing 1 changed files
... ...
@@ -219,11 +219,11 @@ re_processkey(re_t *re, SDL_Event *event)
219 219
                         return(-1); /* couldn't get current line data */
220 220
                 if(event->key.keysym.sym==SDLK_UP && newpos==0)
221 221
                         return(-1); /* going up but already at top */
222
-                oldcol=reui_utf8len(re->ui,ptr,re->cursorpos-newpos);
222
+                oldcol=redata_generic_utf8len(ptr,re->cursorpos-newpos);
223 223
                 if(redata_line_info(re->data,(event->key.keysym.sym==SDLK_DOWN)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
224 224
                         return(-1); /* couldn't get next line data */
225 225
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
226
-                ptr2=reui_utf8col(re->ui,ptr,len-has_nl,oldcol);
226
+                ptr2=redata_generic_utf8col(ptr,len-has_nl,oldcol);
227 227
                 if(ptr2!=NULL)
228 228
                         re->cursorpos=newpos2+(ptr2-ptr);
229 229
                 else
... ...
@@ -239,12 +239,12 @@ re_processkey(re_t *re, SDL_Event *event)
239 239
                         return(-1); /* couldn't get current line data */
240 240
                 if(event->key.keysym.sym==SDLK_LEFT && re->cursorpos==0)
241 241
                         return(-1); /* going left but already at leftmost char */
242
-                linecols=reui_utf8len(re->ui,ptr,len);
243
-                oldcol=reui_utf8len(re->ui,ptr,re->cursorpos-newpos);
242
+                linecols=redata_generic_utf8len(ptr,len);
243
+                oldcol=redata_generic_utf8len(ptr,re->cursorpos-newpos);
244 244
                 inc=(event->key.keysym.sym==SDLK_LEFT)?-1:1;
245 245
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
246 246
                 if(re->lastcol<=linecols) {
247
-                        ptr2=reui_utf8col(re->ui,ptr,len,re->lastcol+inc);
247
+                        ptr2=redata_generic_utf8col(ptr,len,re->lastcol+inc);
248 248
                 } else
249 249
                         ptr2=NULL;
250 250
                 if(ptr2!=NULL)
... ...
@@ -255,6 +255,8 @@ re_processkey(re_t *re, SDL_Event *event)
255 255
                         re->lastcol+=inc;
256 256
                 re_drawheader(re);
257 257
                 re->contentsdirty=1;
258
+        } else if(event->key.keysym.sym==SDLK_a) {
259
+                ;
258 260
         }
259 261
         return(-1);
260 262
 }
... ...
@@ -300,12 +302,12 @@ re_drawcontents(re_t *re)
300 302
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
301 303
                 reui_write(re->ui,re->x,y,"\x00\x00\x00\xff",(char *)ptr,len-has_nl);
302 304
                 if(row==re->lastrow) {
303
-     #warning DEBUG write of current char
305
+#warning DEBUG write of current char
304 306
                         reui_fill(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
305 307
 #warning TODO: consider tabs
306
-                        curptr=reui_utf8col(re->ui,ptr,len-has_nl,re->lastcol);
308
+                        curptr=redata_generic_utf8col(ptr,len-has_nl,re->lastcol);
307 309
                         curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
308
-                        reui_write(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,"\xff\xff\xff\xff",curptr,reui_utf8charlen(re->ui,ptr,curptrlen));
310
+                        reui_write(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(ptr,curptrlen));
309 311
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
310 312
                 }
311 313
                 pos=newpos+len;
Browse code

Implement left/right movement. Add test_ui with utf8 tests.

Dario Rodriguez authored on 30/08/2020 21:47:55
Showing 1 changed files
... ...
@@ -27,6 +27,7 @@ typedef struct re_t {
27 27
         long cursorpos;
28 28
         int lastcol,lastrow;
29 29
         int maxrow,maxcol;
30
+        int contentsdirty;
30 31
 } re_t;
31 32
 
32 33
 volatile int flag_sigint;
... ...
@@ -43,6 +44,7 @@ void re_free(re_t *re);
43 44
 
44 45
 int re_setfilename(re_t *re, char *filename);
45 46
 int re_processkey(re_t *re, SDL_Event *event);
47
+int re_drawheader(re_t *re);
46 48
 int re_drawcontents(re_t *re);
47 49
 
48 50
 
... ...
@@ -98,11 +100,12 @@ main(int argc, char *argv[])
98 100
         re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
99 101
         re->maxrow=re->h/re->ui->fontheight-1;
100 102
         re->maxcol=re->w/re->ui->fontwidth-1;
101
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,"\x00\x00\xff\xff");
102
-        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","Fichero: %s",re->filename);
103
+        re_drawheader(re);
103 104
         re_drawcontents(re);
104 105
         flag_had_events=0;
105 106
         while(do_exit==0 && flag_sigint==0) {
107
+                if(re->contentsdirty)
108
+                        re_drawcontents(re);
106 109
                 if(re->ui->rendererdirty)
107 110
                         reui_present(re->ui);
108 111
                 sselect_wait(ssel,(flag_had_events)?10:100);
... ...
@@ -207,8 +210,10 @@ re_processkey(re_t *re, SDL_Event *event)
207 210
         int len;
208 211
         int has_nl;
209 212
         int oldcol;
213
+        int linecols;
214
+        int inc;
210 215
         if(re==NULL || event==NULL || event->type!=SDL_KEYDOWN)
211
-                return(-1);
216
+                return(-1); /* sanity check failed */
212 217
         if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
213 218
                 if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
214 219
                         return(-1); /* couldn't get current line data */
... ...
@@ -227,12 +232,44 @@ re_processkey(re_t *re, SDL_Event *event)
227 232
                         re->lastrow++;
228 233
                 else if(event->key.keysym.sym==SDLK_UP && re->lastrow>0)
229 234
                         re->lastrow--;
230
-                re_drawcontents(re);
235
+                re_drawheader(re);
236
+                re->contentsdirty=1;
237
+        } else if(event->key.keysym.sym==SDLK_LEFT || event->key.keysym.sym==SDLK_RIGHT) {
238
+                if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
239
+                        return(-1); /* couldn't get current line data */
240
+                if(event->key.keysym.sym==SDLK_LEFT && re->cursorpos==0)
241
+                        return(-1); /* going left but already at leftmost char */
242
+                linecols=reui_utf8len(re->ui,ptr,len);
243
+                oldcol=reui_utf8len(re->ui,ptr,re->cursorpos-newpos);
244
+                inc=(event->key.keysym.sym==SDLK_LEFT)?-1:1;
245
+                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
246
+                if(re->lastcol<=linecols) {
247
+                        ptr2=reui_utf8col(re->ui,ptr,len,re->lastcol+inc);
248
+                } else
249
+                        ptr2=NULL;
250
+                if(ptr2!=NULL)
251
+                        re->cursorpos=newpos+(ptr2-ptr);
252
+                else
253
+                        re->cursorpos=newpos+(len-has_nl); /* we're past the last col, set cursor to last pos in line */
254
+                if((re->lastcol+inc)>=0)
255
+                        re->lastcol+=inc;
256
+                re_drawheader(re);
257
+                re->contentsdirty=1;
231 258
         }
232 259
         return(-1);
233 260
 }
234 261
 
235 262
 
263
+int
264
+re_drawheader(re_t *re)
265
+{
266
+        if(re==NULL)
267
+                return(-1);
268
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,"\x00\x00\xff\xff");
269
+        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","Fichero: %s Col:%i Row:%i Pos:%li",re->filename,re->lastcol,re->lastrow,re->cursorpos);
270
+        return(0);
271
+}
272
+
236 273
 int
237 274
 re_drawcontents(re_t *re)
238 275
 {
... ...
@@ -240,8 +277,11 @@ re_drawcontents(re_t *re)
240 277
         char *ptr;
241 278
         int len;
242 279
         int y,row;
243
-        char c;
280
+        char *curptr;
281
+        int curptrlen;
244 282
         int has_nl;
283
+        if(re==NULL)
284
+                return(-1);
245 285
         reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
246 286
         row=re->lastrow;
247 287
         pos=re->cursorpos;
... ...
@@ -260,14 +300,17 @@ re_drawcontents(re_t *re)
260 300
                 has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
261 301
                 reui_write(re->ui,re->x,y,"\x00\x00\x00\xff",(char *)ptr,len-has_nl);
262 302
                 if(row==re->lastrow) {
303
+     #warning DEBUG write of current char
263 304
                         reui_fill(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
264
-#warning TODO: consider multibytes characters and tabs to position on the corect character and to pass the correct number of bytes to reui_write
265
-                        c=(re->lastcol>=(len-has_nl))?' ':ptr[re->lastcol];
266
-                        reui_write(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,"\xff\xff\xff\xff",&c,1);
305
+#warning TODO: consider tabs
306
+                        curptr=reui_utf8col(re->ui,ptr,len-has_nl,re->lastcol);
307
+                        curptrlen=(curptr==NULL)?0:(len-has_nl)-(curptr-ptr);
308
+                        reui_write(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,"\xff\xff\xff\xff",curptr,reui_utf8charlen(re->ui,ptr,curptrlen));
267 309
 #warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
268 310
                 }
269 311
                 pos=newpos+len;
270 312
         }
313
+        re->contentsdirty=0;
271 314
         re->ui->rendererdirty=1;
272 315
         return(0);
273 316
 }
Browse code

Implement up/down movement

Dario Rodriguez authored on 26/08/2020 21:50:45
Showing 1 changed files
... ...
@@ -19,11 +19,14 @@
19 19
 #include "ext/socklib.h"
20 20
 
21 21
 typedef struct re_t {
22
-        redata_t *redata;
22
+        redata_t *data;
23 23
         reui_t *ui;
24 24
         int flag_newfile;
25 25
         char filename[PATH_MAX];
26 26
         int x, y, w, h; // contents rect
27
+        long cursorpos;
28
+        int lastcol,lastrow;
29
+        int maxrow,maxcol;
27 30
 } re_t;
28 31
 
29 32
 volatile int flag_sigint;
... ...
@@ -50,6 +53,7 @@ main(int argc, char *argv[])
50 53
         int do_exit;
51 54
         SDL_Event event;
52 55
         sselect *ssel;
56
+        int flag_had_events;
53 57
         if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
54 58
                 fprintf(stderr,"Syntax: %s filename\n",argv[0]);
55 59
                 return(1);
... ...
@@ -68,17 +72,18 @@ main(int argc, char *argv[])
68 72
                 re_free(re),re=NULL;
69 73
                 return(2);
70 74
         }
71
-        if((redata_load(re->redata,re->filename,NULL,NULL))!=0)
75
+        if((redata_load(re->data,re->filename,NULL,NULL))!=0)
72 76
                 re->flag_newfile=1;
73 77
         else
74 78
                 re->flag_newfile=0;
79
+#if 0
75 80
 #warning TESTS
76 81
         {
77 82
                 char buf[129];
78
-                redata_hash(re->redata,buf);
83
+                redata_hash(re->data,buf);
79 84
                 fprintf(stderr,"%s %s\n",buf,re->filename);
80 85
         }
81
-#warning TODO
86
+#endif
82 87
         reui_title(re->ui,re->filename);
83 88
         flag_sigint=flag_sigpipe=0;
84 89
         setsignal(SIGINT,sighandler_sigint);
... ...
@@ -91,15 +96,20 @@ main(int argc, char *argv[])
91 96
         }
92 97
         reui_scr2renderer(re->ui,0,0,re->ui->w,re->ui->h);
93 98
         re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
94
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,(unsigned char *) "\x00\x00\xff\xff");
95
-        reui_printf(re->ui,0,0,(unsigned char *) "\xff\xff\x00\xff","Fichero: %s",re->filename);
99
+        re->maxrow=re->h/re->ui->fontheight-1;
100
+        re->maxcol=re->w/re->ui->fontwidth-1;
101
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,"\x00\x00\xff\xff");
102
+        reui_printf(re->ui,0,0,"\xff\xff\x00\xff","Fichero: %s",re->filename);
96 103
         re_drawcontents(re);
104
+        flag_had_events=0;
97 105
         while(do_exit==0 && flag_sigint==0) {
98 106
                 if(re->ui->rendererdirty)
99 107
                         reui_present(re->ui);
100
-                sselect_wait(ssel,100);
108
+                sselect_wait(ssel,(flag_had_events)?10:100);
109
+                flag_had_events=(flag_had_events>0)?flag_had_events-1:0;
101 110
                 SDL_PumpEvents();
102 111
                 while(SDL_PeepEvents(&event,1,SDL_GETEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT)>0) {
112
+                        flag_had_events=10;
103 113
                         switch(event.type) {
104 114
                                 case SDL_QUIT:
105 115
                                         do_exit=1;
... ...
@@ -153,7 +163,7 @@ re_init(void)
153 163
         if((re=malloc(sizeof(re_t)))==NULL)
154 164
                 return(NULL); /* insuf. mem. */
155 165
         memset(re,0,sizeof(re_t));
156
-        if((re->redata=redata_init(NULL))==NULL) {
166
+        if((re->data=redata_init(NULL))==NULL) {
157 167
                 re_free(re),re=NULL;
158 168
                 return(NULL); /* insuf. mem. */
159 169
         }
... ...
@@ -171,8 +181,8 @@ re_free(re_t *re)
171 181
                 return; /* all done */
172 182
         if(re->ui!=NULL)
173 183
                 reui_free(re->ui),re->ui=NULL;
174
-        if(re->redata!=NULL)
175
-                redata_free(re->redata),re->redata=NULL;
184
+        if(re->data!=NULL)
185
+                redata_free(re->data),re->data=NULL;
176 186
         free(re),re=NULL;
177 187
         return;
178 188
 }
... ...
@@ -192,7 +202,33 @@ re_setfilename(re_t *re, char *filename)
192 202
 int
193 203
 re_processkey(re_t *re, SDL_Event *event)
194 204
 {
195
-#warning TODO
205
+        long newpos,newpos2;
206
+        char *ptr,*ptr2;
207
+        int len;
208
+        int has_nl;
209
+        int oldcol;
210
+        if(re==NULL || event==NULL || event->type!=SDL_KEYDOWN)
211
+                return(-1);
212
+        if(event->key.keysym.sym==SDLK_DOWN || event->key.keysym.sym==SDLK_UP) {
213
+                if(redata_line_info(re->data,re->cursorpos,&newpos,&ptr,&len)==-1)
214
+                        return(-1); /* couldn't get current line data */
215
+                if(event->key.keysym.sym==SDLK_UP && newpos==0)
216
+                        return(-1); /* going up but already at top */
217
+                oldcol=reui_utf8len(re->ui,ptr,re->cursorpos-newpos);
218
+                if(redata_line_info(re->data,(event->key.keysym.sym==SDLK_DOWN)?(newpos+len):(newpos-1),&newpos2,&ptr,&len)==-1)
219
+                        return(-1); /* couldn't get next line data */
220
+                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
221
+                ptr2=reui_utf8col(re->ui,ptr,len-has_nl,oldcol);
222
+                if(ptr2!=NULL)
223
+                        re->cursorpos=newpos2+(ptr2-ptr);
224
+                else
225
+                        re->cursorpos=newpos2+len-has_nl;
226
+                if(event->key.keysym.sym==SDLK_DOWN && re->lastrow<re->maxrow)
227
+                        re->lastrow++;
228
+                else if(event->key.keysym.sym==SDLK_UP && re->lastrow>0)
229
+                        re->lastrow--;
230
+                re_drawcontents(re);
231
+        }
196 232
         return(-1);
197 233
 }
198 234
 
... ...
@@ -200,24 +236,40 @@ re_processkey(re_t *re, SDL_Event *event)
200 236
 int
201 237
 re_drawcontents(re_t *re)
202 238
 {
203
-        int numchunk;
204
-        long offset;
205
-        rechunk_t *chunk;
206
-        unsigned char *ptr,*end;
207
-        int y;
208
-        reui_fill(re->ui,re->x,re->y,re->w,re->h,(unsigned char *) "\xdf\xdf\xdf\xff");
209
-        if(redata_getposptr(re->redata,0,&numchunk,&offset)==-1)
210
-                return(-1);
211
-        chunk=re->redata->chunks[numchunk];
212
-        /* iterate on lines */
213
-        for(y=re->y,ptr=chunk->data+offset,end=memchr(ptr,'\n',chunk->useddata-(ptr-chunk->data)),
214
-          end=(end==NULL)?chunk->data+chunk->useddata:end;ptr!=NULL && y<(re->y+re->h);
215
-          y+=re->ui->fontheight,ptr=(end!=(chunk->data+chunk->useddata))?end+1:NULL,
216
-          end=(ptr==NULL)?NULL:memchr(ptr,'\n',chunk->useddata-(ptr-chunk->data)),
217
-          end=(end==NULL)?chunk->data+chunk->useddata:end) {
218
-                reui_write(re->ui,re->x,y,(unsigned char *) "\x00\x00\x00\xff",ptr,end-ptr);
239
+        long pos,newpos;
240
+        char *ptr;
241
+        int len;
242
+        int y,row;
243
+        char c;
244
+        int has_nl;
245
+        reui_fill(re->ui,re->x,re->y,re->w,re->h,"\xdf\xdf\xdf\xff");
246
+        row=re->lastrow;
247
+        pos=re->cursorpos;
248
+        while(row>0) {
249
+                if(redata_line_info(re->data,pos,&newpos,NULL,NULL)==-1)
250
+                        return(-1);
251
+                pos=(newpos>0)?newpos-1:0;
252
+                row--;
219 253
         }
220
-#warning TODO
221
-        return(-1);
254
+        /* highlight current line */
255
+        reui_fill(re->ui,re->x,re->y+(re->lastrow)*re->ui->fontheight,re->w,re->ui->fontheight+1,"\xef\xef\xef\xff");
256
+        /* draw the lines */
257
+        for(y=re->y;y<(re->y+re->h);y+=re->ui->fontheight,row++) {
258
+                if(redata_line_info(re->data,pos,&newpos,&ptr,&len)==-1)
259
+                        break; /* couldn't get line start pos */
260
+                has_nl=((len>0 && ptr[len-1]=='\n')?1:0);
261
+                reui_write(re->ui,re->x,y,"\x00\x00\x00\xff",(char *)ptr,len-has_nl);
262
+                if(row==re->lastrow) {
263
+                        reui_fill(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,re->ui->fontwidth,re->ui->fontheight+1,"\x00\x00\x00\xff");
264
+#warning TODO: consider multibytes characters and tabs to position on the corect character and to pass the correct number of bytes to reui_write
265
+                        c=(re->lastcol>=(len-has_nl))?' ':ptr[re->lastcol];
266
+                        reui_write(re->ui,re->x+re->ui->fontwidth*re->lastcol,y,"\xff\xff\xff\xff",&c,1);
267
+#warning TODO: if it is one of  '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket.
268
+                }
269
+                pos=newpos+len;
270
+        }
271
+        re->ui->rendererdirty=1;
272
+        return(0);
222 273
 }
223 274
 
275
+
Browse code

Display first lines of the loaded file

Dario Rodriguez authored on 18/08/2020 20:31:28
Showing 1 changed files
... ...
@@ -12,24 +12,44 @@
12 12
 #include <unistd.h>
13 13
 #include <string.h>
14 14
 #include <limits.h>
15
+#include <signal.h>
15 16
 
16 17
 #include "re_data.h"
18
+#include "re_ui.h"
19
+#include "ext/socklib.h"
17 20
 
18 21
 typedef struct re_t {
19 22
         redata_t *redata;
23
+        reui_t *ui;
20 24
         int flag_newfile;
21 25
         char filename[PATH_MAX];
26
+        int x, y, w, h; // contents rect
22 27
 } re_t;
23 28
 
29
+volatile int flag_sigint;
30
+volatile int flag_sigpipe;
31
+
32
+
33
+static int setsignal(int num, void (*sighandler)(int));
34
+static void sighandler_sigint(int num);
35
+static void sighandler_sigpipe(int num);
36
+
37
+
24 38
 re_t *re_init(void);
25 39
 void re_free(re_t *re);
26 40
 
27 41
 int re_setfilename(re_t *re, char *filename);
42
+int re_processkey(re_t *re, SDL_Event *event);
43
+int re_drawcontents(re_t *re);
44
+
28 45
 
29 46
 int
30 47
 main(int argc, char *argv[])
31 48
 {
32 49
         re_t *re;
50
+        int do_exit;
51
+        SDL_Event event;
52
+        sselect *ssel;
33 53
         if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
34 54
                 fprintf(stderr,"Syntax: %s filename\n",argv[0]);
35 55
                 return(1);
... ...
@@ -38,6 +58,11 @@ main(int argc, char *argv[])
38 58
                 fprintf(stderr,"ERROR: couldn't init structs.\n");
39 59
                 return(2);
40 60
         }
61
+        if((ssel=sselect_init())==NULL) {
62
+                fprintf(stderr,"ERROR: couln't init internal data.\n");
63
+                re_free(re),re=NULL;
64
+                return(2);
65
+        }
41 66
         if(re_setfilename(re,argv[argc-1])!=0) {
42 67
                 fprintf(stderr,"ERROR: filename too long.\n");
43 68
                 re_free(re),re=NULL;
... ...
@@ -54,10 +79,73 @@ main(int argc, char *argv[])
54 79
                 fprintf(stderr,"%s %s\n",buf,re->filename);
55 80
         }
56 81
 #warning TODO
82
+        reui_title(re->ui,re->filename);
83
+        flag_sigint=flag_sigpipe=0;
84
+        setsignal(SIGINT,sighandler_sigint);
85
+        setsignal(SIGPIPE,sighandler_sigpipe);
86
+        do_exit=0;
87
+        if((ssel=sselect_init())==NULL) {
88
+                fprintf(stderr,"ERROR: filename too long.\n");
89
+                re_free(re),re=NULL;
90
+                return(2);
91
+        }
92
+        reui_scr2renderer(re->ui,0,0,re->ui->w,re->ui->h);
93
+        re->x=0,re->y=re->ui->fontheight,re->w=re->ui->w,re->h=re->ui->h-re->y;
94
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,(unsigned char *) "\x00\x00\xff\xff");
95
+        reui_printf(re->ui,0,0,(unsigned char *) "\xff\xff\x00\xff","Fichero: %s",re->filename);
96
+        re_drawcontents(re);
97
+        while(do_exit==0 && flag_sigint==0) {
98
+                if(re->ui->rendererdirty)
99
+                        reui_present(re->ui);
100
+                sselect_wait(ssel,100);
101
+                SDL_PumpEvents();
102
+                while(SDL_PeepEvents(&event,1,SDL_GETEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT)>0) {
103
+                        switch(event.type) {
104
+                                case SDL_QUIT:
105
+                                        do_exit=1;
106
+                                        break;
107
+                                case SDL_KEYDOWN:
108
+                                        re_processkey(re,&event);
109
+                                        break;
110
+                                case SDL_WINDOWEVENT:
111
+                                        if(event.window.event==SDL_WINDOWEVENT_SHOWN
112
+                                          || event.window.event==SDL_WINDOWEVENT_EXPOSED) {
113
+                                                re->ui->rendererdirty=1;
114
+                                        }
115
+                                        break;
116
+                                default:
117
+                                        break;
118
+                        }
119
+                }
120
+        }
121
+        sselect_free(ssel),ssel=NULL;
57 122
         re_free(re),re=NULL;
58 123
         return(0);
59 124
 }
60 125
 
126
+static int
127
+setsignal(int num, void (*sighandler)(int))
128
+{
129
+        struct sigaction sa;
130
+        sa.sa_handler=sighandler;
131
+        sigemptyset(&sa.sa_mask);
132
+        sa.sa_flags=0;
133
+        return(sigaction(num,&sa,0));
134
+}
135
+
136
+static void
137
+sighandler_sigint(int num)
138
+{
139
+        flag_sigint=1;
140
+}
141
+
142
+static void
143
+sighandler_sigpipe(int num)
144
+{
145
+        flag_sigpipe=1;
146
+}
147
+
148
+
61 149
 re_t *
62 150
 re_init(void)
63 151
 {
... ...
@@ -69,6 +157,10 @@ re_init(void)
69 157
                 re_free(re),re=NULL;
70 158
                 return(NULL); /* insuf. mem. */
71 159
         }
160
+        if((re->ui=reui_init())==NULL) {
161
+                re_free(re),re=NULL;
162
+                return(NULL); /* video init error */
163
+        }
72 164
         return(re);
73 165
 }
74 166
 
... ...
@@ -77,6 +169,8 @@ re_free(re_t *re)
77 169
 {
78 170
         if(re==NULL)
79 171
                 return; /* all done */
172
+        if(re->ui!=NULL)
173
+                reui_free(re->ui),re->ui=NULL;
80 174
         if(re->redata!=NULL)
81 175
                 redata_free(re->redata),re->redata=NULL;
82 176
         free(re),re=NULL;
... ...
@@ -95,4 +189,35 @@ re_setfilename(re_t *re, char *filename)
95 189
         return(0);
96 190
 }
97 191
 
192
+int
193
+re_processkey(re_t *re, SDL_Event *event)
194
+{
195
+#warning TODO
196
+        return(-1);
197
+}
198
+
199
+
200
+int
201
+re_drawcontents(re_t *re)
202
+{
203
+        int numchunk;
204
+        long offset;
205
+        rechunk_t *chunk;
206
+        unsigned char *ptr,*end;
207
+        int y;
208
+        reui_fill(re->ui,re->x,re->y,re->w,re->h,(unsigned char *) "\xdf\xdf\xdf\xff");
209
+        if(redata_getposptr(re->redata,0,&numchunk,&offset)==-1)
210
+                return(-1);
211
+        chunk=re->redata->chunks[numchunk];
212
+        /* iterate on lines */
213
+        for(y=re->y,ptr=chunk->data+offset,end=memchr(ptr,'\n',chunk->useddata-(ptr-chunk->data)),
214
+          end=(end==NULL)?chunk->data+chunk->useddata:end;ptr!=NULL && y<(re->y+re->h);
215
+          y+=re->ui->fontheight,ptr=(end!=(chunk->data+chunk->useddata))?end+1:NULL,
216
+          end=(ptr==NULL)?NULL:memchr(ptr,'\n',chunk->useddata-(ptr-chunk->data)),
217
+          end=(end==NULL)?chunk->data+chunk->useddata:end) {
218
+                reui_write(re->ui,re->x,y,(unsigned char *) "\x00\x00\x00\xff",ptr,end-ptr);
219
+        }
220
+#warning TODO
221
+        return(-1);
222
+}
98 223
 
Browse code

Reworked plugin API

Dario Rodriguez authored on 09/04/2019 14:28:44
Showing 1 changed files
... ...
@@ -43,7 +43,7 @@ main(int argc, char *argv[])
43 43
                 re_free(re),re=NULL;
44 44
                 return(2);
45 45
         }
46
-        if((redata_load(re->redata,re->filename,0))!=0)
46
+        if((redata_load(re->redata,re->filename,NULL,NULL))!=0)
47 47
                 re->flag_newfile=1;
48 48
         else
49 49
                 re->flag_newfile=0;
Browse code

Refactor unsaved into a plugin of redata

Dario Rodriguez authored on 04/04/2019 21:53:07
Showing 1 changed files
... ...
@@ -65,7 +65,7 @@ re_init(void)
65 65
         if((re=malloc(sizeof(re_t)))==NULL)
66 66
                 return(NULL); /* insuf. mem. */
67 67
         memset(re,0,sizeof(re_t));
68
-        if((re->redata=redata_init())==NULL) {
68
+        if((re->redata=redata_init(NULL))==NULL) {
69 69
                 re_free(re),re=NULL;
70 70
                 return(NULL); /* insuf. mem. */
71 71
         }
Browse code

renamed recenteditor_data to re_data, recenteditor_tests to re_tests

Dario Rodriguez authored on 01/04/2019 21:26:29
Showing 1 changed files
... ...
@@ -13,7 +13,7 @@
13 13
 #include <string.h>
14 14
 #include <limits.h>
15 15
 
16
-#include "recenteditor_data.h"
16
+#include "re_data.h"
17 17
 
18 18
 typedef struct re_t {
19 19
         redata_t *redata;
Browse code

start implementation of undo and unsaved in redata. tentative sha3-512 support for unsaved integrity check

Dario Rodriguez authored on 26/02/2019 21:26:05
Showing 1 changed files
... ...
@@ -43,10 +43,16 @@ main(int argc, char *argv[])
43 43
                 re_free(re),re=NULL;
44 44
                 return(2);
45 45
         }
46
-        if((redata_load(re->redata,re->filename))!=0)
46
+        if((redata_load(re->redata,re->filename,0))!=0)
47 47
                 re->flag_newfile=1;
48 48
         else
49 49
                 re->flag_newfile=0;
50
+#warning TESTS
51
+        {
52
+                char buf[129];
53
+                redata_hash(re->redata,buf);
54
+                fprintf(stderr,"%s %s\n",buf,re->filename);
55
+        }
50 56
 #warning TODO
51 57
         re_free(re),re=NULL;
52 58
         return(0);
Browse code

data structures skeleton

Dario Rodriguez authored on 25/02/2019 22:04:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,92 @@
1
+/*
2
+ * recenteditor.c
3
+ *
4
+ * A programmers editor
5
+ *
6
+ * Author: Dario Rodriguez dario@softhome.net
7
+ * This program is licensed under the terms of GNU GPL v2.1+
8
+ */
9
+
10
+#include <stdio.h>
11
+#include <stdlib.h>
12
+#include <unistd.h>
13
+#include <string.h>
14
+#include <limits.h>
15
+
16
+#include "recenteditor_data.h"
17
+
18
+typedef struct re_t {
19
+        redata_t *redata;
20
+        int flag_newfile;
21
+        char filename[PATH_MAX];
22
+} re_t;
23
+
24
+re_t *re_init(void);
25
+void re_free(re_t *re);
26
+
27
+int re_setfilename(re_t *re, char *filename);
28
+
29
+int
30
+main(int argc, char *argv[])
31
+{
32
+        re_t *re;
33
+        if(argc!=2 || strcmp(argv[argc-1],"--help")==0) {
34
+                fprintf(stderr,"Syntax: %s filename\n",argv[0]);
35
+                return(1);
36
+        }
37
+        if((re=re_init())==NULL) {
38
+                fprintf(stderr,"ERROR: couldn't init structs.\n");
39
+                return(2);
40
+        }
41
+        if(re_setfilename(re,argv[argc-1])!=0) {
42
+                fprintf(stderr,"ERROR: filename too long.\n");
43
+                re_free(re),re=NULL;
44
+                return(2);
45
+        }
46
+        if((redata_load(re->redata,re->filename))!=0)
47
+                re->flag_newfile=1;
48
+        else
49
+                re->flag_newfile=0;
50
+#warning TODO
51
+        re_free(re),re=NULL;
52
+        return(0);
53
+}
54
+
55
+re_t *
56
+re_init(void)
57
+{
58
+        re_t *re;
59
+        if((re=malloc(sizeof(re_t)))==NULL)
60
+                return(NULL); /* insuf. mem. */
61
+        memset(re,0,sizeof(re_t));
62
+        if((re->redata=redata_init())==NULL) {
63
+                re_free(re),re=NULL;
64
+                return(NULL); /* insuf. mem. */
65
+        }
66
+        return(re);
67
+}
68
+
69
+void
70
+re_free(re_t *re)
71
+{
72
+        if(re==NULL)
73
+                return; /* all done */
74
+        if(re->redata!=NULL)
75
+                redata_free(re->redata),re->redata=NULL;
76
+        free(re),re=NULL;
77
+        return;
78
+}
79
+
80
+int
81
+re_setfilename(re_t *re, char *filename)
82
+{
83
+        if(re==NULL || filename==NULL)
84
+                return(-1);
85
+        strncpy(re->filename,filename,sizeof(re->filename));
86
+        re->filename[sizeof(re->filename)-1]='\0';
87
+        if(strcmp(filename,re->filename)!=0)
88
+                return(-1); /* filename too long */
89
+        return(0);
90
+}
91
+
92
+