Browse code

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

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