... | ... |
@@ -236,6 +236,28 @@ redata_getposptr(redata_t *redata, long pos, int *numchunk, int *offset) |
236 | 236 |
return(-1); |
237 | 237 |
} |
238 | 238 |
|
239 |
+int |
|
240 |
+redata_getchar(redata_t *redata, long pos) |
|
241 |
+{ |
|
242 |
+ int numchunk; |
|
243 |
+ int offset; |
|
244 |
+ int avail; |
|
245 |
+ rechunk_t *chunk; |
|
246 |
+ if(redata==NULL || pos<0 || pos>=redata_getsize(redata)) |
|
247 |
+ return(-1); /* sanity check failed */ |
|
248 |
+ if(redata_getposptr(redata,pos,&numchunk,&offset)!=0) |
|
249 |
+ return(-1); /* couldn't get pos */ |
|
250 |
+ /* search for data starting at that pos */ |
|
251 |
+ for(;numchunk<redata->sizechunks;numchunk++,offset=0) { |
|
252 |
+ chunk=redata->chunks[numchunk]; |
|
253 |
+ avail=chunk->useddata-offset; |
|
254 |
+ if(avail>0) { |
|
255 |
+ return((int) (((unsigned char *)chunk->data)[offset])); |
|
256 |
+ } |
|
257 |
+ } |
|
258 |
+ return(-1); /* not found */ |
|
259 |
+} |
|
260 |
+ |
|
239 | 261 |
int |
240 | 262 |
redata_wipe(redata_t *redata) |
241 | 263 |
{ |
... | ... |
@@ -108,7 +108,8 @@ long redata_getsize(redata_t *redata); |
108 | 108 |
long redata_getused(redata_t *redata); |
109 | 109 |
long redata_getavailable(redata_t *redata); |
110 | 110 |
int redata_getposptr(redata_t *redata, long pos, int *numchunk, int *offset); |
111 |
- |
|
111 |
+int redata_getchar(redata_t *redata, long pos); |
|
112 |
+ |
|
112 | 113 |
/* low level stuff */ |
113 | 114 |
int redata_wipe(redata_t *redata); |
114 | 115 |
int redata_preallocate(redata_t *redata, long size); |
... | ... |
@@ -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); |