... | ... |
@@ -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 |
{ |
... | ... |
@@ -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) |
... | ... |
@@ -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\ |
... | ... |
@@ -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) { |
... | ... |
@@ -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)); |
... | ... |
@@ -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); |
... | ... |
@@ -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 { |
... | ... |
@@ -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 { |
... | ... |
@@ -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); |
... | ... |
@@ -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 |
|
... | ... |
@@ -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; |
... | ... |
@@ -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 |
+} |
... | ... |
@@ -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 |
... | ... |
@@ -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 |
|
... | ... |
@@ -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; |
... | ... |
@@ -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; |
... | ... |
@@ -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); |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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; |
... | ... |
@@ -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) |
... | ... |
@@ -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); |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
|
... | ... |
@@ -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 |
|
... | ... |
@@ -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 */ |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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 */ |
... | ... |
@@ -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; |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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); |
... | ... |
@@ -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 */ |
... | ... |
@@ -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 |
|
... | ... |
@@ -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 |
|
... | ... |
@@ -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 */ |
... | ... |
@@ -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> |
... | ... |
@@ -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; |
... | ... |
@@ -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 */ |
... | ... |
@@ -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) { |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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())); |
... | ... |
@@ -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++; |
... | ... |
@@ -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); |
... | ... |
@@ -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)); |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
... | ... |
@@ -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 */ |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
|
... | ... |
@@ -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 { |
... | ... |
@@ -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 */ |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
|
... | ... |
@@ -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)) { |
... | ... |
@@ -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) { |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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) |
... | ... |
@@ -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; |
... | ... |
@@ -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¬-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); |
... | ... |
@@ -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) { |
... | ... |
@@ -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); |
... | ... |
@@ -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¬-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)); |
... | ... |
@@ -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¬-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); |
... | ... |
@@ -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)) { |
... | ... |
@@ -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 |
{ |
... | ... |
@@ -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) |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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 |
{ |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
|
... | ... |
@@ -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)) { |
... | ... |
@@ -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 |
|
... | ... |
@@ -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); |
... | ... |
@@ -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) |
... | ... |
@@ -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"); |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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); |
... | ... |
@@ -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 |
... | ... |
@@ -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; |
... | ... |
@@ -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) |
... | ... |
@@ -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 |
{ |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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'; |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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); |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
{ |
... | ... |
@@ -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; |
... | ... |
@@ -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 |
|
... | ... |
@@ -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; |
... | ... |
@@ -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 |
} |
... | ... |
@@ -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 |
+ |
... | ... |
@@ -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 |
|
... | ... |
@@ -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 |
} |
... | ... |
@@ -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); |
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 |
+ |