summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCalyton rhodes <clayton@berkels.CCCC.com>2021-11-08 13:09:46 -0500
committerCalyton rhodes <clayton@berkels.CCCC.com>2021-11-08 13:09:46 -0500
commitd39ecb70db2e5de42f1966bb2d577a652291d761 (patch)
tree22c2fa187d6af7fe1ee73548f96569edff443117
parent7f697b39c6fed3ec7185f2025ec0fa7776ce930e (diff)
Updated README.MD.v0.0.4
Signed-off-by: Calyton rhodes <clayton@berkels.CCCC.com>
-rw-r--r--+MANIFEST5
-rw-r--r--3Days.nsi2
-rw-r--r--HolyEd/EDITOR.HC792
-rw-r--r--HolyEd/EDITOR2.HC2641
-rw-r--r--HolyEd/_EDITOR2.HC2674
-rw-r--r--README.MD6
-rw-r--r--ed_screenshot.pngbin60968 -> 10219 bytes
7 files changed, 577 insertions, 5543 deletions
diff --git a/+MANIFEST b/+MANIFEST
index 757a2cb..3cb17ff 100644
--- a/+MANIFEST
+++ b/+MANIFEST
@@ -1,5 +1,5 @@
name: 3days
-version: 0.0.3
+version: 0.0.4
comment: A HolyC Compiler
desc: <<EOD
This is a 64bit HolyC JIT Compiler,it also includes an assembler.
@@ -7,4 +7,5 @@ EOD
arch: amd64
maintainer: nrootconauto@gmail.com
prefix: /
-origin: devel/3Days \ No newline at end of file
+origin: devel/3Days
+deps: {sdl2:{origin:"devel/sdl20",version:"2.0.12_7"}}
diff --git a/3Days.nsi b/3Days.nsi
index cad4e1e..2bd3ece 100644
--- a/3Days.nsi
+++ b/3Days.nsi
@@ -6,7 +6,7 @@
!define APP_NAME "3Days"
!define COMP_NAME "nrootconauto@gmail.com"
-!define VERSION "00.00.03.00"
+!define VERSION "00.00.04.00"
!define COPYRIGHT "None"
!define DESCRIPTION "A HolyC Compiler"
!define INSTALLER_NAME "setup.exe"
diff --git a/HolyEd/EDITOR.HC b/HolyEd/EDITOR.HC
index c4b31c9..9445553 100644
--- a/HolyEd/EDITOR.HC
+++ b/HolyEd/EDITOR.HC
@@ -1,5 +1,6 @@
-#include "KEYS.HC"
+#include "KEYS2.HC"
#include "ROPE.HC"
+#include "FONT.HC"
#define EDIT_UNUSED 0
#define EDIT_INS_STR 3
#define EDIT_DEL_STR 4
@@ -75,7 +76,7 @@ U0 FreeTrie(CTrie *t) {
FreeTrie(t->ents[cnt]);
}
Free(t->name);
- Free(t->fullname);
+ Free(t->fullname);
Free(t);
}
CTrie *TagNew(U8 *fullname,U8 *name,U8 *fn,I64 ln,U8 kind) {
@@ -369,6 +370,7 @@ I64 IndentLevel(CLine *ln) {
return cnt;
}
//Color pairs
+#define CP_BLANK 0
#define CP_KW 1
#define CP_WORD 2
#define CP_TOK 3
@@ -388,13 +390,174 @@ I64 IndentLevel(CLine *ln) {
#define CP_LINUM_ERR 17
#define CP_LINUM_WARN 18
#define CP_CURSOR 19
+//TODO
+#define SOL_BLACK 0x000000
+#define SOL_WHITE 0xfdf6e3
+#define SOL_YELLOW 0xb58900
+#define SOL_ORANGE 0xcb4b16
+#define SOL_RED 0xdc322f
+#define SOL_MAGENTA 0xd33682
+#define SOL_BLUE 0x286bd2
+#define SOL_CYAN 0x2aa198
+#define SOL_GREEN 0x859900
+U32 union U_RGBA8888 {
+ class {
+ U8 b;
+ U8 g;
+ U8 r;
+ U8 a;
+ };
+};
+class CSDL_ColorPair {
+ U_RGBA8888 fg;
+ U_RGBA8888 bg;
+};
+CSDL_ColorPair SDL_ColorPairs[64];
+SDL_Window *global_window=NULL;
+SDL_Surface *global_font=NULL;
+#define FONT_X 8
+#define FONT_Y 8
+U0 SDL_InitScr() {
+ global_window=SDL_CreateWindow("HolyEd",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_RESIZABLE);
+ global_font=SDL_CreateRGBSurface(0,FONT_X*0x100,FONT_Y,32,0,0,0,0);
+ SDL_FillRect(global_font, NULL, 0x00000000);
+ I64 cnt=0x100;
+ while(--cnt>=0) {
+ I64 top=8;
+ while(--top>=0) {
+ I64 bit=0;
+ U8 byte=sys_font_std[cnt].u8[top];
+ for(;bit!=8;bit++) {
+ if(Bt(&byte,bit)) {
+ SDL_Rect pixel={cnt*8+bit,top,1,1};
+ SDL_FillRect(global_font,&pixel,0xffffffff);
+ }
+ }
+ }
+ }
+ SDL_SetColorKey(global_font,1,0x00000000);
+ SDL_StartTextInput;
+}
+class CSDL_ScrnChr {
+ U8 chr;
+ I8 cp; //negative for inverse
+};
+class CSDL_TextWin {
+ SDL_Surface *text;
+ U8 cur_cp; //From SDL_ColorPairs
+ I64 x,y,begx,begy,curx,cury;
+ //The charactors on the screen.
+ CSDL_ScrnChr *char_cache;
+ Bool cur_enabled;
+ Bool inverse;
+};
+#define FONT_X 8
+#define FONT_Y 8
+#define FONT_X2 16
+#define FONT_Y2 16
+CSDL_TextWin *SDL_NewTextWin(I64 w,I64 h) {
+ CSDL_TextWin *ret=MAlloc(sizeof(CSDL_TextWin));
+ ret->text=SDL_CreateRGBSurface(0,w*FONT_X2,h*FONT_Y2,32,0,0,0,0);
+ ret->cur_cp=CP_WHITE;
+ ret->char_cache=MAlloc(sizeof(CSDL_ScrnChr)*w*h);
+ return ret;
+}
+U0 SDL_DestroyTextWin(CSDL_TextWin *win) {
+ Free(win->char_cache);
+ SDL_FreeSurface(win->text);
+ Free(win);
+}
+I64 SDL_WinX(CSDL_TextWin *w) {
+ I32 x=w->text->w,y=w->text->h;
+ return x/FONT_X2;
+}
+I64 SDL_WinY(CSDL_TextWin *w) {
+ I32 x=w->text->w,y=w->text->h;
+ return y/FONT_Y2;
+}
+//Pass CSDL_TextWin's
+U0 SDL_DrawWin(...) {
+ I64 idx=0;
+ I32 winx,winy;
+ SDL_GetWindowSize(global_window,&winx,&winy);
+ winx/=FONT_X2,winy/=FONT_Y2;
+ SDL_Surface *winsurf=SDL_GetWindowSurface(global_window);
+ SDL_FillRect(winsurf,NULL,SOL_WHITE);
+ for(;idx!=argc;idx++) {
+ CSDL_TextWin *w=argv[idx];
+ I32 rx=w->text->w,ry=w->text->h;
+ SDL_Rect sbox={w->begx*FONT_X2,w->begy*FONT_Y2,rx/FONT_X2*FONT_X2,ry/FONT_Y2*FONT_Y2};
+ SDL_BlitSurface(w->text,NULL,winsurf,&sbox);
+ if(rx/FONT_X2!=winx||ry/FONT_Y2!=winy) {
+ "RESETING\n";
+ SDL_FreeSurface(w->text);
+ w->text=SDL_CreateRGBSurface(0,winx*FONT_X2,winy*FONT_Y2,32,0,0,0,0);
+ Free(w->char_cache);
+ w->char_cache=MAlloc(sizeof(CSDL_ScrnChr)*winx*winy);
+ }
+ if(w->cur_enabled) {
+ SDL_Rect crect={w->curx*FONT_X2,w->cury*FONT_Y2+FONT_Y2-2,FONT_X2,4};
+ SDL_FillRect(winsurf,&crect,0xff000000);
+ }
+ }
+ SDL_UpdateWindowSurface(global_window);
+}
+U0 SDL_AddCh(CSDL_TextWin *win,U8 ch,Bool force_in_view=FALSE) {
+ I64 w=SDL_WinX(win);
+ if(force_in_view&&ch!='\n') {
+ if(win->x+1>=w) return;
+ }
+ if(ch=='\n') goto nxtln;
+ I64 mult=1;
+ if(win->inverse) mult=-1;
+ if((win->char_cache[win->y*w+win->x].chr==ch)&&(win->char_cache[win->y*w+win->x].cp==mult*win->cur_cp)) goto next;
+ SDL_Rect fsrc={ch*FONT_X,0,FONT_X,FONT_Y};
+ SDL_Rect dstbox={win->x*FONT_X2,win->y*FONT_Y2,FONT_X2,FONT_Y2};
+ U_RGBA8888 bg=SDL_ColorPairs[win->cur_cp].bg;
+ U_RGBA8888 fg=SDL_ColorPairs[win->cur_cp].fg;
+ if(win->inverse) {
+ U_RGBA8888 tmp=bg;
+ bg=fg;
+ fg=tmp;
+ }
+ SDL_SetSurfaceColorMod(global_font,fg.r,fg.g,fg.b);
+ SDL_FillRect(win->text,&dstbox,bg);
+ SDL_BlitScaled(global_font,&fsrc,win->text,&dstbox);
+ win->char_cache[win->y*w+win->x].chr=ch;
+ win->char_cache[win->y*w+win->x].cp=win->cur_cp*mult;
+ next:
+ if(++win->x>=w) {
+ nxtln:
+ win->x=0,win->y++;
+ }
+ if(win->y<SDL_WinY(win)) {
+ } else {
+ win->y=SDL_WinY(win)-1;
+ }
+}
+U0 SDL_Print(CSDL_TextWin *win,U8 *str) {
+ I64 len=StrLen(str),idx=0;
+ for(;idx!=len;idx++) {
+ SDL_AddCh(win,str[idx],TRUE);
+ }
+}
+U0 SDL_ClrToEOL(CSDL_TextWin *w) {
+ I64 width=SDL_WinX(w)-w->x;
+ U_RGBA8888 white=SOL_WHITE;
+ SDL_Rect r={w->x*FONT_X2,w->y*FONT_Y2,width*FONT_X2,FONT_Y2};
+ SDL_LockSurface(w->text);
+ SDL_FillRect(w->text,&r,SOL_WHITE);
+ SDL_UnlockSurface(w->text);
+ I64 idx=w->y*SDL_WinX(w)+w->x;
+ while(--width>=0)
+ w->char_cache[idx+width].chr=' ',w->char_cache[width].cp=CP_BLANK;
+}
class CEditor {
- WINDOW * window;
+ CSDL_TextWin *window;
CUndoInfo undo_info[UNDO_INFO_LENGTH];
I64 undo_info_cur;
I64 undo_info_end;
I64 undo_info_start;
-
Bool *dirty_screen_lines;
I64 vp_start_line;
I64 x_scroll;
@@ -412,9 +575,12 @@ class CEditor {
CDiag *diags;
U8 *fn;
I64 margin_top,margin_bottom;
+ I64 sel_start,sel_end;
};
+U8 *EdGetSelText(CEditor *ed);
+U0 EdDelSel(CEditor *ed);
U0 MarkLineColors(CEditor *ed);
-U0 WriteWithinWin(WINDOW *win,U8 *text,I64 x_scroll=0);
+U0 WriteWithinWin(CSDL_TextWin *win,U8 *text,I64 x_scroll=0);
I64 OpenFile(U8 *name,I64 ln=0);
I64 ShowDiagsWindow(CEditor *parent) {
CDiag *first=parent->diags;
@@ -426,8 +592,8 @@ I64 ShowDiagsWindow(CEditor *parent) {
CDiag **lines=MAlloc(cnt*sizeof(CDiag*));
cnt=0;
while(iter) {lines[cnt++]=iter;iter=iter->next;}
- WINDOW *win=newwin(getmaxy(stdscr),getmaxx(stdscr),0,0);
- wbkgdset(win,COLOR_PAIR(CP_WHITE));
+ parent->window->cur_cp=CP_WHITE;
+ CSDL_TextWin *win=parent->window;
draw:
I64 h=getmaxy(stdscr);
I64 cap=MinI64(y_scroll+h,cnt);
@@ -435,18 +601,19 @@ I64 ShowDiagsWindow(CEditor *parent) {
dloop:
if(cnt2+y_scroll>=cnt) {
clear:
- while(cnt2<getmaxy(win)) {
- wmove(win,cnt2++,0);
- wclrtoeol(win);
+ while(cnt2<SDL_WinY(win)) {
+ win->y=cnt2++;
+ win->x=0;
+ SDL_ClrToEOL(win);
}
goto inp;
}
if(cnt2+y_scroll==curln) {
- wattron(win,COLOR_PAIR(CP_FUZZY_SEL_B));
+ win->cur_cp=CP_FUZZY_SEL_B;
} else {
- wattron(win,COLOR_PAIR(CP_FUZZY_UNSEL_A));
+ win->cur_cp=CP_FUZZY_UNSEL_A;
}
- wmove(win,cnt2,0);
+ win->y=cnt2,win->x=0;
I64 off=-x_scroll;
CDiag *cur=lines[cnt2++ +y_scroll];
U8 *lncol=MStrPrint("%s:%d:%d: ",cur->fn,cur->ln,cur->col);
@@ -465,20 +632,20 @@ I64 ShowDiagsWindow(CEditor *parent) {
}
if(StrFirstOcc(cur.msg,"\r\n")) *StrFirstOcc(cur.msg,"\n\r")=0;
WriteWithinWin(win,cur->msg,off);
- wclrtoeol(win);
+ SDL_ClrToEOL(win);
if(cnt2+y_scroll<cap) goto dloop;
goto clear;
inp:
- redrawwin(win);
- I64 key=GetKey(win);
+ SDL_DrawWin(win);
+ I64 key=GetKey();
switch(key) {
case ED_KEY_ESCAPE: goto exit;
case ERR: goto inp;
case ED_KEY_PAGEUP:
- curln=MaxI64(0,curln-getmaxy(win));
+ curln=MaxI64(0,curln-SDL_WinY(win));
break;
case ED_KEY_PAGEDOWN:
- curln=MinI64(cnt,curln+getmaxy(win));
+ curln=MinI64(cnt,curln+SDL_WinY(win));
break;
case ED_KEY_RIGHT: ++x_scroll; break;
case ED_KEY_LEFT: x_scroll=MaxI64(0,--x_scroll); break;
@@ -492,18 +659,16 @@ I64 ShowDiagsWindow(CEditor *parent) {
goto exit;
}
break;
+ case ED_KEY_REDRAW:
case ED_KEY_RESIZE:
- wresize(win,getmaxy(stdscr),getmaxx(stdscr));
- redrawwin(win);
+ SDL_DrawWin(win);
break;
}
if(curln<y_scroll) y_scroll=curln;
- else if(curln>=getmaxy(win)+y_scroll) y_scroll=curln-getmaxy(win)+1;
+ else if(curln>=SDL_WinY(win)+y_scroll) y_scroll=curln-SDL_WinY(win)+1;
goto draw;
exit:
- delwin(win);
Free(lines);
- redrawwin(parent->window);
return ret;
}
@@ -564,9 +729,7 @@ class CBuffer:CHash {
CHashTable *buffers=HashTableNew(1<<5);
U0 FocusCursor(CEditor *ed,I64 lmargin=0) {
//https://stackoverflow.com/questions/1811955/ncurses-terminal-size
- wtimeout(stdscr,0);
- wgetch(stdscr);
- I64 w=getmaxx(ed->window)-lmargin;
+ I64 w=SDL_WinX(ed->window)-lmargin;
if(ed->curx<ed->x_scroll) {
ed->x_scroll=ed->curx;
} else if(ed->x_scroll+w<=ed->curx) {
@@ -574,8 +737,8 @@ U0 FocusCursor(CEditor *ed,I64 lmargin=0) {
}
if(ed->cury<ed->vp_start_line) {
ed->vp_start_line=ed->cury;
- } else if(ed->vp_start_line+getmaxy(ed->window)-ed->margin_top<=ed->cury) {
- ed->vp_start_line=ed->cury-getmaxy(ed->window)+1+ed->margin_top;
+ } else if(ed->vp_start_line+SDL_WinY(ed->window)-ed->margin_top<=ed->cury) {
+ ed->vp_start_line=ed->cury-SDL_WinY(ed->window)+1+ed->margin_top;
}
}
I64 GetLinum(CEditor *ed,CLine *ln) {
@@ -640,16 +803,16 @@ U0 DirtyLinesBelow(CEditor *ed,I64 ln) {
ed->line_cache_size=ln;
ln-=ed->vp_start_line;
}
-U0 WriteWithinWin(WINDOW *win,U8 *text,I64 x_scroll=0) {
+U0 WriteWithinWin(CSDL_TextWin *win,U8 *text,I64 x_scroll=0) {
I64 l=StrLen(text)+x_scroll;
I64 s=x_scroll;
while(s!=l) {
- if(getmaxx(win)>=s>=0) {
+ if(SDL_WinX(win)>=s>=0) {
U8 chr=text[s-x_scroll];
if(chr=='\t')
- waddch(win,' ');
+ SDL_AddCh(win,' ',TRUE);
else if(chr!='\r'){
- waddch(win,chr);
+ SDL_AddCh(win,chr,TRUE);
}
}
s++;
@@ -660,11 +823,11 @@ U0 WriteWithinView(CEditor *ed,U8 *text,I64 off) {
I64 s=off;
I64 e=off+l;
while(s!=e) {
- if(ed->x_scroll+ed->w>=s>=ed->x_scroll) {
+ if(ed->x_scroll+SDL_WinX(ed->window)>=s>=ed->x_scroll) {
if(text[s-off]=='\t')
- waddch(ed->window,' ');
+ SDL_AddCh(ed->window,' ',TRUE);
else if(text[s-off]!='\r')
- waddch(ed->window,text[s-off]);
+ SDL_AddCh(ed->window,text[s-off],TRUE);
}
s++;
}
@@ -679,7 +842,7 @@ CLine *SearchForMLCommmentStart(CLine *s) {
while(s) {
if(s->flags&ED_LNF_COMMENTED_START)
if(!(s->flags&ED_LNF_COMMENTED_OUT))
- return s;
+ return s;
s=s->prev;
}
return NULL;
@@ -692,8 +855,36 @@ CLine *SearchForMLCommmentEnd(CLine *s) {
}
return NULL;
}
+U0 __HighlightWrite(CEditor *ed,U8 *text,I64 off,I64 sel_start=I64_MAX,I64 sel_end=I64_MAX) {
+ I64 len=StrLen(text),idx;
+ for(idx=0;idx!=len;idx++) {
+ if(off+idx>=ed->x_scroll) {
+ if(sel_start<=off+idx<sel_end) {
+ ed->window->inverse=TRUE;
+ } else
+ ed->window->inverse=FALSE;
+ SDL_AddCh(ed->window,text[idx],TRUE);
+ }
+ }
+ ed->window->inverse=FALSE;
+}
U0 Highlight(CEditor *ed,CLine *ln,Bool dryRun=FALSE,Bool recur=TRUE) {
+ I64 ln_off=GetLineOffset(ed,GetLinum(ed,ln));
+ I64 sel_start=ed->sel_start;
+ I64 sel_end=ed->sel_end;
+ if(sel_start==sel_end) goto ignoresel;
+ sel_start-=ln_off;
+ sel_end-=ln_off;
+ //Compute relative to line start
+ if(sel_start<0) sel_start=0;
+ if(sel_end<0) sel_end=0;
+ if(sel_end>RopeLength(ln->text))
+ sel_end=RopeLength(ln->text);
+ if(sel_start>sel_end) SwapI64(&sel_start,&sel_end);
+ ignoresel:
U8 *text=Rope2Str(ln->text);
+ U8 *nl=StrFirstOcc(text,"\n");
+ if(nl) *nl=0;
U8 *buf=MAlloc(StrLen(text)+1);
I64 idx=0,ns=0;
if(ln->prev) {
@@ -710,25 +901,23 @@ U0 Highlight(CEditor *ed,CLine *ln,Bool dryRun=FALSE,Bool recur=TRUE) {
while(text[idx]) {
if(0==StrNCmp(text+idx,"*/",2)) {
idx+=2;
- wattron(ed->window,COLOR_PAIR(CP_COMMENT));
+ ed->window->cur_cp=CP_COMMENT;
StrNCpy(buf,text,idx);
buf[idx]=0;
- if(!dryRun) WriteWithinView(ed,buf,0);
+ if(!dryRun) __HighlightWrite(ed,buf,0,sel_start,sel_end);
ln->flags|=ED_LNF_COMMENTED_END;
ln->flags&=~ED_LNF_COMMENTED_OUT;
goto s;
}
idx++;
}
- wattron(ed->window,COLOR_PAIR(CP_COMMENT));
- if(!dryRun) WriteWithinView(ed,text,0);
+ ed->window->cur_cp=CP_COMMENT;
+ if(!dryRun) __HighlightWrite(ed,text,0,sel_start,sel_end);
ln->flags&=~ED_LNF_COMMENTED_END;
ln->flags|=ED_LNF_COMMENTED_OUT;
}
s:
U8 *orig=text;
- U8 *nl=StrFirstOcc(text,"\n");
- if(nl) *nl=0;
loop:
ns=idx;
//Try lexing name
@@ -739,19 +928,19 @@ loop:
buf[idx-ns]=0;
CHash *kw;
if(kw=HashFind(buf,keywords)) {
- wattron(ed->window,COLOR_PAIR(CP_KW));
+ ed->window->cur_cp=CP_KW;
} else {
- wattron(ed->window,COLOR_PAIR(CP_WORD));
+ ed->window->cur_cp=CP_WORD;
}
- if(!dryRun) WriteWithinView(ed,buf,ns);
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
goto loop;
}
if(text[idx]=='/') {
if(text[idx+1]=='/') {
StrCpy(buf,text+idx);
- wattron(ed->window,COLOR_PAIR(CP_COMMENT));
- if(!dryRun) WriteWithinView(ed,text+ns,idx);
+ ed->window->cur_cp=CP_COMMENT;
+ if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
idx=StrLen(text);
goto loop;
} else if(text[idx+1]=='*') {
@@ -761,14 +950,14 @@ loop:
idx+=2;
StrNCpy(buf,text+ns,idx-ns);
buf[idx-ns]=0;
- wattron(ed->window,COLOR_PAIR(CP_COMMENT));
- if(!dryRun) WriteWithinView(ed,buf,ns);
+ ed->window->cur_cp=CP_COMMENT;
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
goto loop;
}
idx++;
}
- wattron(ed->window,COLOR_PAIR(CP_COMMENT));
- if(!dryRun) WriteWithinView(ed,text+ns,ns);
+ ed->window->cur_cp=CP_COMMENT;
+ if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
ln->flags|=ED_LNF_COMMENTED_START;
//Dry run hgihlight until we find a line end
CLine *nxtln=ln->next;
@@ -786,18 +975,18 @@ loop:
sloop:
U8 *sfind=StrFirstOcc(text+idx,sseek);
if(!sfind) {
- wattron(ed->window,COLOR_PAIR(CP_STR));
- if(!dryRun) WriteWithinView(ed,text+ns,idx);
+ ed->window->cur_cp=CP_STR;
+ if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
idx=StrLen(text);
} else if(IsEscaped(text,sfind)) {
idx=sfind-orig+1;
goto sloop;
} else {
idx=sfind-orig+1;
- wattron(ed->window,COLOR_PAIR(CP_STR));
+ ed->window->cur_cp=CP_STR;
StrNCpy(buf,text+ns,idx-ns);
buf[idx-ns]=0;
- if(!dryRun) WriteWithinView(ed,buf,ns);
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
goto loop;
}
}
@@ -808,8 +997,8 @@ sloop:
if(ns!=idx) {
StrNCpy(buf,text+ns,idx-ns);
buf[idx-ns]=0;
- wattron(ed->window,COLOR_PAIR(CP_WHITE));
- if(!dryRun) WriteWithinView(ed,buf,ns);
+ ed->window->cur_cp=CP_WHITE;
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
goto loop;
}
U8 *idx2=text+idx;
@@ -818,8 +1007,8 @@ sloop:
idx=idx2-text;
StrNCpy(buf,text+ns,idx-ns);
buf[idx-ns]=0;
- wattron(ed->window,COLOR_PAIR(CP_NUM));
- if(!dryRun) WriteWithinView(ed,buf,ns);
+ ed->window->cur_cp=CP_NUM;
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
goto loop;
}
Str2F64(idx2,&idx2);
@@ -827,15 +1016,15 @@ sloop:
idx=idx2-text;
StrNCpy(buf,text+ns,idx-ns);
buf[idx-ns]=0;
- wattron(ed->window,COLOR_PAIR(CP_NUM));
- if(!dryRun) WriteWithinView(ed,buf,ns);
+ ed->window->cur_cp=CP_NUM;
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
goto loop;
}
if(!text[idx]) goto en;
- wattron(ed->window,COLOR_PAIR(CP_TOK));
+ ed->window->cur_cp=CP_TOK;
buf[1]=0;
buf[0]=text[idx];
- if(!dryRun) WriteWithinView(ed,buf,idx);
+ if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
idx++;
goto loop;
en:
@@ -860,8 +1049,8 @@ en:
if((nxtln->flags&ED_LNF_COMMENTED_OUT)!=isCommentedOut2) break;
}
}
- wattron(ed->window,COLOR_PAIR(CP_WHITE));
- wclrtoeol(ed->window);
+ ed->window->cur_cp=CP_WHITE;
+ SDL_ClrToEOL(ed->window);
Free(buf);
}
U0 __EditorInsText(CEditor *ed,U8 *text,I64 at) {
@@ -930,6 +1119,7 @@ U0 RenumberLines(CEditor *ed,CLine *l=NULL) {
}
}
U0 EditorInsText(CEditor *ed,U8 *text,I64 at,Bool undo=FALSE) {
+ EdDelSel(ed); //Clear selection if needed
__EditorInsText(ed, text, at);
if(undo) {
CUndoInfo *prev;
@@ -953,31 +1143,32 @@ U0 EditorInsText(CEditor *ed,U8 *text,I64 at,Bool undo=FALSE) {
ret:
RenumberLines(ed);
}
+U0 SDL_InitPair(I64 idx,U_RGBA8888 fg,U_RGBA8888 bg) {
+ SDL_ColorPairs[idx].fg=fg,SDL_ColorPairs[idx].bg=bg;
+}
CEditor *EditorNew(Bool gen_rt_tags=FALSE) {
- noecho;
CEditor *r=MAlloc(sizeof(CEditor));
- start_color;
- init_pair(CP_KW,COLOR_MAGENTA,COLOR_WHITE);
- init_pair(CP_WORD,COLOR_BLUE,COLOR_WHITE);
- init_pair(CP_TOK,COLOR_GREEN,COLOR_WHITE);
- init_pair(CP_NUM,COLOR_YELLOW,COLOR_WHITE);
- init_pair(CP_STR,COLOR_RED,COLOR_WHITE);
- init_pair(CP_WHITE,COLOR_BLACK,COLOR_WHITE);
- init_pair(CP_LINUM,COLOR_WHITE,COLOR_BLUE);
- init_pair(CP_COMMENT,COLOR_CYAN,COLOR_WHITE);
- init_pair(CP_AC_SEL,COLOR_CYAN,COLOR_RED);
- init_pair(CP_AC_UNSEL,COLOR_YELLOW,COLOR_BLUE);
- init_pair(CP_MENU_SEL,COLOR_YELLOW,COLOR_RED);
- init_pair(CP_MENU_UNSEL,COLOR_WHITE,COLOR_BLUE);
- init_pair(CP_FUZZY_SEL_A,COLOR_BLACK,COLOR_YELLOW);
- init_pair(CP_FUZZY_UNSEL_A,COLOR_BLACK,COLOR_WHITE);
- init_pair(CP_FUZZY_SEL_B,COLOR_RED,COLOR_YELLOW);
- init_pair(CP_FUZZY_UNSEL_B,COLOR_RED,COLOR_WHITE);
- init_pair(CP_LINUM_ERR,COLOR_WHITE,COLOR_RED);
- init_pair(CP_LINUM_WARN,COLOR_WHITE,COLOR_YELLOW);
- r->w=getmaxx(stdscr);
- r->window=newwin(getmaxy(stdscr),r->w,0,0);
- wbkgdset(r->window,COLOR_PAIR(CP_WHITE));
+ SDL_InitPair(CP_KW,SOL_MAGENTA,SOL_WHITE);
+ SDL_InitPair(CP_WORD,SOL_BLUE,SOL_WHITE);
+ SDL_InitPair(CP_TOK,SOL_GREEN,SOL_WHITE);
+ SDL_InitPair(CP_NUM,SOL_YELLOW,SOL_WHITE);
+ SDL_InitPair(CP_STR,SOL_RED,SOL_WHITE);
+ SDL_InitPair(CP_WHITE,SOL_BLACK,SOL_WHITE);
+ SDL_InitPair(CP_LINUM,SOL_WHITE,SOL_BLUE);
+ SDL_InitPair(CP_COMMENT,SOL_CYAN,SOL_WHITE);
+ SDL_InitPair(CP_AC_SEL,SOL_CYAN,SOL_RED);
+ SDL_InitPair(CP_AC_UNSEL,SOL_YELLOW,SOL_BLUE);
+ SDL_InitPair(CP_MENU_SEL,SOL_YELLOW,SOL_RED);
+ SDL_InitPair(CP_MENU_UNSEL,SOL_WHITE,SOL_BLUE);
+ SDL_InitPair(CP_FUZZY_SEL_A,SOL_BLACK,SOL_YELLOW);
+ SDL_InitPair(CP_FUZZY_UNSEL_A,SOL_BLACK,SOL_WHITE);
+ SDL_InitPair(CP_FUZZY_SEL_B,SOL_RED,SOL_YELLOW);
+ SDL_InitPair(CP_FUZZY_UNSEL_B,SOL_RED,SOL_WHITE);
+ SDL_InitPair(CP_LINUM_ERR,SOL_WHITE,SOL_RED);
+ SDL_InitPair(CP_LINUM_WARN,SOL_WHITE,SOL_YELLOW);
+ I32 x,y;
+ SDL_GetWindowSize(global_window,&x,&y);
+ r->window=SDL_NewTextWin(x/FONT_X2,y/FONT_Y2);
r->vp_start_line=0;
r->line_cache=MAlloc(sizeof(CLine*));
r->line_cache_size=0;
@@ -1086,6 +1277,13 @@ merge:
FreeLine(end_ln);
ed->line_count--;
}
+ //All lines must end in newline.
+ if(RopeLength(start_ln->text)==0) {
+ addnl:
+ start_ln->text=RopeAppendText(start_ln->text,"\n");
+ } else if(RopeChar(start_ln->text,RopeLength(start_ln->text)-1)!='\n'){
+ goto addnl;
+ }
}
U8 *EdTextSlice(CEditor *ed,I64 soff,I64 eoff) {
U8 *ret=MAlloc(eoff-soff+1);
@@ -1111,6 +1309,7 @@ U8 *EdTextSlice(CEditor *ed,I64 soff,I64 eoff) {
goto sloop;
}
eloop:
+ if(!ln) goto en;
text=Rope2Str(ln->text);
if(off<=eoff<off+RopeLength(ln->text)) {
StrNCpy(retptr,text,eoff-off);
@@ -1124,6 +1323,7 @@ U8 *EdTextSlice(CEditor *ed,I64 soff,I64 eoff) {
Free(text);
goto eloop;
}
+ en:
return ret;
}
U0 EditorDelText(CEditor *ed,I64 soff,I64 eoff,Bool undo=FALSE) {
@@ -1156,7 +1356,10 @@ U0 EdJumpToChar(CEditor *ed,I64 chr) {
CLine *ln=ed->lines;
I64 off=0;
loop:
- if(!ln) return;
+ if(!ln) {
+ ed->curx=ed->cury=0;
+ return;
+ }
I64 len;
if(off<=chr<off+(len=RopeLength(ln->text))) {
ed->cury=GetLinum(ed, ln);
@@ -1200,15 +1403,16 @@ U0 Redo(CEditor *ed) {
U0 DrawLinumWithPad(CEditor *ed,I64 num,I64 barwidth) {
U8 *lnumtxt=MStrPrint("%d: ",num);
I64 lnumlen=StrLen(lnumtxt);
- wprint(ed->window,lnumtxt);
+ SDL_Print(ed->window,lnumtxt);
Free(lnumtxt);
- while(barwidth>lnumlen++) waddch(ed->window,' ');
+ while(barwidth>lnumlen++) SDL_AddCh(ed->window,' ');
}
#define ED_DRAW_LINUMS 1
#define ED_DRAW_SEARCH 2
#define ED_DRAW_DIALOG 4
#define ED_DRAW_MENUBAR 8
#define ED_DRAW_DFT (ED_DRAW_LINUMS|ED_DRAW_MENUBAR)
+#define ED_DRAW_NO_RENDER 16
U0 AddMenuBar(CEditor *ed,I64 active=-1);
I64 DrawEditor(CEditor *ed,I64 flags=0,U8 *dialogtxt=NULL,I64 mb_active=-1) {
curs_set(0);
@@ -1230,18 +1434,18 @@ I64 DrawEditor(CEditor *ed,I64 flags=0,U8 *dialogtxt=NULL,I64 mb_active=-1) {
I64 lnumlen=StrLen(lnumtxt);
Free(lnumtxt);
} else if(flags&ED_DRAW_SEARCH) {
- wattron(ed->window,COLOR_PAIR(CP_LINUM));
+ ed->window->cur_cp=CP_LINUM;
lnumtxt=MStrPrint("Search: ");
lnumlen=StrLen(lnumtxt);
- wmove(ed->window,0,0);
- wprint(ed->window,lnumtxt);
+ ed->window->y=ed->window->x=0;
+ SDL_Print(ed->window,lnumtxt);
Free(lnumtxt);
} else if(flags&ED_DRAW_DIALOG) {
- wattron(ed->window,COLOR_PAIR(CP_LINUM));
+ ed->window->cur_cp=CP_LINUM;
lnumtxt=MStrPrint("%s: ",dialogtxt);
lnumlen=StrLen(lnumtxt);
- wmove(ed->window,0,0);
- wprint(ed->window,lnumtxt);
+ ed->window->y=ed->window->x=0;
+ SDL_Print(ed->window,lnumtxt);
Free(lnumtxt);
} else
lnumlen=0;
@@ -1253,48 +1457,50 @@ I64 DrawEditor(CEditor *ed,I64 flags=0,U8 *dialogtxt=NULL,I64 mb_active=-1) {
if(ln->line==ed->vp_start_line) break;
ln=ln->next;
}
- I64 cnt=getmaxy(ed->window),line=ed->vp_start_line+1,screen_line=ed->margin_top;
+ I64 cnt=SDL_WinY(ed->window),line=ed->vp_start_line+1,screen_line=ed->margin_top;
cnt-=(ed->margin_top+ed->margin_bottom);
while(--cnt>=0&&ln) {
if(flags&ED_DRAW_LINUMS) {
- wmove(ed->window,screen_line,0);
- I64 cp=COLOR_PAIR(CP_LINUM);
+ ed->window->y=screen_line,ed->window->x=0;
+ I64 cp=CP_LINUM;
if(ln->flags&ED_LNF_ERR) {
- cp=COLOR_PAIR(CP_LINUM_ERR);
+ cp=CP_LINUM_ERR;
} else if(ln->flags&ED_LNF_WARN) {
- cp=COLOR_PAIR(CP_LINUM_WARN);
+ cp=CP_LINUM_WARN;
}
- wattron(ed->window,cp);
+ ed->window->cur_cp=cp;
DrawLinumWithPad(ed,line++,lnumlen);
}
if(1) {
- wmove(ed->window,screen_line,lnumlen);
+ ed->window->y=screen_line,ed->window->x=lnumlen;
Highlight(ed,ln,,TRUE);
}
++screen_line;
ln=ln->next;
}
+ U8 *pad=MStrPrint("%*c",lnumlen,' ');
while(cnt>=0) {
- wattron(ed->window,COLOR_PAIR(CP_LINUM));
- wmove(ed->window,screen_line,0);
- wprint(ed->window,"%*c",lnumlen,' ');
- wattron(ed->window,COLOR_PAIR(CP_WHITE));
- wmove(ed->window,screen_line++,lnumlen);
- wclrtoeol(ed->window);
+ ed->window->cur_cp=CP_LINUM;
+ ed->window->y=screen_line,ed->window->x=0;
+ SDL_Print(ed->window,pad);
+ ed->window->cur_cp=CP_WHITE;
+ ed->window->y=screen_line++,ed->window->x=lnumlen;
+ SDL_ClrToEOL(ed->window);
cnt--;
}
if(diagln) {
- wmove(ed->window,getmaxy(ed->window)-1,0);
- if(diagln->flags&ED_LNF_ERR) wattron(ed->window,COLOR_PAIR(CP_LINUM_ERR));
- else if(diagln->flags&ED_LNF_WARN) wattron(ed->window,COLOR_PAIR(CP_LINUM_WARN));
+ ed->window->y=SDL_WinY(ed->window)-1,ed->window->x=0;
+ if(diagln->flags&ED_LNF_ERR) ed->window->cur_cp=CP_LINUM_ERR;
+ else if(diagln->flags&ED_LNF_WARN) ed->window->cur_cp=CP_LINUM_WARN;
else throw('InvDiag');
- wprint(ed->window,"%s",diagln->diag->msg);
- wclrtoeol(ed->window);
- }
- wmove(ed->window,ed->cury-ed->vp_start_line+ed->margin_top,lnumlen+ed->curx-ed->x_scroll);
- curs_set(2);
- wrefresh(ed->window);
- ed->w=getmaxx(ed->window);
+ SDL_Print(ed->window,diagln->diag->msg);
+ SDL_ClrToEOL(ed->window);
+ }
+ ed->window->cur_enabled=TRUE;
+ ed->window->curx=lnumlen+ed->curx-ed->x_scroll;
+ ed->window->cury=ed->cury-ed->vp_start_line+ed->margin_top;
+ if(flags&ED_DRAW_NO_RENDER);
+ else SDL_DrawWin(ed->window);
return ED_RET_OK;
}
U0 EdUp(CEditor *ed) {
@@ -1465,7 +1671,7 @@ U0 EdBackspace(CEditor *ed) {
U0 EdPageDown(CEditor *ed) {
//Check if there is enough room for a page down
CLine *lline=GetLine(ed,ed->cury);
- I64 cnt=getmaxy(ed->window),cnt2=0;
+ I64 cnt=SDL_WinY(ed->window),cnt2=0;
while(lline&&--cnt>=0) {
lline=lline->next;
cnt2++;
@@ -1477,7 +1683,7 @@ U0 EdPageDown(CEditor *ed) {
if(RopeLength(lline->text)>=ed->_curx) ed->curx=RopeLength(lline->text);
}
U0 EdPageUp(CEditor *ed) {
- ed->vp_start_line-=getmaxy(ed->window);
+ ed->vp_start_line-=SDL_WinY(ed->window);
ed->vp_start_line=MaxI64(ed->vp_start_line,0);
CLine *lline=GetLine(ed,ed->vp_start_line);
ed->cury=ed->vp_start_line;
@@ -1489,24 +1695,14 @@ I64 EdSearch(CEditor *ed) {
CEditor *sed=EditorNew();
goto resize;
loop:
- I64 key=GetKey(sed->window);
+ I64 key=GetKey;
switch(key) {
case ERR:
goto loop;
case ED_KEY_RESIZE:
resize:
- I64 h=getmaxy(stdscr);
- I64 w=getmaxx(stdscr);
- I64 x=getbegx(stdscr);
- I64 y=getbegy(stdscr);
- if(h>=1) {
- wresize(sed->window,1,w);
- mvwin(sed->window,y+h-1,x);
- } else {
- wresize(sed->window,h,w);
- mvwin(sed->window,y,x);
- }
- redrawwin(sed->window);
+ SDL_DrawWin(ed->window);
+ sed->window->begy=SDL_WinY(ed->window)-1;
goto mvsrncur;
case ED_KEY_CTRL_UP:
case ED_KEY_UP: //TODO
@@ -1520,6 +1716,7 @@ resize:
case ED_KEY_LEFT:
EdLeft(sed);
goto mvsrncur;
+ case ED_KEY_REDRAW: goto mvsrncur;
case ED_KEY_CTRL_LEFT:
left:
EdWordLeft(sed);
@@ -1579,21 +1776,23 @@ fail:
EditorInsText(sed,buffer,soff,TRUE);
}
mvsrncur:
- DrawEditor(ed,ED_DRAW_DFT);
- DrawEditor(sed,ED_DRAW_SEARCH);
+ DrawEditor(ed,ED_DRAW_DFT|ED_DRAW_NO_RENDER);
+ sed->window->y=SDL_WinY(ed->window)-1;
+ DrawEditor(sed,ED_DRAW_SEARCH|ED_DRAW_NO_RENDER);
+ SDL_DrawWin(ed.window,sed.window);
goto loop;
en:
- redrawwin(ed->window);
+ DrawEditor(ed);
FreeEditor(sed);
}
I64 Edit(CEditor *ed);
//interactive tells us to enter the autcomplete
Bool DrawAutocomplete(CEditor *parent,Bool interactive=FALSE) {
Bool ret=FALSE;
- I64 wx1=getbegx(parent->window);
- I64 wy1=getbegy(parent->window);
- I64 sw=getmaxx(parent->window);
- I64 sh=getmaxy(parent->window);
+ I64 wx1=0;
+ I64 wy1=0;
+ I64 sw=SDL_WinX(parent->window);
+ I64 sh=SDL_WinY(parent->window);
CLine *ln=GetLine(parent, parent->cury);
U8 *text=Rope2Str(ln->text);
I64 idx=parent->curx;
@@ -1625,29 +1824,30 @@ loop:
if(!cnt) goto free;
I64 maxlen=StrLen(ents[cnt-1]->fullname); //Ents are sorted by length
if(screenx+1<sw&&screeny+1<sh) {
- WINDOW *ac=newwin(MinI64(cnt,sh-screeny-wy1-1),MinI64(maxlen,sw-screenx-wx1),screeny+1,screenx);
+ CSDL_TextWin *ac=SDL_NewTextWin(MinI64(maxlen,sw-screenx-wx1),MinI64(cnt,sh-screeny-wy1));
+ ac->begx=screenx+1,ac->begy=screeny+1;
I64 iter=0;
for(; iter<cnt; iter++) {
len=StrLen(ents[iter]->fullname);
I64 chr=0;
if(iter==active)
- wattron(ac,COLOR_PAIR(CP_AC_SEL));
+ ac->cur_cp=CP_AC_SEL;
else
- wattron(ac,COLOR_PAIR(CP_AC_UNSEL));
- wmove(ac,iter,0);
- I64 cap=getmaxx(ac);
+ ac->cur_cp=CP_AC_UNSEL;
+ ac->y=iter,ac->x=0;
+ I64 cap=SDL_WinX(ac);
WriteWithinWin(ac,ents[iter]->fullname);
while(len++<cap) {
- waddch(ac,' ');
+ SDL_AddCh(ac,' ');
}
}
- DrawEditor(parent, ED_DRAW_DFT);
- wrefresh(ac);
- delwin(ac);
+ DrawEditor(parent, ED_DRAW_DFT|ED_DRAW_NO_RENDER);
+ SDL_DrawWin(parent->window, ac);
+ SDL_DestroyTextWin(ac);
}
if(interactive) {
winput:
- I64 key=GetKey(parent->window);
+ I64 key=GetKey();
switch(key) {
case ERR:
goto winput;
@@ -1672,7 +1872,7 @@ free:
Free(ents),Free(sub);
fin:
Free(text);
- redrawwin(parent->window);
+ SDL_DrawWin(parent->window);
return ret;
}
class CMenuEnt {
@@ -1736,29 +1936,26 @@ I64 SaveDoc(CEditor *ed) {
if(!ed->fn) {
SaveDocAs(ed);
} else {
- WINDOW *msgs=newwin(getmaxy(stdscr),getmaxx(stdscr),0,0);
- wbkgdset(msgs,COLOR_PAIR(CP_WHITE));
- wclear(msgs);
- wprint(msgs,"SAVING FILE %s\n",ed->fn);
- wrefresh(msgs);
+ CSDL_TextWin *msgs=SDL_NewTextWin(SDL_WinX(ed->window),SDL_WinY(ed->window));
+ SDL_Print(msgs,"SAVING FILE\n");
+ SDL_DrawWin(msgs);
U8 *etxt=Editor2Str(ed,&cnt);
FileWrite(ed->fn,etxt,cnt);
Free(etxt);
FreeTrie(ed->tags);
FreeDiags(ed->diags);
- wprint(msgs,"Generating tags and diagnostics.\n");
- wrefresh(msgs);
+ SDL_Print(msgs,"Generating tags and diagnostics.\n");
+ SDL_DrawWin(msgs);
CreateTagsAndErrorsFiles("TAGS","ERRS",ed->fn);
- wprint(msgs,"Parsing Tags.\n");
- wrefresh(msgs);
+ SDL_Print(msgs,"Parsing Tags.\n");
+ SDL_DrawWin(msgs);
ed->tags=ReadTags("TAGS");
ed->diags=ParseDiags("ERRS");
- wprint(msgs,"Garbage collecting.\n");
- wrefresh(msgs);
+ SDL_Print(msgs,"Garbage collecting.\n");
+ SDL_DrawWin(msgs);
GC_Collect();
MarkLineColors(ed);
- redrawwin(ed->window);
- flushinp;
+ SDL_DrawWin(ed->window);
}
return ED_RET_OK;
}
@@ -1780,10 +1977,10 @@ I64 OpenDoc(CEditor *ed) {
}
return ED_RET_OK;
}
-U0 DrawMenuDropdown(CMenuEnt *ent,I64 off,I64 active=-1) {
- I64 x=getbegx(stdscr);
- I64 he=getmaxy(stdscr);
- I64 w=getmaxx(stdscr);
+U0 DrawMenuDropdown(CEditor *ed,CMenuEnt *ent,I64 off,I64 active=-1) {
+ I64 x=0;
+ I64 he=SDL_WinY(ed->window);
+ I64 w=SDL_WinX(ed->window);
I64 mwidth=0;
I64 h=0;
while(ent[h].name) {
@@ -1791,20 +1988,40 @@ U0 DrawMenuDropdown(CMenuEnt *ent,I64 off,I64 active=-1) {
h++;
}
if(!h) return;
- WINDOW *win=newwin(MinI64(h, he-1),MinI64(mwidth,w),1,off);
+ CSDL_TextWin *win=SDL_NewTextWin(MinI64(mwidth,w-off),MinI64(h, he-1));
+ win->begy=1;
+ win->begx=off;
I64 i;
for(i=0; i!=h; i++) {
- if(active==i) wattron(win,COLOR_PAIR(CP_AC_SEL));
- else wattron(win,COLOR_PAIR(CP_AC_UNSEL));
- wmove(win,i,0);
- wprint(win,ent[i].name);
+ if(active==i) win->cur_cp=CP_AC_SEL;
+ else win->cur_cp=CP_AC_UNSEL;
+ win->y=i,win->x=0;
+ SDL_Print(win,ent[i].name);
I64 len=StrLen(ent[i].name);
- while(len++<mwidth) waddch(win,' ');
+ while(len++<mwidth) SDL_AddCh(win,' ');
}
- wrefresh(win);
- delwin(win);
+ DrawEditor(ed,ED_DRAW_DFT|ED_DRAW_NO_RENDER);
+ SDL_DrawWin(ed->window,win);
+ SDL_DestroyTextWin(win);
}
I64 BufferSelect(CEditor *ed);
+U0 EdCopy(CEditor *ed) {
+ U8 *clip=EdGetSelText(ed);
+ SDL_SetClipboardText(clip);
+ Free(clip);
+ ed->sel_start=ed->sel_end=-1;
+}
+U0 EdPaste(CEditor *ed) {
+ U8 *clip=SDL_GetClipboardText;
+ EditorInsText(ed,clip,GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
+ Free(clip);
+}
+U0 EdCut(CEditor *ed) {
+ U8 *clip=EdGetSelText(ed);
+ SDL_SetClipboardText(clip);
+ EdDelSel(ed);
+ Free(clip);
+}
//Draws at first line
U0 AddMenuBar(CEditor *ed,I64 active=-1) {
I64 ret=ED_RET_OK;
@@ -1816,6 +2033,12 @@ U0 AddMenuBar(CEditor *ed,I64 active=-1) {
{"[B]uffer Select",'b',&BufferSelect},
{NULL,0,NULL},
};
+ CMenuEnt Edit[]={
+ {"[C]opy",'c',&EdCopy},
+ {"Cu[t]",'t',&EdCut},
+ {"[P]aste",'p',&EdPaste},
+ {NULL,0,NULL},
+ };
CMenuEnt Code[]= {
{"[G]oto Symbol",'g',&GotoSymbol},
{"[C]ompile Check",'c',&ShowDiagsWindow},
@@ -1830,12 +2053,13 @@ U0 AddMenuBar(CEditor *ed,I64 active=-1) {
U8 key;
} cats[]= {
{&File,"[F]ile",'f'},
+ {&Edit,"[E]dit",'e'},
{&Code,"[C]ode",'c'},
};
I64 cnt=sizeof(cats)/sizeof(*cats),cur,active_sub=0;
goto draw;
loop:
- I64 key=GetKey(ed->window);
+ I64 key=GetKey();
switch(key) {
case ERR: goto loop;
case ED_KEY_ESCAPE: goto en;
@@ -1851,6 +2075,7 @@ loop:
case ED_KEY_RIGHT:
active=MinI64(cnt-1,++active),active_sub=0;
break;
+ case ED_KEY_REDRAW: goto draw;
case '\n':
if(cats[active].spec[active_sub].callback)
ret=(cats[active].spec[active_sub].callback[0])(ed);
@@ -1866,25 +2091,24 @@ loop:
}
}
draw:
- wmove(ed->window,0,0);
+ ed->window->x=ed->window->y=0;
I64 off=0,sel_off=-1;
for(cur=0; cur!=cnt; cur++) {
if(cur==active) {
- wattron(ed->window,COLOR_PAIR(CP_MENU_SEL));
+ ed->window->cur_cp=CP_MENU_SEL;
sel_off=cur;
} else
- wattron(ed->window,COLOR_PAIR(CP_MENU_UNSEL));
- wprint(ed->window,cats[cur].name);
+ ed->window->cur_cp=CP_MENU_UNSEL;
+ SDL_Print(ed->window,cats[cur].name);
if(cur>=active)
; //Do Nothing
else
off+=StrLen(cats[cur].name);
}
- wclrtoeol(ed->window);
+ SDL_ClrToEOL(ed->window);
if(sel_off!=-1) {
- redrawwin(ed->window);
DrawEditor(ed, ED_DRAW_DFT&(~ED_DRAW_MENUBAR));
- if(DrawMenuDropdown(cats[active].spec, off,active_sub)==ED_RET_QUIT) return ED_RET_QUIT;
+ if(DrawMenuDropdown(ed,cats[active].spec, off,active_sub)==ED_RET_QUIT) return ED_RET_QUIT;
}
if(active!=-1)
goto loop;
@@ -1898,7 +2122,7 @@ U0 FreeEditor(CEditor *ed) {
FreeLine(ln);
ln=n;
}
- delwin(ed->window);
+ SDL_DestroyTextWin(ed->window);
Free(ed->dirty_screen_lines);
Free(ed->line_cache);
if(ed->tags) FreeTrie(ed->tags);
@@ -1930,7 +2154,7 @@ U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *
matches=(*match_cb)(parent,init);
goto draw;
loop:
- I64 key=GetKey(ed->window);
+ I64 key=GetKey();
switch(key) {
case ERR: goto loop;
case ED_KEY_ESCAPE:
@@ -1943,7 +2167,7 @@ U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *
goto draw;
case ED_KEY_DOWN:
if(active==-1) {active=0; goto draw;}
- if(active>=getmaxy(ed->window)-1) goto loop;
+ if(active>=SDL_WinY(ed->window)-1) goto loop;
if(!matches[active]) goto loop;
if(!matches[active+1]) goto loop;
active++;
@@ -1961,6 +2185,7 @@ U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *
case ED_KEY_BACKSPACE:
EdBackspace(ed);
goto update;
+ case ED_KEY_REDRAW: goto draw;
case ED_KEY_RIGHT:
right:
EdRight(ed);
@@ -1976,7 +2201,7 @@ U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *
}
Free(matches);
parent->margin_bottom=0;
- redrawwin(parent->window);
+ SDL_DrawWin(parent->window);
return ret;
default:
U8 buffer[]={key,0};
@@ -1995,25 +2220,25 @@ U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *
draw:
FocusCursor(ed);
if(active==-1)
- wattron(ed->window,COLOR_PAIR(CP_FUZZY_SEL_A));
+ ed->window->cur_cp=CP_FUZZY_SEL_A;
else
- wattron(ed->window,COLOR_PAIR(CP_FUZZY_UNSEL_A));
+ ed->window->cur_cp=CP_FUZZY_UNSEL_A;
t=RemoveNL(Rope2Str(ed->lines->text));
- wmove(ed->window,0,0);
- wclrtoeol(ed->window);
+ ed->window->y=ed->window->x=0;
+ SDL_ClrToEOL(ed->window);
WriteWithinView(ed,t, 0);
idx=1;
- for(;idx<getmaxy(ed->window);idx++) {
+ for(;idx<SDL_WinY(ed->window);idx++) {
if(!matches[idx-1]) break;
U8 *mat=matches[idx-1];
U8 *tc=t;
I64 offset=0;
- wmove(ed->window,idx,0);
+ ed->window->y=idx,ed->window->x=0;
hl:
if(active==idx-1)
- wattron(ed->window,COLOR_PAIR(CP_FUZZY_SEL_A));
+ ed->window->cur_cp=CP_FUZZY_SEL_A;
else
- wattron(ed->window,COLOR_PAIR(CP_FUZZY_UNSEL_A));
+ ed->window->cur_cp=CP_FUZZY_UNSEL_A;
U8 buffer2[]={*(tc++),0};
U8 *chr=StrFirstOcc(mat,buffer2);
if(!chr) {
@@ -2026,22 +2251,23 @@ U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *
offset+=StrLen(slice);
Free(slice);
if(active==idx-1)
- wattron(ed->window,COLOR_PAIR(CP_FUZZY_SEL_B));
+ ed->window->cur_cp=CP_FUZZY_SEL_B;
else
- wattron(ed->window,COLOR_PAIR(CP_FUZZY_UNSEL_B));
+ ed->window->cur_cp=CP_FUZZY_UNSEL_B;
WriteWithinView(ed,buffer2, offset++);
mat++;
}
if(*mat) goto hl;
- wclrtoeol(ed->window);
+ SDL_ClrToEOL(ed->window);
}
- for(;idx<getmaxy(ed->window);idx++) {
- wmove(ed->window,idx,0);
- wclrtoeol(ed->window);
+ for(;idx<SDL_WinY(ed->window);idx++) {
+ ed->window->y=idx,ed->window.x=0;
+ SDL_ClrToEOL(ed->window);
}
-
- wmove(ed->window,0,ed->curx-ed->x_scroll);
- redrawwin(ed->window);
+ ed->window->cury=0,ed->window->curx=ed->curx-ed->x_scroll;
+ ed->window->cur_enabled=TRUE;
+ SDL_DrawWin(ed->window);
+ ed->window->cur_enabled=FALSE;
Free(t);
goto loop;
}
@@ -2177,10 +2403,78 @@ I64 BufferSelect(CEditor *ed) {
}
return ED_RET_OK;
}
+I64 EdOffset(CEditor *ed) {
+ return GetLineOffset(ed,ed->cury)+ed->curx;
+}
+I64 EdClearSelect(CEditor *ed) {
+ ed->sel_start=ed->sel_end;
+}
+I64 EdSelLeft(CEditor *ed) {
+ Bool in_select=ed->sel_start!=ed->sel_end;
+ if(!in_select) ed->sel_start=EdOffset(ed);
+ EdLeft(ed);
+ ed->sel_end=EdOffset(ed);
+}
+I64 EdSelRight(CEditor *ed) {
+ Bool in_select=ed->sel_start!=ed->sel_end;
+ if(!in_select) ed->sel_start=EdOffset(ed);
+ EdRight(ed);
+ ed->sel_end=EdOffset(ed);
+}
+I64 EdSelUp(CEditor *ed) {
+ Bool in_select=ed->sel_start!=ed->sel_end;
+ if(!in_select) ed->sel_start=EdOffset(ed);
+ EdUp(ed);
+ ed->sel_end=EdOffset(ed);
+}
+I64 EdSelDown(CEditor *ed) {
+ Bool in_select=ed->sel_start!=ed->sel_end;
+ if(!in_select) ed->sel_start=EdOffset(ed);
+ EdDown(ed);
+ ed->sel_end=EdOffset(ed);
+}
+U0 EdDelSel(CEditor *ed) {
+ Bool in_select=ed->sel_start!=ed->sel_end;
+ if(!in_select) return;
+ if(ed->sel_start>ed->sel_end) SwapI64(&ed->sel_end,&ed->sel_start);
+ EditorDelText(ed,ed->sel_start,ed->sel_end,TRUE);
+ EdJumpToChar(ed,ed->sel_start);
+ ed->sel_start=ed->sel_end=-1;
+}
+U8 *EdGetSelText(CEditor *ed) {
+ Bool in_select=ed->sel_start!=ed->sel_end;
+ if(!in_select) return NULL;
+ if(ed->sel_start>ed->sel_end) {
+ SwapI64(&ed->sel_end,&ed->sel_start);
+ }
+ U8 *ret=MAlloc(ed->sel_end-ed->sel_start+1);
+ I64 cnt=GetLineCount(ed),idx=0;
+ I64 offset=0,reti=0;
+ for(;idx!=cnt;idx++) {
+ offset=GetLineOffset(ed,idx);
+ CRope *text;
+ I64 en=RopeLength(text=GetLine(ed,idx)->text);
+ {
+ I64 st=MaxI64(ed->sel_start-offset,0);
+ en=MinI64(en,ed->sel_end-offset);
+ if(st>en) goto next;
+ U8 *lntxt=Rope2Str(text);
+ StrNCpy(ret+reti,lntxt+st,en-st);
+ Free(lntxt);
+ reti+=en-st;
+ if(reti>=ed->sel_end-ed->sel_start) {
+ goto ret;
+ }
+ next:
+ }
+ }
+ ret:
+ return ret;
+}
I64 Edit(CEditor *ed) {
goto mvsrncur;
loop:
- I64 key=GetKey(ed->window),cnt,cnt2;
+ I64 key=GetKey,cnt,cnt2;
if(key==ERR) goto loop;
I64 eoff,soff;
switch(key) {
@@ -2192,56 +2486,96 @@ loop:
* [F]ile
* [C]ode
*/
+ case 'x'&0x1f:
+ U8 *clip=EdGetSelText(ed);
+ EdDelSel(ed);
+ SDL_SetClipboardText(clip);
+ Free(clip);
+ goto mvsrncur;
+ case 'c'&0x1f:
+ clip=EdGetSelText(ed);
+ SDL_SetClipboardText(clip);
+ EdClearSelect(ed);
+ goto mvsrncur;
+ case 'v'&0x1f:
+ EdDelSel(ed);
+ clip=SDL_GetClipboardText();
+ EditorInsText(ed,clip,GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
+ I64 righti=StrLen(clip);
+ Free(clip);
+ while(--righti>=0) EdRight(ed);
+ goto mvsrncur;
+ case ED_KEY_SHIFT_UP:
+ EdSelUp(ed);
+ goto mvsrncur;
+ case ED_KEY_SHIFT_DOWN:
+ EdSelDown(ed);
+ goto mvsrncur;
+ case ED_KEY_SHIFT_LEFT:
+ EdSelLeft(ed);
+ goto mvsrncur;
+ case ED_KEY_SHIFT_RIGHT:
+ EdSelRight(ed);
+ goto mvsrncur;
case ED_KEY_ESCAPE:
case ALT_KEY('f'):
if(DrawEditor(ed,ED_DRAW_DFT,,0)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
goto mvsrncur;
+ case ALT_KEY('e'):
+ if(DrawEditor(ed,ED_DRAW_DFT,,1)==ED_RET_QUIT) return ED_RET_QUIT;
+ goto mvsrncur;
case ALT_KEY('c'):
- if(DrawEditor(ed,ED_DRAW_DFT,,1)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
+ if(DrawEditor(ed,ED_DRAW_DFT,,2)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
goto mvsrncur;
-
case ED_KEY_RESIZE:
- I64 h=getmaxy(stdscr);
- I64 w=getmaxx(stdscr);
- I64 x=getbegx(stdscr);
- I64 y=getbegy(stdscr);
- mvwin(ed->window,0,0);
- wresize(ed->window,h,w);
- redrawwin(ed->window);
goto mvsrncur;
case ED_KEY_UP:
+ EdClearSelect(ed);
EdUp(ed);
goto mvsrncur;
case ED_KEY_DOWN:
+ EdClearSelect(ed);
EdDown(ed);
goto mvsrncur;
+ case ED_KEY_REDRAW: goto mvsrncur;
case ED_KEY_LEFT:
left:
+ EdClearSelect(ed);
EdLeft(ed);
goto mvsrncur;
case ED_KEY_RIGHT:
right:
+ EdClearSelect(ed);
EdRight(ed);
goto mvsrncur;
case ED_KEY_END:
+ EdClearSelect(ed);
ed->_curx=ed->curx=0;
goto mvsrncur;
case ED_KEY_HOME:
+ EdClearSelect(ed);
CLine *heline=GetLine(ed,ed->cury);
ed->_curx=ed->curx=RopeLength(heline->text);
goto mvsrncur;
case ED_KEY_CTRL_UP:
+ EdClearSelect(ed);
goto pageup;
case ED_KEY_CTRL_DOWN:
+ EdClearSelect(ed);
goto pagedown;
case ED_KEY_CTRL_LEFT:
+ EdClearSelect(ed);
EdWordLeft(ed);
goto mvsrncur;
case ED_KEY_CTRL_RIGHT:
+ EdClearSelect(ed);
EdWordRight(ed);
goto mvsrncur;
case ED_KEY_BACKSPACE:
- EdBackspace(ed);
+ if(ed->sel_start!=ed->sel_end)
+ EdDelSel(ed);
+ else
+ EdBackspace(ed);
goto mvsrncur;
case ED_KEY_PAGEUP:
pageup:
@@ -2265,19 +2599,19 @@ pagedown:
goto mvsrncur;
case 'b'&0x1f:
BufferSelect(ed);
- redrawwin(ed->window);
+ SDL_DrawWin(ed->window);
goto mvsrncur;
case 't'&0x1f:
GotoSymbol(ed);
- redrawwin(ed->window);
+ SDL_DrawWin(ed->window);
goto mvsrncur;
case 'o'&0x1f:
OpenDoc(ed);
- redrawwin(ed->window);
+ SDL_DrawWin(ed->window);
goto mvsrncur;
case 's'&0x1f:
SaveDoc(ed);
- redrawwin(ed->window);
+ SDL_DrawWin(ed->window);
goto mvsrncur;
default:
if(key==('q'&0x1f)) {return ED_RET_QUIT;}
@@ -2317,10 +2651,20 @@ EditorDelText(ed,1,2);
EditorDelText(ed,1,15-1);
DrawEditor(ed);
*/
-initscr;
+SDL_InitScr;
CEditor *ed=EditorNew(TRUE);
Edit(ed);
-endwin;
+U0 FreeBuffer(U0 *buf) {
+ FreeEditor(buf(CBuffer*)->ed);
+}
+U0 SDL_ExitScr() {
+ SDL_DestroyWindow(global_window);
+ SDL_FreeSurface(global_font);
+ global_window=NULL,global_font=NULL;
+ SDL_StopTextInput;
+ HashTableDel(buffers,(&FreeBuffer)(U0*));
+}
+SDL_ExitScr;
diff --git a/HolyEd/EDITOR2.HC b/HolyEd/EDITOR2.HC
deleted file mode 100644
index a9c77db..0000000
--- a/HolyEd/EDITOR2.HC
+++ /dev/null
@@ -1,2641 +0,0 @@
-#include "KEYS2.HC"
-#include "ROPE.HC"
-#include "FONT.HC"
-#define EDIT_UNUSED 0
-#define EDIT_INS_STR 3
-#define EDIT_DEL_STR 4
-class CUndoInfo {
- I64 type;
- I64 at;
- union {
- U8 inserted_char;
- U8 removed_char;
- U8* inserted_str;
- U8* removed_str;
- };
-};
-#define UNDO_INFO_LENGTH 512
-#define TAG_MACRO 1
-#define TAG_UNION 2
-#define TAG_CLASS 3
-#define TAG_VAR 4
-#define TAG_FUNC 5
-CHashTable *TagFiles=HashTableNew(1<<7);
-class CTrie {
- CTrie *ents[26+10+1+1]; //a...z/0-9/_/.
- U8 *fn; //From TagFiles
- U8 *fullname;
- U8 * name;
- I64 ln;
- U8 kind;
-};
-I64 TrieChrIdx(U8 chr) {
- I64 idx;
- switch(chr) {
- case '0'...'9':
- idx=26+chr-'0';
- break;
- case 'a'...'z':
- idx=chr-'a';
- break;
- case 'A'...'Z':
- idx=chr-'A';
- break;
- case '_':
- idx=26+10;
- break;
- case '.':
- idx=26+10+1;
- break;
- default:
- idx=-1;
- }
- return idx;
-}
-CTrie *TrieIns(CTrie *t,U8 *name,CTrie * child) {
- if(!*name) {
- t->name=StrNew(child->name);
- t->fullname=child->fullname;
- t->fn=child->fn;
- t->ln=child->ln;
- t->kind=child->kind;
- Free(child);
- return child;
- }
- I64 idx=TrieChrIdx(*name);
- CTrie *b=t->ents[idx];
- if(!b)
- t->ents[idx]=MAlloc(sizeof(CTrie));
- TrieIns(t->ents[idx],name+1,child);
- return t;
-}
-U0 FreeTrie(CTrie *t) {
- if(!t) return;
- I64 cnt=sizeof(t->ents)/sizeof(*t->ents);
- while(--cnt>=0) {
- FreeTrie(t->ents[cnt]);
- }
- Free(t->name);
- Free(t->fullname);
- Free(t);
-}
-CTrie *TagNew(U8 *fullname,U8 *name,U8 *fn,I64 ln,U8 kind) {
- CTrie *t=MAlloc(sizeof(CTrie));
- t->name=StrNew(name);
- t->fullname=StrNew(fullname);
- t->ln=ln;
- t->kind=kind;
-loop:
- CHash *ff=HashFind(fn,TagFiles);
- if(ff) {
- t->fn=ff->str;
- } else {
- CHash *new=MAlloc(sizeof(CHash));
- new->str=StrNew(fn);
- HashAdd(new,TagFiles);
- goto loop;
- }
- return t;
-}
-CTrie *ReadTags(U8 *file) {
- CTrie *ret=MAlloc(sizeof(CTrie));
- I64 len;
- U8 *text=FileRead(file,&len);
- U8 *en=text+len,*fullname;
- U8 buf1[256],buf2[256],buf3[256];
- U8 *_buf1=buf1,*_buf2=buf2,*_buf3=buf3;
- I64 ln;
-loop:
- if(text!=en) {
- text=StrScan(text,"%s\t%s\t",&_buf1,&_buf2);
- ln=Str2I64(text,,&text);
- fullname=StrNew(buf1);
- U8 type=TAG_VAR;
- if(*text==';') {
- text++;
-attrloop:
- if(*text=='\t') {
- text++;
- if(0==StrNCmp("kind:",text,len=StrLen("kind:"))) {
- text+=len;
- switch(*text) {
- case 'c':
- type=TAG_CLASS;
- break;
- case 'm':
- type=TAG_MACRO;
- break;
- case 'f':
- type=TAG_FUNC;
- break;
- case 'u':
- type=TAG_UNION;
- break;
- case 'v':
- type=TAG_VAR;
- break;
- default:
- throw('InvType');
- }
- text++;
- goto attrloop;
- }
- if(0==StrNCmp("struct:",text,len=StrLen("struct:"))) {
- text+=len;
- U8 *tdelim=StrFirstOcc(text,"\x0d\n\t");
- U8 *ofclass=StrNCpy(MAlloc(tdelim-text+1),text,tdelim-text);
- ofclass[tdelim-text]=0;
- Free(fullname);
- fullname=MStrPrint("%s.%s",ofclass,buf1);
- text=tdelim;
- goto attrloop;
- }
- if(0==StrNCmp("union:",text,len=StrLen("union:"))) {
- text+=len;
- tdelim=StrFirstOcc(text,"\x0d\n\t");
- ofclass=StrNCpy(MAlloc(tdelim-text+1),text,tdelim-text);
- ofclass[tdelim-text]=0;
- Free(fullname);
- fullname=MStrPrint("%s.%s",ofclass,buf1);
- text=tdelim;
- goto attrloop;
- }
- } else if(*text==0x0d) {
- //Cariage return
- text++;
- if(*text++=='\n')
- goto ins;
- }
- else if(*text++=='\n')
- goto ins;
- else {
- "%s\n",text;
- throw('Tag');
- }
- } else if(*text++!='\n') {
- "%s\n",text;
- throw('Tag');
- }
-ins:
- TrieIns(ret,fullname,TagNew(fullname,buf1,buf2,ln,type));
- Free(fullname);
- goto loop;
- }
-en:
- Free(text);
- return ret;
-}
-#define DIAG_WARN 0
-#define DIAG_ERR 1
-class CDiag {
- CDiag *prev,*next;
- I64 type,ln,col;
- //From TagFiles
- U8 *fn,*msg;
-};
-CDiag *ParseDiags(U8 *file) {
- I64 cnt,len;
- U8 *text=FileRead(file,&cnt);
- U8 *ptr=text;
- CDiag *prev=NULL;
- while(*ptr) {
- CDiag *new=MAlloc(sizeof(CDiag));
- new->prev=prev;
- if(prev) prev->next=new;
- new->fn=MAlloc(1024);
- try {
- //fn:ln:col [WARNING|ERROR] [msg]
- //Filename can contain ':' so ensure a number follows the ':'
- U8 *fnstart=ptr;
- loop:
- U8 *colon=StrFirstOcc(ptr,":");
- if(!colon) goto fail;
- if(Bt(&char_bmp_dec_numeric,colon[1])) {
- StrNCpy(new->fn,fnstart,colon-fnstart);
- ptr=colon+1;
- } else {
- ptr=colon+1;
- goto loop;
- }
- ptr=StrScan(ptr,"%d:%d: ",&new->ln,&new->col);
- if(0==StrNCmp(ptr,"WARNING",len=StrLen("WARNING"))) {
- ptr+=len;
- new->type=DIAG_WARN;
- } else if(0==StrNCmp(ptr,"ERROR",len=StrLen("ERROR"))) {
- ptr+=len;
- new->type=DIAG_ERR;
- }
- U8 *nl=StrFirstOcc(ptr,"\n");
- new->msg=StrNCpy(MAlloc(nl-ptr+1),ptr,nl-ptr);
- prev=new;
- ptr=nl+1;
- } catch {
- Fs->catch_except=TRUE;
- goto fail;
- }
- }
- CDiag *first=prev;
- while(prev) {first=prev;prev=prev->prev;}
- Free(text);
- return first;
- fail:
- Free(text);
- return NULL;
-}
-U0 FreeDiags(CDiag *errs) {
- if(!errs) return;
- FreeDiags(errs->next);
- Free(errs->fn);
- Free(errs->msg);
- Free(errs);
-}
-U0 __FuzzyMatch(CTrie *trie,U8 *name,I64 *cnt,CTrie **dumpto) {
- if(!trie) return;
- if(!*name) {
- if(trie->name) {
- if(dumpto)
- dumpto[*cnt]=trie;
- ++*cnt;
- }
- }
- I64 idx=-1;
- if(*name)
- idx=TrieChrIdx(*name);
- I64 cnt2=sizeof(trie->ents)/sizeof(*trie->ents);
- while(--cnt2>=0) {
- if(cnt2!=idx)
- __FuzzyMatch(trie->ents[cnt2],name,cnt,dumpto);
- else
- __FuzzyMatch(trie->ents[cnt2],name+1,cnt,dumpto);
- }
-}
-I64 MatchCmp(U0 *a,U0 *b) {
- CTrie **A=a,**B=b;
- return StrLen(A[0]->fullname)-StrLen(B[0]->fullname);
-}
-CTrie **FuzzyMatch(CTrie *trie,U8 *name,I64 *cnt=NULL) {
- I64 cnt2=0;
- __FuzzyMatch(trie,name,&cnt2,NULL);
- CTrie **ents=MAlloc(sizeof(CTrie*)*(cnt2+1));
- cnt2=0;
- __FuzzyMatch(trie,name,&cnt2,ents);
- if(cnt) *cnt=cnt2;
- ents[cnt2]=NULL;
- QSort(ents(U8*),cnt2,sizeof(CTrie*),&MatchCmp);
- return ents;
-}
-CHashTable *keywords=HashTableNew(1<<5);
-U0 AddKeyword(U8i *text) {
- CHash *h=MAlloc(sizeof(CHash));
- h->str=StrNew(text);
- h->type=1;
- HashAdd(h,keywords);
-}
-U8 *kws[]= {
- "union",
- "catch",
- "class",
- "try",
- "if",
- "else",
- "for",
- "while",
- "extern",
- "_extern",
- "return",
- "sizeof",
- "intern",
- "do",
- "goto",
- "break",
- "switch",
- "start",
- "end",
- "case",
- "default",
- "public",
- "import",
- "_import",
- "lastclass",
- "static",
- "U0",
- "U8i",
- "I8i",
- "U16i",
- "I16i",
- "U32i",
- "I32i",
- "U64i",
- "I64i",
- "F64",
- "Bool",
- "#include",
- "#exe",
- "#define",
- "#assert",
- "#if",
- "#else",
- "#endif",
- "#ifdef",
- "#ifndef",
-};
-I64 cnt=sizeof(kws)/sizeof(*kws);;
-while(--cnt>=0) {
- AddKeyword(kws[cnt]);
-}
-#define ED_RET_OK 1
-#define ED_RET_QUIT 2
-
-#define ED_LNF_COMMENTED_OUT 1
-#define ED_LNF_COMMENTED_START (1<<1)
-#define ED_LNF_COMMENTED_END (1<<2)
-#define ED_LNF_ERR (1<<3)
-#define ED_LNF_WARN (1<<4)
-class CLine {
- CLine *prev,*next;
- I64 line,length,flags;
- CDiag *diag;
- //Used with ED_LNF_COMMENTED_START
- CLine *commentStart;
- CRope *text;
- //Will be invalided when CEditor.line_cache_size is lesser than line number
- I64 cached_offset;
-};
-I64 IndentLevel(CLine *ln) {
- U8 *txt=Rope2Str(ln->text);
- I64 cnt=0;
- while(txt[cnt]==' ') cnt++;
- cnt/=4;
- Free(txt);
- return cnt;
-}
-//Color pairs
-#define CP_BLANK 0
-#define CP_KW 1
-#define CP_WORD 2
-#define CP_TOK 3
-#define CP_NUM 4
-#define CP_STR 5
-#define CP_WHITE 6
-#define CP_LINUM 7
-#define CP_COMMENT 8
-#define CP_AC_SEL 9
-#define CP_AC_UNSEL 10
-#define CP_MENU_SEL 11
-#define CP_MENU_UNSEL 12
-#define CP_FUZZY_SEL_A 13
-#define CP_FUZZY_UNSEL_A 14
-#define CP_FUZZY_SEL_B 15
-#define CP_FUZZY_UNSEL_B 16
-#define CP_LINUM_ERR 17
-#define CP_LINUM_WARN 18
-#define CP_CURSOR 19
-//TODO
-#define SOL_BLACK 0x000000
-#define SOL_WHITE 0xfdf6e3
-#define SOL_YELLOW 0xb58900
-#define SOL_ORANGE 0xcb4b16
-#define SOL_RED 0xdc322f
-#define SOL_MAGENTA 0xd33682
-#define SOL_BLUE 0x286bd2
-#define SOL_CYAN 0x2aa198
-#define SOL_GREEN 0x859900
-U32 union U_RGBA8888 {
- class {
- U8 b;
- U8 g;
- U8 r;
- U8 a;
- };
-};
-class CSDL_ColorPair {
- U_RGBA8888 fg;
- U_RGBA8888 bg;
-};
-CSDL_ColorPair SDL_ColorPairs[64];
-SDL_Window *global_window=NULL;
-SDL_Texture *global_font=NULL;
-SDL_Renderer *global_rend=NULL;
-#define FONT_X 8
-#define FONT_Y 8
-U0 SDL_InitScr() {
- global_window=SDL_CreateWindow("HolyEd",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_RESIZABLE);
- global_rend=SDL_CreateRenderer(global_window,-1,SDL_RENDERER_TARGETTEXTURE|SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
- global_font=SDL_CreateTexture(global_rend,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,FONT_X*0x100,FONT_Y);
- SDL_SetRenderTarget(global_rend,global_font);
- SDL_SetRenderDrawColor(global_rend,0,0,0,0);
- SDL_RenderClear(global_rend);
- SDL_SetRenderDrawColor(global_rend,0xff,0xff,0xff,0xff);
- I64 cnt=0x100;
- SDL_SetTextureBlendMode(global_font,SDL_BLENDMODE_BLEND);
- while(--cnt>=0) {
- I64 top=8;
- while(--top>=0) {
- I64 bit=0;
- U8 byte=sys_font_std[cnt].u8[top];
- for(;bit!=8;bit++) {
- if(Bt(&byte,bit)) {
- SDL_RenderDrawPoint(global_rend,cnt*8+bit,top);
- }
- }
- }
- }
- SDL_StartTextInput;
-}
-U0 SDL_ExitScr() {
- SDL_DestroyRenderer(global_rend);
- SDL_DestroyWindow(global_window);
- SDL_DestroyTexture(global_font);
- global_rend=NULL,global_window=NULL,global_font=NULL;
- SDL_StopTextInput;
-}
-class CSDL_ScrnChr {
- U8 chr;
- I8 cp; //negative for inverse
-};
-class CSDL_TextWin {
- SDL_Texture *text;
- U8 cur_cp; //From SDL_ColorPairs
- I64 x,y,begx,begy,curx,cury;
- //The charactors on the screen.
- CSDL_ScrnChr *char_cache;
- Bool cur_enabled;
- Bool inverse;
-};
-#define FONT_X 8
-#define FONT_Y 8
-#define FONT_X2 16
-#define FONT_Y2 16
-CSDL_TextWin *SDL_NewTextWin(I64 w,I64 h) {
- CSDL_TextWin *ret=MAlloc(sizeof(CSDL_TextWin));
- ret->text=SDL_CreateTexture(global_rend,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,w*FONT_X2,h*FONT_Y2);
- ret->cur_cp=CP_WHITE;
- ret->char_cache=MAlloc(sizeof(CSDL_ScrnChr)*w*h);
- return ret;
-}
-U0 SDL_DestroyTextWin(CSDL_TextWin *win) {
- Free(win->char_cache);
- SDL_DestroyTexture(win->text);
- Free(win);
-}
-I64 SDL_WinX(CSDL_TextWin *w) {
- I32 x,y;
- SDL_QueryTexture(w->text,NULL,NULL,&x,&y);
- return x/FONT_X2;
-}
-I64 SDL_WinY(CSDL_TextWin *w) {
- I32 x,y;
- SDL_QueryTexture(w->text,NULL,NULL,&x,&y);
- return y/FONT_Y2;
-}
-//Pass CSDL_TextWin's
-U0 SDL_DrawWin(...) {
- I64 idx=0;
- SDL_SetRenderTarget(global_rend,NULL);
- I32 winx,winy;
- SDL_GetWindowSize(global_window,&winx,&winy);
- winx/=FONT_X2,winy/=FONT_Y2;
- SDL_RenderClear(global_rend);
- for(;idx!=argc;idx++) {
- CSDL_TextWin *w=argv[idx];
- SDL_Renderer *rend=SDL_GetRenderer(global_window);
- U_RGBA8888 white=SOL_WHITE;
- SDL_SetRenderDrawColor(rend,white.r,white.g,white.b,0xff);
- I64 x=SDL_WinX(w)*FONT_X2,y=SDL_WinY(w)*FONT_Y2;
- SDL_Rect box={w->begx*FONT_X2,w->begy*FONT_Y2,x,y};
- I32 rx,ry;
- SDL_SetRenderTarget(rend,w->text);
- SDL_GetRendererOutputSize(rend,&rx,&ry);
- SDL_Rect sbox={0,0,rx/FONT_X2*FONT_X2,ry/FONT_Y2*FONT_Y2};
- SDL_SetRenderTarget(rend,NULL);
- SDL_RenderCopy(rend,w->text,NULL,&box);
- if(x/FONT_X2!=winx||y/FONT_Y2!=winy) {
- "RESETING\n";
- SDL_DestroyTexture(w->text);
- w->text=SDL_CreateTexture(global_rend,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,winx*FONT_X2,winy*FONT_Y2);
- Free(w->char_cache);
- w->char_cache=MAlloc(sizeof(CSDL_ScrnChr)*winx*winy);
- }
- if(w->cur_enabled) {
- SDL_Rect crect={w->curx*FONT_X2,w->cury*FONT_X2,FONT_X2,FONT_Y2};
- SDL_SetRenderDrawColor(global_rend,0,0,0,0xff);
- SDL_RenderDrawRect(global_rend,&crect);
- }
- }
- SDL_RenderPresent(global_rend);
-}
-U0 SDL_AddCh(CSDL_TextWin *win,U8 ch,Bool force_in_view=FALSE) {
- I64 w=SDL_WinX(win);
- if(force_in_view&&ch!='\n') {
- if(win->x+1>=w) return;
- }
- if(ch=='\n') goto nxtln;
- I64 mult=1;
- if(win->inverse) mult=-1;
- if((win->char_cache[win->y*w+win->x].chr==ch)&&(win->char_cache[win->y*w+win->x].cp==mult*win->cur_cp)) goto next;
- SDL_Rect fsrc={ch*FONT_X,0,FONT_X,FONT_Y};
- SDL_Rect dstbox={win->x*FONT_X2,win->y*FONT_Y2,FONT_X2,FONT_Y2};
- SDL_SetRenderTarget(global_rend,win->text);
- U_RGBA8888 bg=SDL_ColorPairs[win->cur_cp].bg;
- U_RGBA8888 fg=SDL_ColorPairs[win->cur_cp].fg;
- if(win->inverse) {
- U_RGBA8888 tmp=bg;
- bg=fg;
- fg=tmp;
- }
- SDL_SetRenderDrawColor(global_rend,bg.r,bg.g,bg.b,0xff);
- SDL_SetTextureColorMod(global_font,fg.r,fg.g,fg.b);
- SDL_RenderFillRect(global_rend,&dstbox);
- SDL_RenderCopy(global_rend,global_font,&fsrc,&dstbox);
- win->char_cache[win->y*w+win->x].chr=ch;
- win->char_cache[win->y*w+win->x].cp=win->cur_cp*mult;
- next:
- if(++win->x>=w) {
- nxtln:
- win->x=0,win->y++;
- }
- if(win->y<SDL_WinY(win)) {
- } else {
- win->y=SDL_WinY(win)-1;
- }
-}
-U0 SDL_Print(CSDL_TextWin *win,U8 *str) {
- I64 len=StrLen(str),idx=0;
- for(;idx!=len;idx++) {
- SDL_AddCh(win,str[idx],TRUE);
- }
-}
-U0 SDL_SetBgColor(CSDL_TextWin *w) {
- U_RGBA8888 bg=SDL_ColorPairs[w->cur_cp].bg;
- SDL_SetRenderDrawColor(global_rend, bg.r,bg.g,bg.b,0xff);
-}
-U0 SDL_ClrToEOL(CSDL_TextWin *w) {
- I64 width=SDL_WinX(w)-w->x;
- U_RGBA8888 white=SOL_WHITE;
- SDL_SetRenderDrawColor(global_rend,white.r,white.g,white.b,0xff);
- SDL_Rect r={w->x*FONT_X2,w->y*FONT_Y2,width*FONT_X2,FONT_Y2};
- SDL_SetRenderTarget(global_rend,w->text);
- SDL_RenderFillRect(global_rend,&r);
- I64 idx=w->y*SDL_WinX(w)+w->x;
- while(--width>=0)
- w->char_cache[idx+width].chr=' ',w->char_cache[width].cp=CP_BLANK;
-}
-class CEditor {
- CSDL_TextWin *window;
- CUndoInfo undo_info[UNDO_INFO_LENGTH];
- I64 undo_info_cur;
- I64 undo_info_end;
- I64 undo_info_start;
- Bool *dirty_screen_lines;
- I64 vp_start_line;
- I64 x_scroll;
- I64 curx,cury;
- //The expected x position,,we can enter a line that isnt as long as our expected curx
- I64 _curx;
- I64 h,w;
- CLine *lines;
- I64 line_count;
- //
- CLine **line_cache;
- I64 line_cache_size;
- //
- CTrie *tags;
- CDiag *diags;
- U8 *fn;
- I64 margin_top,margin_bottom;
- I64 sel_start,sel_end;
-};
-U8 *EdGetSelText(CEditor *ed);
-U0 EdDelSel(CEditor *ed);
-U0 MarkLineColors(CEditor *ed);
-U0 WriteWithinWin(CSDL_TextWin *win,U8 *text,I64 x_scroll=0);
-I64 OpenFile(U8 *name,I64 ln=0);
-I64 ShowDiagsWindow(CEditor *parent) {
- CDiag *first=parent->diags;
- I64 y_scroll=0,x_scroll=0,curln=0,ret=ED_RET_OK;
- CDiag *iter=first;
- I64 cnt=0;
- while(iter) cnt++,iter=iter->next;
- iter=first;
- CDiag **lines=MAlloc(cnt*sizeof(CDiag*));
- cnt=0;
- while(iter) {lines[cnt++]=iter;iter=iter->next;}
- parent->window->cur_cp=CP_WHITE;
- CSDL_TextWin *win=parent->window;
- draw:
- I64 h=getmaxy(stdscr);
- I64 cap=MinI64(y_scroll+h,cnt);
- I64 cnt2=0;
- dloop:
- if(cnt2+y_scroll>=cnt) {
- clear:
- while(cnt2<SDL_WinY(win)) {
- win->y=cnt2++;
- win->x=0;
- SDL_ClrToEOL(win);
- }
- goto inp;
- }
- if(cnt2+y_scroll==curln) {
- win->cur_cp=CP_FUZZY_SEL_B;
- } else {
- win->cur_cp=CP_FUZZY_UNSEL_A;
- }
- win->y=cnt2,win->x=0;
- I64 off=-x_scroll;
- CDiag *cur=lines[cnt2++ +y_scroll];
- U8 *lncol=MStrPrint("%s:%d:%d: ",cur->fn,cur->ln,cur->col);
- WriteWithinWin(win,lncol,off);
- off+=StrLen(lncol);
- Free(lncol);
-
- if(cur->type==DIAG_ERR) {
- WriteWithinWin(win,"ERROR",off);
- //TODO COLOR
- off+=StrLen("ERROR");
- } else {
- WriteWithinWin(win,"WARNING",off);
- //TODO COLOR
- off+=StrLen("WARNING");
- }
- if(StrFirstOcc(cur.msg,"\r\n")) *StrFirstOcc(cur.msg,"\n\r")=0;
- WriteWithinWin(win,cur->msg,off);
- SDL_ClrToEOL(win);
- if(cnt2+y_scroll<cap) goto dloop;
- goto clear;
- inp:
- SDL_DrawWin(win);
- I64 key=GetKey();
- switch(key) {
- case ED_KEY_ESCAPE: goto exit;
- case ERR: goto inp;
- case ED_KEY_PAGEUP:
- curln=MaxI64(0,curln-SDL_WinY(win));
- break;
- case ED_KEY_PAGEDOWN:
- curln=MinI64(cnt,curln+SDL_WinY(win));
- break;
- case ED_KEY_RIGHT: ++x_scroll; break;
- case ED_KEY_LEFT: x_scroll=MaxI64(0,--x_scroll); break;
- case ED_KEY_UP: curln=MinI64(MaxI64(0,--curln),cnt); break;
- case ED_KEY_DOWN: curln++; break;
- case '\n':
- if(curln<cnt) {
- ret=OpenFile(lines[curln]->fn,lines[curln]->ln);
- goto exit;
- } else {
- goto exit;
- }
- break;
- case ED_KEY_REDRAW:
- case ED_KEY_RESIZE:
- SDL_DrawWin(win);
- break;
- }
- if(curln<y_scroll) y_scroll=curln;
- else if(curln>=SDL_WinY(win)+y_scroll) y_scroll=curln-SDL_WinY(win)+1;
- goto draw;
- exit:
- Free(lines);
- return ret;
-}
-
-I64 UndoBufSize(CEditor* ed) {
- if (ed->undo_info_end > ed->undo_info_start)
- return ed->undo_info_end - ed->undo_info_start;
- else
- return (UNDO_INFO_LENGTH - ed->undo_info_start) + ed->undo_info_end;
-}
-U0 InsUndoInfo(CUndoInfo* info, CEditor* ed) {
- ed->undo_info_end = (ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH;
-
- if (ed->undo_info_cur != UNDO_INFO_LENGTH) {
- ed->undo_info_cur++;
- } else if (ed->undo_info_end == ed->undo_info_start) {
- ed->undo_info_start = (ed->undo_info_start + 1) % UNDO_INFO_LENGTH;
- }
-
- //Destroy old value
- switch (ed->undo_info[ed->undo_info_end]->type) {
- case EDIT_DEL_STR:
- Free(ed->undo_info[ed->undo_info_end]->removed_str);
- break;
-
- case EDIT_INS_STR:
- Free(ed->undo_info[ed->undo_info_end]->inserted_str);
- break;
- }
-
- ed->undo_info[ed->undo_info_end] = *info;
- ed->undo_info_end = (ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH;
-}
-CUndoInfo* GetUndoInfo(CEditor* ed) {
- if ((ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH == ed->undo_info_end)
- if (ed->undo_info_cur)
- return NULL;
-
- I64 i = (ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH;
- I64 s = ed->undo_info_start;
- I64 e = ed->undo_info_end;
-
- if (s == e) goto en;
-
- if (s < e) {
- if (!(s <= i < e)) return NULL;
- } else if (e <= i < s) return NULL;
-
- en:
-
- if (ed->undo_info[i]->type == EDIT_UNUSED)
- return NULL;
-
- return &ed->undo_info[i];
-}
-class CBuffer:CHash {
- CEditor *ed;
-};
-CHashTable *buffers=HashTableNew(1<<5);
-U0 FocusCursor(CEditor *ed,I64 lmargin=0) {
- //https://stackoverflow.com/questions/1811955/ncurses-terminal-size
- I64 w=SDL_WinX(ed->window)-lmargin;
- if(ed->curx<ed->x_scroll) {
- ed->x_scroll=ed->curx;
- } else if(ed->x_scroll+w<=ed->curx) {
- ed->x_scroll=ed->curx-w+1;
- }
- if(ed->cury<ed->vp_start_line) {
- ed->vp_start_line=ed->cury;
- } else if(ed->vp_start_line+SDL_WinY(ed->window)-ed->margin_top<=ed->cury) {
- ed->vp_start_line=ed->cury-SDL_WinY(ed->window)+1+ed->margin_top;
- }
-}
-I64 GetLinum(CEditor *ed,CLine *ln) {
- CLine *s=ed->lines;
- I64 num=0;
- while(s) {
- if(s==ln)
- return num;
- num++;
- s=s->next;
- }
- return -1;
-}
-I64 GetLineCount(CEditor *ed) {
- I64 ret=0;
- CLine *ln=ed->lines;
- while(ln) {
- ln=ln->next,ret++;
- }
- return ret;
-}
-CLine *GetLine(CEditor *ed,I64 ln) {
- if(ed->line_cache_size>ln)
- return ed->line_cache[ln];
- CLine *s=ed->lines;
- if(s->cached_offset!=0) throw('');
- I64 num=0,off=0;
- if(MSize(ed->line_cache)/sizeof(CLine*)<=ln) {
- I64 pow2=1;
- while((1<<pow2)<=ln) pow2++;
- CLine **new=MAlloc((1<<pow2)*sizeof(CLine*));
- MemNCpy(new,ed->line_cache,sizeof(CLine*)*ed->line_cache_size);
- if(ed->line_cache_size){
- s=ed->line_cache[ed->line_cache_size-1];
- off=s->cached_offset;
- num=ed->line_cache_size-1;
- }
- Free(ed->line_cache);
- ed->line_cache=new;
- }
- while(s) {
- ed->line_cache[num]=s;
- s->cached_offset=off;
- if(num==ln) {
- ed->line_cache_size=MaxI64(ln,ed->line_cache_size);
- return s;
- }
- off+=RopeLength(s->text);
- s=s->next;
- num++;
- }
- ed->line_cache_size=num;
- return NULL;
-}
-I64 GetLineOffset(CEditor *ed,I64 ln) {
- CLine *ln2=GetLine(ed,ln);
- if(ln2) return ln2->cached_offset;
- return -1;
-}
-
-U0 DirtyLinesBelow(CEditor *ed,I64 ln) {
- ed->line_cache_size=ln;
- ln-=ed->vp_start_line;
-}
-U0 WriteWithinWin(CSDL_TextWin *win,U8 *text,I64 x_scroll=0) {
- I64 l=StrLen(text)+x_scroll;
- I64 s=x_scroll;
- while(s!=l) {
- if(SDL_WinX(win)>=s>=0) {
- U8 chr=text[s-x_scroll];
- if(chr=='\t')
- SDL_AddCh(win,' ',TRUE);
- else if(chr!='\r'){
- SDL_AddCh(win,chr,TRUE);
- }
- }
- s++;
- }
-}
-U0 WriteWithinView(CEditor *ed,U8 *text,I64 off) {
- I64 l=StrLen(text);
- I64 s=off;
- I64 e=off+l;
- while(s!=e) {
- if(ed->x_scroll+SDL_WinX(ed->window)>=s>=ed->x_scroll) {
- if(text[s-off]=='\t')
- SDL_AddCh(ed->window,' ',TRUE);
- else if(text[s-off]!='\r')
- SDL_AddCh(ed->window,text[s-off],TRUE);
- }
- s++;
- }
-}
-Bool IsEscaped(U8 *sstart,U8 *chr) {
- if(chr-1>=sstart)
- if(chr[-1]=='\\')
- return !IsEscaped(sstart,chr-1);
- return FALSE;
-}
-CLine *SearchForMLCommmentStart(CLine *s) {
- while(s) {
- if(s->flags&ED_LNF_COMMENTED_START)
- if(!(s->flags&ED_LNF_COMMENTED_OUT))
- return s;
- s=s->prev;
- }
- return NULL;
-}
-CLine *SearchForMLCommmentEnd(CLine *s) {
- while(s) {
- if(s->flags&ED_LNF_COMMENTED_END)
- return s;
- s=s->next;
- }
- return NULL;
-}
-U0 __HighlightWrite(CEditor *ed,U8 *text,I64 off,I64 sel_start=I64_MAX,I64 sel_end=I64_MAX) {
- I64 len=StrLen(text),idx;
- for(idx=0;idx!=len;idx++) {
- if(off+idx>=ed->x_scroll) {
- if(sel_start<=off+idx<sel_end) {
- ed->window->inverse=TRUE;
- } else
- ed->window->inverse=FALSE;
- SDL_AddCh(ed->window,text[idx],TRUE);
- }
- }
- ed->window->inverse=FALSE;
-}
-U0 Highlight(CEditor *ed,CLine *ln,Bool dryRun=FALSE,Bool recur=TRUE) {
- I64 ln_off=GetLineOffset(ed,GetLinum(ed,ln));
- I64 sel_start=ed->sel_start;
- I64 sel_end=ed->sel_end;
- if(sel_start==sel_end) goto ignoresel;
- sel_start-=ln_off;
- sel_end-=ln_off;
- //Compute relative to line start
- if(sel_start<0) sel_start=0;
- if(sel_end<0) sel_end=0;
- if(sel_end>RopeLength(ln->text))
- sel_end=RopeLength(ln->text);
- if(sel_start>sel_end) SwapI64(&sel_start,&sel_end);
- ignoresel:
- U8 *text=Rope2Str(ln->text);
- U8 *nl=StrFirstOcc(text,"\n");
- if(nl) *nl=0;
- U8 *buf=MAlloc(StrLen(text)+1);
- I64 idx=0,ns=0;
- if(ln->prev) {
- if(!(ln->prev->flags&ED_LNF_COMMENTED_OUT))
- ln->flags&=~ED_LNF_COMMENTED_OUT;
- if(!(ln->flags&ED_LNF_COMMENTED_END))
- if((ln->prev->flags&ED_LNF_COMMENTED_OUT)||(ln->prev->flags&ED_LNF_COMMENTED_START))
- ln->flags|=ED_LNF_COMMENTED_OUT;
- }
- I64 isCommentedOut1=(ln->flags&ED_LNF_COMMENTED_OUT)||(ln->flags&ED_LNF_COMMENTED_START);
- I64 isMlEnd1=ln->flags&ED_LNF_COMMENTED_END,isMlStart1=ln->flags&ED_LNF_COMMENTED_START;
- ln->flags&=~ED_LNF_COMMENTED_START;
- if((ln->flags&ED_LNF_COMMENTED_END)||(ln->flags&ED_LNF_COMMENTED_OUT)) {
- while(text[idx]) {
- if(0==StrNCmp(text+idx,"*/",2)) {
- idx+=2;
- ed->window->cur_cp=CP_COMMENT;
- StrNCpy(buf,text,idx);
- buf[idx]=0;
- if(!dryRun) __HighlightWrite(ed,buf,0,sel_start,sel_end);
- ln->flags|=ED_LNF_COMMENTED_END;
- ln->flags&=~ED_LNF_COMMENTED_OUT;
- goto s;
- }
- idx++;
- }
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,text,0,sel_start,sel_end);
- ln->flags&=~ED_LNF_COMMENTED_END;
- ln->flags|=ED_LNF_COMMENTED_OUT;
- }
-s:
- U8 *orig=text;
-loop:
- ns=idx;
- //Try lexing name
- if(!Bt(char_bmp_dec_numeric,text[idx]))
- while(Bt(char_bmp_alpha_numeric,text[idx])||text[idx]=='#') idx++;
- if(ns!=idx) {
- StrNCpy(buf,&text[ns],idx-ns);
- buf[idx-ns]=0;
- CHash *kw;
- if(kw=HashFind(buf,keywords)) {
- ed->window->cur_cp=CP_KW;
- } else {
- ed->window->cur_cp=CP_WORD;
- }
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
-
- if(text[idx]=='/') {
- if(text[idx+1]=='/') {
- StrCpy(buf,text+idx);
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
- idx=StrLen(text);
- goto loop;
- } else if(text[idx+1]=='*') {
- idx++;
- while(text[idx]) {
- if(0==StrNCmp(text+idx,"*/",2)) {
- idx+=2;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- idx++;
- }
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
- ln->flags|=ED_LNF_COMMENTED_START;
- //Dry run hgihlight until we find a line end
- CLine *nxtln=ln->next;
- if(!recur) for(; nxtln;) {
- Highlight(ed, nxtln, TRUE); //Will set ED_LNF_COMMENTED_OUT;
- if(nxtln->flags&ED_LNF_COMMENTED_END) break;
- nxtln=nxtln->next;
- }
- }
- }
- //Try lexing a string
- if(StrOcc("'\"",text[idx])) {
- U8 term=text[idx++];
- U8 sseek[2]= {term,0};
-sloop:
- U8 *sfind=StrFirstOcc(text+idx,sseek);
- if(!sfind) {
- ed->window->cur_cp=CP_STR;
- if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
- idx=StrLen(text);
- } else if(IsEscaped(text,sfind)) {
- idx=sfind-orig+1;
- goto sloop;
- } else {
- idx=sfind-orig+1;
- ed->window->cur_cp=CP_STR;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- }
-
- //Lex numbers
- ns=idx;
- while (Bt(char_bmp_white_space,text[idx])) idx++;
- if(ns!=idx) {
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_WHITE;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- U8 *idx2=text+idx;
- Str2I64(text+idx,,&idx2);
- if(idx2!=text+idx) {
- idx=idx2-text;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_NUM;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- Str2F64(idx2,&idx2);
- if(text+idx!=idx2) {
- idx=idx2-text;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_NUM;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- if(!text[idx]) goto en;
- ed->window->cur_cp=CP_TOK;
- buf[1]=0;
- buf[0]=text[idx];
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- idx++;
- goto loop;
-en:
- I64 isMlEnd2=ln->flags&ED_LNF_COMMENTED_END,isMlStart2=ln->flags&ED_LNF_COMMENTED_START;
- I64 isCommentedOut2=(ln->flags&ED_LNF_COMMENTED_OUT)||(ln->flags&ED_LNF_COMMENTED_START);
- if(recur&&(isMlEnd1!=isMlEnd2||isMlStart1!=isMlStart2)) {
- nxtln=ln->next;
- for(;nxtln;nxtln=nxtln->next) {
- Bool comm_end=nxtln->flags&ED_LNF_COMMENTED_END;
- Highlight(ed, nxtln, TRUE);
- if(isMlEnd2) { //Added '*/',quit at next '*/'
- if(comm_end) break;
- } else { //Removed '*/',quit at next '*/'
- if(comm_end) break;
- }
- }
- }
- if(recur&&isCommentedOut2!=isCommentedOut1) {
- nxtln=ln->next;
- for(;nxtln;nxtln=nxtln->next) {
- Highlight(ed,nxtln,TRUE);
- if((nxtln->flags&ED_LNF_COMMENTED_OUT)!=isCommentedOut2) break;
- }
- }
- ed->window->cur_cp=CP_WHITE;
- SDL_ClrToEOL(ed->window);
- Free(buf);
-}
-U0 __EditorInsText(CEditor *ed,U8 *text,I64 at) {
- U8 *buf;
- I64 ln_off=0;
- CLine *ln=ed->lines,*prev=NULL;
- I64 linum=0;
- while(ln) {
- if(ln_off<=at<ln_off+RopeLength(ln->text)) break;
- ln_off+=RopeLength(ln->text);
- prev=ln;
- ln=ln->next,linum++;
- }
- DirtyLinesBelow(ed,GetLinum(ed,ln));
-
- if(ln_off<=at&&!ln) {
- if(prev) {
- ln=prev;
- ln_off-=RopeLength(ln->text);
- } else {
- CLine *nl=MAlloc(sizeof(CLine));
- ed->line_count++;
- nl->prev=prev;
- if(prev) prev->next=nl;
- ln=nl;
- ln->text=RopeAppendText(NULL,"");
- if(!ed->lines) ed->lines=nl;
- }
- }
- ln->text=RopeInsText(ln->text, text, at-ln_off);
- ln->text=RopeCondense(ln->text);
- Highlight(ed, ln, TRUE);
- CLine *start_ln=ln;
-loop:
- U8 *text2=Rope2Str(ln->text);
- U8 *nl3=StrFirstOcc(text2,"\n");
- if(nl3)
- if(nl3[1]) {
- CRope *right;
- RopeSplit(ln->text, nl3-text2+1, &ln->text, &right);
- //Insert a blank line
- nl=MAlloc(sizeof(CLine));
- ed->line_count++;
- nl->prev=ln;
- if(ln) nl->next=ln->next;
- if(nl->prev) nl->prev->next=nl;
- if(nl->next) nl->next->prev=nl;
- nl->text=right;
- ln=nl;
- Free(text2);
- goto loop;
- }
-
- if(!StrLen(text2)) ln->text=RopeAppendText(ln->text, "\n");
- else if(text2[StrLen(text2)-1]!='\n') ln->text=RopeAppendText(ln->text, "\n");
- DirtyLinesBelow(ed, GetLinum(ed,start_ln));
- Free(text2);
-}
-U0 RenumberLines(CEditor *ed,CLine *l=NULL) {
- I64 num=0;
- if(!l) l=ed->lines;
- else num=l->line;
- while(l) {
- l->line=num++;
- l=l->next;
- }
-}
-U0 EditorInsText(CEditor *ed,U8 *text,I64 at,Bool undo=FALSE) {
- EdDelSel(ed); //Clear selection if needed
- __EditorInsText(ed, text, at);
- if(undo) {
- CUndoInfo *prev;
- if(!(prev=GetUndoInfo(ed))) {
- ins1:
- CUndoInfo info;
- info.type=EDIT_INS_STR;
- info.inserted_str=StrNew(text);
- info.at=at;
- InsUndoInfo(&info,ed);
- goto ret;
- } else if(prev->type==EDIT_INS_STR) {
- if(prev->at+StrLen(prev->inserted_str)==at) {
- U8 *new=MStrPrint("%s%s",prev->inserted_str,text);
- Free(prev->inserted_str);
- prev->inserted_str=new;
- }
- }
- goto ins1;
- }
- ret:
- RenumberLines(ed);
-}
-U0 SDL_InitPair(I64 idx,U_RGBA8888 fg,U_RGBA8888 bg) {
- SDL_ColorPairs[idx].fg=fg,SDL_ColorPairs[idx].bg=bg;
-}
-CEditor *EditorNew(Bool gen_rt_tags=FALSE) {
- CEditor *r=MAlloc(sizeof(CEditor));
- SDL_InitPair(CP_KW,SOL_MAGENTA,SOL_WHITE);
- SDL_InitPair(CP_WORD,SOL_BLUE,SOL_WHITE);
- SDL_InitPair(CP_TOK,SOL_GREEN,SOL_WHITE);
- SDL_InitPair(CP_NUM,SOL_YELLOW,SOL_WHITE);
- SDL_InitPair(CP_STR,SOL_RED,SOL_WHITE);
- SDL_InitPair(CP_WHITE,SOL_BLACK,SOL_WHITE);
- SDL_InitPair(CP_LINUM,SOL_WHITE,SOL_BLUE);
- SDL_InitPair(CP_COMMENT,SOL_CYAN,SOL_WHITE);
- SDL_InitPair(CP_AC_SEL,SOL_CYAN,SOL_RED);
- SDL_InitPair(CP_AC_UNSEL,SOL_YELLOW,SOL_BLUE);
- SDL_InitPair(CP_MENU_SEL,SOL_YELLOW,SOL_RED);
- SDL_InitPair(CP_MENU_UNSEL,SOL_WHITE,SOL_BLUE);
- SDL_InitPair(CP_FUZZY_SEL_A,SOL_BLACK,SOL_YELLOW);
- SDL_InitPair(CP_FUZZY_UNSEL_A,SOL_BLACK,SOL_WHITE);
- SDL_InitPair(CP_FUZZY_SEL_B,SOL_RED,SOL_YELLOW);
- SDL_InitPair(CP_FUZZY_UNSEL_B,SOL_RED,SOL_WHITE);
- SDL_InitPair(CP_LINUM_ERR,SOL_WHITE,SOL_RED);
- SDL_InitPair(CP_LINUM_WARN,SOL_WHITE,SOL_YELLOW);
- I32 x,y;
- SDL_GetWindowSize(global_window,&x,&y);
- r->window=SDL_NewTextWin(x/FONT_X2,y/FONT_Y2);
- r->vp_start_line=0;
- r->line_cache=MAlloc(sizeof(CLine*));
- r->line_cache_size=0;
- EditorInsText(r,"",0);
- if(gen_rt_tags) {
- CreateTagsAndErrorsFiles("TAGS","ERRS",r->fn);
- r->tags=ReadTags("TAGS");
- r->diags=ParseDiags("ERRS");
- MarkLineColors(r);
- }
- return r;
-}
-U0 FreeLine(CLine *ln) {
- //Update multiline comments
- if(ln->flags&ED_LNF_COMMENTED_START) {
- CLine *s=SearchForMLCommmentStart(ln->prev);
- CLine* e=SearchForMLCommmentEnd(ln);
-adjust:
- if(s) {
- if(e) {
- e->commentStart=s;
- } else {
- do {
- s->flags|=ED_LNF_COMMENTED_OUT;
- s=s->next;
- } while(s);
- }
- } else if(e) {
- e->commentStart=NULL;
- do {
- e->flags&=~ED_LNF_COMMENTED_OUT;
- e=e->prev;
- } while(e);
- }
- } else if(ln->flags&ED_LNF_COMMENTED_END) {
- s=SearchForMLCommmentStart(ln);
- e=SearchForMLCommmentEnd(ln->next);
- goto adjust;
- }
- if(ln->prev) ln->prev->next=ln->next;
- if(ln->next) ln->next->prev=ln->prev;
- if(ln->text) RopeFree(ln->text);
- Free(ln);
-}
-U0 __EditorDelText(CEditor *ed,I64 soff,I64 eoff) {
- I64 ln_off=0;
- CLine *ln=ed->lines,*prev=NULL;
- Bool merge=TRUE;
- CLine *end_ln;
- while(ln) {
- if(ln_off<=soff<ln_off+RopeLength(ln->text)) {
- CLine *start_ln=ln;
- DirtyLinesBelow(ed,GetLinum(ed, start_ln));
- I64 en=MinI64(RopeLength(ln->text),eoff-ln_off);
- ln->text=RopeDelText(ln->text,soff-ln_off,en);
- eoff-=en-(soff-ln_off);
- ln->text=RopeCondense(ln->text);
- Highlight(ed, ln, TRUE);
- ln_off+=RopeLength(ln->text);
- if(ln_off+RopeLength(ln->text)>=eoff) {
- DirtyLinesBelow(ed,GetLinum(ed, ln));
- //End of deletion is on same line
- //Merge with next line if doesnt contain an endline
- U8 *txt=Rope2Str(ln->text);
- if(!StrFirstOcc(txt,"\n")) {
- Free(txt);
- end_ln=ln->next;
- goto merge;
- }
- Free(txt);
- return;
- }
- break;
- }
- ln_off+=RopeLength(ln->text);
- prev=ln;
- ln=ln->next;
- }
- if(!ln) return;
- while(ln) {
- if(ln_off<=eoff<ln_off+RopeLength(ln->text)) break;
- ln_off+=RopeLength(ln->text);
- prev=ln;
- ln=ln->next;
- }
- end_ln=ln;
-merge:
- //start_ln!=end_ln;
- if(start_ln!=end_ln)
- ln=start_ln->next;
- DirtyLinesBelow(ed,GetLinum(ed, start_ln));
- while(ln!=end_ln) {
- CLine *nxt=ln->next;
- if(ln==ed->lines) ed->lines=nxt;
- ed->line_count--;
- eoff-=RopeLength(ln->text);
- FreeLine(ln);
- ln=nxt;
- }
- if(merge&&end_ln) {
- U8 *t=Rope2Str(end_ln->text);
- start_ln->text=RopeAppendText(start_ln->text,t+eoff-GetLineOffset(ed,GetLinum(ed,end_ln)));
- start_ln->text=RopeCondense(start_ln->text);
- Highlight(ed, start_ln, TRUE);
- Free(t);
- FreeLine(end_ln);
- ed->line_count--;
- }
-}
-U8 *EdTextSlice(CEditor *ed,I64 soff,I64 eoff) {
- U8 *ret=MAlloc(eoff-soff+1);
- U8 *retptr=ret;
- I64 off=0;
- CLine *ln=ed->lines;
- sloop:
- if(off<=soff<off+RopeLength(ln->text)) {
- U8 *text=Rope2Str(ln->text);
- if(off<=eoff<off+RopeLength(ln->text)) {
- StrNCpy(ret,text+soff-off,eoff-soff);
- Free(text);
- return ret;
- } else {
- StrCpy(ret,text+soff-off);
- retptr+=StrLen(ret);
- off+=RopeLength(ln->text);
- ln=ln->next;
- }
- } else {
- off+=RopeLength(ln->text);
- ln=ln->next;
- goto sloop;
- }
- eloop:
- text=Rope2Str(ln->text);
- if(off<=eoff<off+RopeLength(ln->text)) {
- StrNCpy(retptr,text,eoff-off);
- Free(text);
- return ret;
- } else {
- off+=RopeLength(ln->text);
- StrCpy(retptr,text);
- retptr+=StrLen(retptr);
- ln=ln->next;
- Free(text);
- goto eloop;
- }
- return ret;
-}
-U0 EditorDelText(CEditor *ed,I64 soff,I64 eoff,Bool undo=FALSE) {
- if(undo)
- U8 *slice=EdTextSlice(ed,soff,eoff);
- __EditorDelText(ed, soff, eoff);
- if(undo) {
- CUndoInfo *prev=GetUndoInfo(ed);
- if(!prev) {
- ins1:
- CUndoInfo del;
- del.type=EDIT_DEL_STR;
- del.removed_str=StrNew(slice);
- del.at=soff;
- InsUndoInfo(&del,ed);
- goto ret;
- } else if(prev->type==EDIT_DEL_STR&&prev->at==soff) {
- U8 *new=MStrPrint("%s%s",slice,prev->removed_str);
- Free(prev->removed_str);
- prev->removed_str=new;
- goto ret;
- }
- goto ins1;
- }
- ret:
- if(undo) Free(slice);
- RenumberLines(ed);
-}
-U0 EdJumpToChar(CEditor *ed,I64 chr) {
- CLine *ln=ed->lines;
- I64 off=0;
- loop:
- if(!ln) return;
- I64 len;
- if(off<=chr<off+(len=RopeLength(ln->text))) {
- ed->cury=GetLinum(ed, ln);
- ed->curx=ed->_curx=chr-off;
- return;
- }
- off+=len;
- ln=ln->next;
- goto loop;
-}
-U0 Undo(CEditor *ed) {
- if(ed->undo_info_cur-1<0) return;
- ed->undo_info_cur--;
- CUndoInfo *info=GetUndoInfo(ed);
- switch(info->type) {
- case EDIT_INS_STR:
- EditorDelText(ed,info->at,info->at+StrLen(info->inserted_str));
- EdJumpToChar(ed,info->at);
- break;
- case EDIT_DEL_STR:
- EditorInsText(ed,info->removed_str,info->at);
- EdJumpToChar(ed,info->at+StrLen(info->removed_str));
- break;
- }
-}
-U0 Redo(CEditor *ed) {
- if(ed->undo_info_cur>=UndoBufSize(ed)) return;
- CUndoInfo *info=GetUndoInfo(ed);
- switch(info->type) {
- case EDIT_DEL_STR:
- EditorDelText(ed,info->at,info->at+StrLen(info->removed_str));
- EdJumpToChar(ed,info->at);
- break;
- case EDIT_INS_STR:
- EditorInsText(ed,info->inserted_str,info->at);
- EdJumpToChar(ed,info->at+StrLen(info->inserted_str));
- break;
- }
- ed->undo_info_cur++;
-}
-U0 DrawLinumWithPad(CEditor *ed,I64 num,I64 barwidth) {
- U8 *lnumtxt=MStrPrint("%d: ",num);
- I64 lnumlen=StrLen(lnumtxt);
- SDL_Print(ed->window,lnumtxt);
- Free(lnumtxt);
- while(barwidth>lnumlen++) SDL_AddCh(ed->window,' ');
-}
-#define ED_DRAW_LINUMS 1
-#define ED_DRAW_SEARCH 2
-#define ED_DRAW_DIALOG 4
-#define ED_DRAW_MENUBAR 8
-#define ED_DRAW_DFT (ED_DRAW_LINUMS|ED_DRAW_MENUBAR)
-#define ED_DRAW_NO_RENDER 16
-U0 AddMenuBar(CEditor *ed,I64 active=-1);
-I64 DrawEditor(CEditor *ed,I64 flags=0,U8 *dialogtxt=NULL,I64 mb_active=-1) {
- curs_set(0);
- CLine *diagln=NULL;
- //If we are at a line with a diagnostic,be sure to make a bottom margin
- if(flags&(ED_DRAW_DIALOG|ED_DRAW_SEARCH)) {
- } else {
- diagln=GetLine(ed,ed->cury);
- if(diagln) {
- if(!(diagln->flags&(ED_LNF_ERR|ED_LNF_WARN))) diagln=NULL;
- }
- }
- if(flags&ED_DRAW_MENUBAR) {
- if(AddMenuBar(ed,mb_active)==ED_RET_QUIT) return ED_RET_QUIT;
- ed->margin_top=1;
- }
- if(flags&ED_DRAW_LINUMS) {
- U8 *lnumtxt=MStrPrint("%d: ",ed->line_count);
- I64 lnumlen=StrLen(lnumtxt);
- Free(lnumtxt);
- } else if(flags&ED_DRAW_SEARCH) {
- ed->window->cur_cp=CP_LINUM;
- lnumtxt=MStrPrint("Search: ");
- lnumlen=StrLen(lnumtxt);
- ed->window->y=ed->window->x=0;
- SDL_Print(ed->window,lnumtxt);
- Free(lnumtxt);
- } else if(flags&ED_DRAW_DIALOG) {
- ed->window->cur_cp=CP_LINUM;
- lnumtxt=MStrPrint("%s: ",dialogtxt);
- lnumlen=StrLen(lnumtxt);
- ed->window->y=ed->window->x=0;
- SDL_Print(ed->window,lnumtxt);
- Free(lnumtxt);
- } else
- lnumlen=0;
- FocusCursor(ed,lnumlen);
- //if(ed->x_scroll) Debugger;
- ed->w-=lnumlen;
- CLine *ln=ed->lines;
- while(ln) {
- if(ln->line==ed->vp_start_line) break;
- ln=ln->next;
- }
- I64 cnt=SDL_WinY(ed->window),line=ed->vp_start_line+1,screen_line=ed->margin_top;
- cnt-=(ed->margin_top+ed->margin_bottom);
- while(--cnt>=0&&ln) {
- if(flags&ED_DRAW_LINUMS) {
- ed->window->y=screen_line,ed->window->x=0;
- I64 cp=CP_LINUM;
- if(ln->flags&ED_LNF_ERR) {
- cp=CP_LINUM_ERR;
- } else if(ln->flags&ED_LNF_WARN) {
- cp=CP_LINUM_WARN;
- }
- ed->window->cur_cp=cp;
- DrawLinumWithPad(ed,line++,lnumlen);
- }
- if(1) {
- ed->window->y=screen_line,ed->window->x=lnumlen;
- Highlight(ed,ln,,TRUE);
- }
- ++screen_line;
- ln=ln->next;
- }
- U8 *pad=MStrPrint("%*c",lnumlen,' ');
- while(cnt>=0) {
- ed->window->cur_cp=CP_LINUM;
- ed->window->y=screen_line,ed->window->x=0;
- SDL_Print(ed->window,pad);
- ed->window->cur_cp=CP_WHITE;
- ed->window->y=screen_line++,ed->window->x=lnumlen;
- SDL_ClrToEOL(ed->window);
- cnt--;
- }
- if(diagln) {
- ed->window->y=SDL_WinY(ed->window)-1,ed->window->x=0;
- if(diagln->flags&ED_LNF_ERR) ed->window->cur_cp=CP_LINUM_ERR;
- else if(diagln->flags&ED_LNF_WARN) ed->window->cur_cp=CP_LINUM_WARN;
- else throw('InvDiag');
- SDL_Print(ed->window,diagln->diag->msg);
- SDL_ClrToEOL(ed->window);
- }
- ed->window->cur_enabled=TRUE;
- ed->window->curx=lnumlen+ed->curx-ed->x_scroll;
- ed->window->cury=ed->cury-ed->vp_start_line+ed->margin_top;
- if(flags&ED_DRAW_NO_RENDER);
- else SDL_DrawWin(ed->window);
- return ED_RET_OK;
-}
-U0 EdUp(CEditor *ed) {
- if(ed->cury>0) {
- --ed->cury;
- if(ed->cury<ed->vp_start_line)
- ed->vp_start_line=ed->cury;
- if(ed->_curx>RopeLength(GetLine(ed, ed->cury)->text))
- ed->curx=RopeLength(GetLine(ed, ed->cury)->text);
- else
- ed->curx=ed->_curx;
- } else {
- ed->_curx=ed->curx=0;
- }
-}
-U0 EdDown(CEditor *ed) {
- CLine *dnext=GetLine(ed,ed->cury);
- if(dnext->next) {
- ++ed->cury;
- if(ed->_curx>RopeLength(GetLine(ed, ed->cury)->text))
- ed->curx=RopeLength(GetLine(ed, ed->cury)->text);
- else
- ed->curx=ed->_curx;
- } else {
- ed->_curx=ed->curx=RopeLength(GetLine(ed, ed->cury)->text);
- }
-}
-U0 EdRight(CEditor *ed) {
- CLine *rline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(rline->text);
- I64 x=ed->curx,cnt=0;
- I64 ox=x;
- x++;
- while((--x>=0)&&text[x]==' ') cnt++;
- if(x==-1&&cnt) {
- cnt++;
- cnt/=4;
- I64 cap=4*(cnt+1);
- while(text[ed->curx]==' ') {
- if(ed->curx>=cap) break;
- ed->curx++;
- }
- if(ox==ed->curx) goto next;
- ed->_curx=ed->curx;
- Free(text);
- return;
- }
- next:
- Free(text);
- if(ed->curx+1>=RopeLength(rline->text)) {
- rline=rline->next;
- if(rline) {
- ed->_curx=ed->curx=0;
- ed->cury++;
- } else {
- ed->_curx=ed->curx=RopeLength(GetLine(ed,ed->cury)->text);
- }
- } else ed->_curx=++ed->curx;
-}
-U0 EdLeft(CEditor *ed) {
- CLine *lline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(lline->text);
- I64 x=ed->curx,cnt=1;
- if(x) {
- while(--x&&text[x]==' ') cnt++;
- if(!x&&cnt) {
- cnt/=4;
- if(cnt)
- ed->_curx=ed->curx=4*(cnt-1);
- else
- ed->_curx=ed->curx=0;
- Free(text);
- return;
- }
- }
- Free(text);
- if(ed->curx==0) {
- lline=lline->prev;
- if(lline) {
- ed->_curx=ed->curx=RopeLength(lline->text);
- ed->cury--;
- } else {
- ed->_curx=ed->curx=0;
- }
- } else ed->_curx=--ed->curx;
-}
-U0 EdWordLeft(CEditor *ed) {
- CLine *lline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(lline->text);
- I64 idx=ed->curx;
- Bool hit_word=FALSE;
- if(idx!=0) idx--;
- while(idx>0) {
- if(Bt(char_bmp_alpha_numeric,text[idx])) {
- hit_word=TRUE;
- } else if(hit_word)
- break;
- idx--;
- }
- if(idx==0) {
- lline=lline->prev;
- if(!lline)
- ed->_curx=ed->curx=0;
- else
- ed->_curx=ed->curx=RopeLength(lline->text)-1,ed->cury--; //-1 ignores newline
- } else
- ed->_curx=ed->curx=idx;
- Free(text);
-}
-U0 EdWordRight(CEditor *ed) {
- CLine *lline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(lline->text);
- I64 idx=ed->curx;
- Bool hit_word=FALSE;
- idx++;
- I64 len=RopeLength(lline->text);
- while(idx<len) {
- if(!text[idx]) break;
- if(Bt(char_bmp_alpha_numeric,text[idx])) {
- hit_word=TRUE;
- } else if(hit_word)
- break;
- idx++;
- }
- if(idx==len) {
- lline=lline->next;
- if(lline) {
- ed->cury++;
- ed->_curx=ed->curx=0;
- }
- } else
- ed->_curx=ed->curx=idx;
- Free(text);
-}
-U0 EdBackspace(CEditor *ed) {
- CLine *bline=GetLine(ed,ed->cury);
- I64 eoff=GetLineOffset(ed,ed->cury);
- I64 ox=ed->curx,oy=ed->cury;
- EdLeft(ed);
- if(ox==0) {
- //Kill Newline on previous line
- if(bline->prev) {
- I64 no=RopeLength(bline->prev->text)-1; //ignore newline
- EditorDelText(ed, eoff-1, eoff,TRUE);
- ed->_curx=ed->curx=no;
- return;
- } else {
- //Do nothing
- }
- } else {
- U8 *text=Rope2Str(bline->text);
- I64 cnt=0,orig=ox;
- while(--ox&&text[ox]==' ') cnt++;
- if(!ox&&cnt) {
- cnt/=4;
- EditorDelText(ed,eoff,eoff+orig,TRUE);
- Free(text);
- ed->curx=ed->_curx=0;
- //text=MStrPrint("%*c",cnt,' ');
- //EditorInsText(ed,text,eoff);
- //ed->curx=ed->_curx=StrLen(text);
- } else {
- EditorDelText(ed, eoff+orig-1, eoff+orig,TRUE);
- }
- Free(text);
- }
-}
-U0 EdPageDown(CEditor *ed) {
- //Check if there is enough room for a page down
- CLine *lline=GetLine(ed,ed->cury);
- I64 cnt=SDL_WinY(ed->window),cnt2=0;
- while(lline&&--cnt>=0) {
- lline=lline->next;
- cnt2++;
- }
- if(!lline) cnt2--;
- ed->vp_start_line+=cnt2;
- ed->cury+=cnt2;
- lline=GetLine(ed,ed->cury);
- if(RopeLength(lline->text)>=ed->_curx) ed->curx=RopeLength(lline->text);
-}
-U0 EdPageUp(CEditor *ed) {
- ed->vp_start_line-=SDL_WinY(ed->window);
- ed->vp_start_line=MaxI64(ed->vp_start_line,0);
- CLine *lline=GetLine(ed,ed->vp_start_line);
- ed->cury=ed->vp_start_line;
- if(RopeLength(lline->text)>=ed->_curx) ed->curx=RopeLength(lline->text);
-}
-U0 FreeEditor(CEditor *ed);
-I64 EdSearch(CEditor *ed) {
- static U8 prevs[1024];
- CEditor *sed=EditorNew();
- goto resize;
-loop:
- I64 key=GetKey;
- switch(key) {
- case ERR:
- goto loop;
- case ED_KEY_RESIZE:
-resize:
- SDL_DrawWin(ed->window);
- sed->window->begy=SDL_WinY(ed->window)-1;
- goto mvsrncur;
- case ED_KEY_CTRL_UP:
- case ED_KEY_UP: //TODO
- goto mvsrncur;
- case ED_KEY_CTRL_DOWN:
- case ED_KEY_DOWN: //TODO
- goto mvsrncur;
- case ED_KEY_RIGHT:
- EdRight(sed);
- goto mvsrncur;
- case ED_KEY_LEFT:
- EdLeft(sed);
- goto mvsrncur;
- case ED_KEY_REDRAW: goto mvsrncur;
- case ED_KEY_CTRL_LEFT:
-left:
- EdWordLeft(sed);
- goto mvsrncur;
- case ED_KEY_CTRL_RIGHT:
- EdWordRight(sed);
- goto mvsrncur;
- case ED_KEY_BACKSPACE:
- //Check for a tab
- EdBackspace(sed);
- goto mvsrncur;
- case ED_KEY_INSERT: //TODO
- goto mvsrncur;
- case ED_KEY_DELETE: //TODO
- goto mvsrncur;
- default:
- if(key=='\n') {
- U8 *needle=Rope2Str(sed->lines->text); //Only one line
- if(StrFirstOcc(needle,"\n")) *StrFirstOcc(needle,"\n")=0;
- if(StrLen(needle))
- StrCpy(prevs,needle);
- else {
- Free(needle);
- needle=StrNew(prevs);
- }
- I64 origln=ed->cury;
- I64 curln=origln;
- CLine *ln=GetLine(ed, ed->cury);
- I64 lnoff=ed->curx;
- Bool wrapped_around=FALSE;
-loop2:
- while(ln) {
- U8 *txt=Rope2Str(ln->text);
- U8 *find=StrIMatch(txt+lnoff,needle);
- Free(txt);
- if(find) {
- ed->cury=curln;
- ed->_curx=ed->curx=find-txt+StrLen(needle);
- Free(needle);
- goto en;
- }
- if(wrapped_around&&curln==origln) goto fail;
- lnoff=0;
- ln=ln->next;
- curln++;
- }
- ln=ed->lines;
- curln=0;
- wrapped_around=TRUE;
- goto loop2;
-fail:
- Free(needle);
- goto en;
- }
- I64 soff=GetLineOffset(sed, sed->cury)+sed->curx++;
- U8 buffer[2]= {key,0};
- EditorInsText(sed,buffer,soff,TRUE);
- }
-mvsrncur:
- DrawEditor(ed,ED_DRAW_DFT|ED_DRAW_NO_RENDER);
- sed->window->y=SDL_WinY(ed->window)-1;
- DrawEditor(sed,ED_DRAW_SEARCH|ED_DRAW_NO_RENDER);
- SDL_DrawWin(ed.window,sed.window);
- goto loop;
-en:
- DrawEditor(ed);
- FreeEditor(sed);
-}
-I64 Edit(CEditor *ed);
-//interactive tells us to enter the autcomplete
-Bool DrawAutocomplete(CEditor *parent,Bool interactive=FALSE) {
- Bool ret=FALSE;
- I64 wx1=0;
- I64 wy1=0;
- I64 sw=SDL_WinX(parent->window);
- I64 sh=SDL_WinY(parent->window);
- CLine *ln=GetLine(parent, parent->cury);
- U8 *text=Rope2Str(ln->text);
- I64 idx=parent->curx;
- if(idx==0) goto fin;
- --idx;
-loop0:
- if(idx==0) goto begin;
- switch(text[idx]) {
- case 'a'...'z':
- case 'A'...'Z':
- case '0'...'9':
- case '_':
- idx--;
- goto loop0;
- default:
- idx++;
- }
-begin:
- if(idx==parent->curx) goto fin;
- I64 screenx=wx1+parent->curx-parent->x_scroll;
- I64 screeny=wy1+parent->cury-parent->vp_start_line+parent->margin_top;
- I64 len=parent->curx-idx;
- U8 *sub=StrNCpy(MAlloc(len+1),text+idx,len);
- if(StrLen(sub)) ret=TRUE;
- I64 cnt;
- I64 active=-1;
-loop:
- CTrie **ents=FuzzyMatch(parent->tags, sub, &cnt);
- if(!cnt) goto free;
- I64 maxlen=StrLen(ents[cnt-1]->fullname); //Ents are sorted by length
- if(screenx+1<sw&&screeny+1<sh) {
- CSDL_TextWin *ac=SDL_NewTextWin(MinI64(maxlen,sw-screenx-wx1),MinI64(cnt,sh-screeny-wy1));
- ac->begx=screenx+1,ac->begy=screeny+1;
- I64 iter=0;
- for(; iter<cnt; iter++) {
- len=StrLen(ents[iter]->fullname);
- I64 chr=0;
- if(iter==active)
- ac->cur_cp=CP_AC_SEL;
- else
- ac->cur_cp=CP_AC_UNSEL;
- ac->y=iter,ac->x=0;
- I64 cap=SDL_WinX(ac);
- WriteWithinWin(ac,ents[iter]->fullname);
- while(len++<cap) {
- SDL_AddCh(ac,' ');
- }
- }
- DrawEditor(parent, ED_DRAW_DFT|ED_DRAW_NO_RENDER);
- SDL_DrawWin(parent->window, ac);
- SDL_DestroyTextWin(ac);
- }
- if(interactive) {
-winput:
- I64 key=GetKey();
- switch(key) {
- case ERR:
- goto winput;
- case ED_KEY_UP:
- active=MaxI64(0,--active);
- goto loop;
- case ED_KEY_DOWN:
- active=MinI64(cnt-1,++active);
- goto loop;
- case '\n':
- if(active==-1) active=0;
- I64 off=GetLineOffset(parent,parent->cury);
- EditorDelText(parent, off+idx,off+parent->curx,TRUE);
- EditorInsText(parent, ents[active]->name, off+idx,TRUE);
- parent->_curx=parent->curx=(idx+StrLen(ents[active]->name));
- goto free;
- default:
- goto free;
- }
- }
-free:
- Free(ents),Free(sub);
-fin:
- Free(text);
- SDL_DrawWin(parent->window);
- return ret;
-}
-class CMenuEnt {
- U8 *name;
- U8 key;
- I64(*callback)(CEditor *ed);
-};
-U8 *Editor2Str(CEditor *ed,I64 *cnt) {
- CLine *lns=ed->lines;
- I64 len=0;
- while(lns) {
- len+=RopeLength(lns->text);
- lns=lns->next;
- }
- U8 *ret=MAlloc(len+1);
- lns=ed->lines,len=0;
- while(lns) {
- U8 *tmp=Rope2Str(lns->text);
- StrCpy(ret+len,tmp);
- Free(tmp);
- len+=RopeLength(lns->text);
- lns=lns->next;
- }
- if(cnt) *cnt=len;
- return ret;
-}
-U8 *FileDialog(CEditor *parent);
-I64 GotoSymbol(CEditor *ed);
-I64 SaveDocAs(CEditor *ed);
-/**
- * This will color the lines based on diagnostitc
- */
-U0 MarkLineColors(CEditor *ed) {
- if(!ed->fn) return;
- CLine *line=ed->lines;
- while(line) {
- line->flags&=~(ED_LNF_WARN|ED_LNF_ERR);
- line=line->next;
- }
- CDiag *diag=ed->diags;
- while(diag) {
- if(0!=StrCmp(diag->fn,ed->fn)) goto next;
- line=GetLine(ed,diag->ln-1); //Diag lines are 1 indexes
- if(line) {
- //Errors>warning
- if(line->flags&ED_LNF_ERR) goto next;
- if(diag->type==DIAG_ERR) {
- line->flags&=~ED_LNF_WARN;
- line->flags|=ED_LNF_ERR;
- line->diag=diag;
- } else {
- line->flags|=ED_LNF_WARN;
- line->diag=diag;
- }
- } else ;//???
- next:
- diag=diag->next;
- }
-}
-I64 SaveDoc(CEditor *ed) {
- if(!ed->fn) {
- SaveDocAs(ed);
- } else {
- CSDL_TextWin *msgs=SDL_NewTextWin(SDL_WinX(ed->window),SDL_WinY(ed->window));
- SDL_Print(msgs,"SAVING FILE\n");
- SDL_DrawWin(msgs);
- U8 *etxt=Editor2Str(ed,&cnt);
- FileWrite(ed->fn,etxt,cnt);
- Free(etxt);
- FreeTrie(ed->tags);
- FreeDiags(ed->diags);
- SDL_Print(msgs,"Generating tags and diagnostics.\n");
- SDL_DrawWin(msgs);
- CreateTagsAndErrorsFiles("TAGS","ERRS",ed->fn);
- SDL_Print(msgs,"Parsing Tags.\n");
- SDL_DrawWin(msgs);
- ed->tags=ReadTags("TAGS");
- ed->diags=ParseDiags("ERRS");
- SDL_Print(msgs,"Garbage collecting.\n");
- SDL_DrawWin(msgs);
- GC_Collect();
- MarkLineColors(ed);
- SDL_DrawWin(ed->window);
- }
- return ED_RET_OK;
-}
-
-I64 SaveDocAs(CEditor *ed) {
- U8 *new=FileDialog(ed);
- if(new) {
- Free(ed->fn);
- ed->fn=new;
- SaveDoc(ed);
- }
- return ED_RET_OK;
-}
-I64 OpenDoc(CEditor *ed) {
- U8 *new=FileDialog(ed);
- if(new) {
- I64 ret=OpenFile(new);
- return ret;
- }
- return ED_RET_OK;
-}
-U0 DrawMenuDropdown(CEditor *ed,CMenuEnt *ent,I64 off,I64 active=-1) {
- I64 x=0;
- I64 he=SDL_WinY(ed->window);
- I64 w=SDL_WinX(ed->window);
- I64 mwidth=0;
- I64 h=0;
- while(ent[h].name) {
- mwidth=MaxI64(mwidth,StrLen(ent[h].name));
- h++;
- }
- if(!h) return;
- CSDL_TextWin *win=SDL_NewTextWin(MinI64(mwidth,w),MinI64(h, he-1));
- win->begy=1;
- I64 i;
- for(i=0; i!=h; i++) {
- if(active==i) win->cur_cp=CP_AC_SEL;
- else win->cur_cp=CP_AC_UNSEL;
- win->y=i,win->x=0;
- SDL_Print(win,ent[i].name);
- I64 len=StrLen(ent[i].name);
- while(len++<mwidth) SDL_AddCh(win,' ');
- }
- DrawEditor(ed,ED_DRAW_DFT|ED_DRAW_NO_RENDER);
- SDL_DrawWin(ed->window,win);
- SDL_DestroyTextWin(win);
-}
-I64 BufferSelect(CEditor *ed);
-//Draws at first line
-U0 AddMenuBar(CEditor *ed,I64 active=-1) {
- I64 ret=ED_RET_OK;
- ed->margin_top=1;
- CMenuEnt File[]= {
- {"[S]ave",'s',&SaveDoc},
- {"Save [A]s",'a',&SaveDocAs},
- {"[O]pen File",'o',&OpenDoc},
- {"[B]uffer Select",'b',&BufferSelect},
- {NULL,0,NULL},
- };
- CMenuEnt Code[]= {
- {"[G]oto Symbol",'g',&GotoSymbol},
- {"[C]ompile Check",'c',&ShowDiagsWindow},
- {NULL,0,NULL},
- };
- I64 x=getbegx(stdscr);
- I64 y=getbegy(stdscr);
- I64 w=getmaxx(stdscr);
- class {
- CMenuEnt *spec;
- U8 *name;
- U8 key;
- } cats[]= {
- {&File,"[F]ile",'f'},
- {&Code,"[C]ode",'c'},
- };
- I64 cnt=sizeof(cats)/sizeof(*cats),cur,active_sub=0;
- goto draw;
-loop:
- I64 key=GetKey();
- switch(key) {
- case ERR: goto loop;
- case ED_KEY_ESCAPE: goto en;
- case ED_KEY_UP:
- active_sub=MaxI64(0,--active_sub);
- break;
- case ED_KEY_DOWN:
- if(cats[active].spec[++active_sub].name==NULL) --active_sub;
- break;
- case ED_KEY_LEFT:
- active=MaxI64(0,--active),active_sub=0;
- break;
- case ED_KEY_RIGHT:
- active=MinI64(cnt-1,++active),active_sub=0;
- break;
- case ED_KEY_REDRAW: goto draw;
- case '\n':
- if(cats[active].spec[active_sub].callback)
- ret=(cats[active].spec[active_sub].callback[0])(ed);
- goto en;
- default:
- I64 s=0;
- if(active!=-1)
- for(; cats[active].spec[s].name; s++) {
- if(cats[active].spec[s].key==key) {
- ret=(cats[active].spec[s].callback[0])(ed);
- goto en;
- }
- }
- }
-draw:
- ed->window->x=ed->window->y=0;
- I64 off=0,sel_off=-1;
- for(cur=0; cur!=cnt; cur++) {
- if(cur==active) {
- ed->window->cur_cp=CP_MENU_SEL;
- sel_off=cur;
- } else
- ed->window->cur_cp=CP_MENU_UNSEL;
- SDL_Print(ed->window,cats[cur].name);
- if(cur>=active)
- ; //Do Nothing
- else
- off+=StrLen(cats[cur].name);
- }
- SDL_ClrToEOL(ed->window);
- if(sel_off!=-1) {
- DrawEditor(ed, ED_DRAW_DFT&(~ED_DRAW_MENUBAR));
- if(DrawMenuDropdown(ed,cats[active].spec, off,active_sub)==ED_RET_QUIT) return ED_RET_QUIT;
- }
- if(active!=-1)
- goto loop;
-en:
- return ret;
-}
-U0 FreeEditor(CEditor *ed) {
- CLine *ln=ed->lines;
- while(ln) {
- CLine *n=ln->next;
- FreeLine(ln);
- ln=n;
- }
- SDL_DestroyTextWin(ed->window);
- Free(ed->dirty_screen_lines);
- Free(ed->line_cache);
- if(ed->tags) FreeTrie(ed->tags);
- if(ed->diags) FreeDiags(ed->diags);
- Free(ed);
-}
-U8 *RemoveNL(U8 *t) {
- U8 *f;
- if(f=StrFirstOcc(t,"\n")) *f=0;
- return t;
-}
-U8 **FuzzySymbolSelect(CEditor *ed,U8 *str) {
- I64 cnt;
- CTrie **t=FuzzyMatch(ed->tags, str,&cnt);
- U8 **ret=MAlloc((cnt+1)*sizeof(U8*));
- while(--cnt>=0) {
- ret[cnt]=StrNew(t[cnt]->fullname);
- }
- Free(t);
- return ret;
-}
-U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *init=NULL) {
- CEditor *ed=EditorNew();
- if(init) EditorInsText(ed,init,0);
- I64 active=-1,idx;
- if(!init)
- U8 **matches=(*match_cb)(parent,"");
- else
- matches=(*match_cb)(parent,init);
- goto draw;
- loop:
- I64 key=GetKey();
- switch(key) {
- case ERR: goto loop;
- case ED_KEY_ESCAPE:
- for(idx=0;matches[idx];idx++)
- Free(matches[idx]);
- Free(matches);
- return NULL;
- case ED_KEY_UP:
- active=MaxI64(0,--active);
- goto draw;
- case ED_KEY_DOWN:
- if(active==-1) {active=0; goto draw;}
- if(active>=SDL_WinY(ed->window)-1) goto loop;
- if(!matches[active]) goto loop;
- if(!matches[active+1]) goto loop;
- active++;
- goto draw;
- case ED_KEY_CTRL_LEFT:
- EdWordLeft(ed);
- goto draw;
- case ED_KEY_CTRL_RIGHT:
- EdWordRight(ed);
- goto draw;
- case ED_KEY_LEFT:
- left:
- EdLeft(ed);
- goto draw;
- case ED_KEY_BACKSPACE:
- EdBackspace(ed);
- goto update;
- case ED_KEY_REDRAW: goto draw;
- case ED_KEY_RIGHT:
- right:
- EdRight(ed);
- goto draw;
- case '\n':
- U8 *ret=NULL;
- for(idx=0;matches[idx];idx++)
- if(active!=idx) Free(matches[idx]);
- if(active==-1) {
- ret=RemoveNL(Rope2Str(ed->lines->text));
- } else {
- ret=matches[active];
- }
- Free(matches);
- parent->margin_bottom=0;
- SDL_DrawWin(parent->window);
- return ret;
- default:
- U8 buffer[]={key,0};
- EditorInsText(ed, buffer,ed->curx,TRUE);
- update:
- active=-1;
- for(idx=0;matches[idx];idx++)
- Free(matches[idx]);
- Free(matches);
- U8 *t=RemoveNL(Rope2Str(ed->lines->text));
- matches=(*match_cb)(parent,t);
- Free(t);
- if(key!=ED_KEY_BACKSPACE)
- goto right;
- }
- draw:
- FocusCursor(ed);
- if(active==-1)
- ed->window->cur_cp=CP_FUZZY_SEL_A;
- else
- ed->window->cur_cp=CP_FUZZY_UNSEL_A;
- t=RemoveNL(Rope2Str(ed->lines->text));
- ed->window->y=ed->window->x=0;
- SDL_ClrToEOL(ed->window);
- WriteWithinView(ed,t, 0);
- idx=1;
- for(;idx<SDL_WinY(ed->window);idx++) {
- if(!matches[idx-1]) break;
- U8 *mat=matches[idx-1];
- U8 *tc=t;
- I64 offset=0;
- ed->window->y=idx,ed->window->x=0;
- hl:
- if(active==idx-1)
- ed->window->cur_cp=CP_FUZZY_SEL_A;
- else
- ed->window->cur_cp=CP_FUZZY_UNSEL_A;
- U8 buffer2[]={*(tc++),0};
- U8 *chr=StrFirstOcc(mat,buffer2);
- if(!chr) {
- WriteWithinView(ed,mat, offset);
- mat+=StrLen(mat);
- } else {
- U8 *slice=StrNCpy(MAlloc(chr-mat+1),mat,chr-mat);
- WriteWithinView(ed,slice, offset);
- mat+=StrLen(slice);
- offset+=StrLen(slice);
- Free(slice);
- if(active==idx-1)
- ed->window->cur_cp=CP_FUZZY_SEL_B;
- else
- ed->window->cur_cp=CP_FUZZY_UNSEL_B;
- WriteWithinView(ed,buffer2, offset++);
- mat++;
- }
- if(*mat) goto hl;
- SDL_ClrToEOL(ed->window);
- }
- for(;idx<SDL_WinY(ed->window);idx++) {
- ed->window->y=idx,ed->window.x=0;
- SDL_ClrToEOL(ed->window);
- }
- ed->window->cury=0,ed->window->curx=ed->curx-ed->x_scroll;
- ed->window->cur_enabled=TRUE;
- SDL_DrawWin(ed->window);
- ed->window->cur_enabled=FALSE;
- Free(t);
- goto loop;
-}
-I64 OpenFile(U8 *name,I64 ln=0) {
- loop:
- CDirEntry *find=FilesFind(name,FUF_SINGLE);
- if(find) {
- DirEntryFree(find);
- name=FileNameAbs(name);
- } else {
- name=StrNew(name);
- FileWrite(name,"",0);
- goto loop;
- }
- CBuffer *buf;
- if(buf=HashFind(name,buffers)) {
- Free(name);
- buf->ed->cury=MinI64(ln,GetLineCount(buf->ed));
- return Edit(buf->ed);
- }
- I64 cnt;
- U8 *text=FileRead(name,&cnt);
- if(!text) return ED_RET_OK;
- CEditor *new=EditorNew();
- EditorInsText(new,text,0);
- new->fn=StrNew(name);
- new->cury=MinI64(ln,GetLineCount(new));
- Free(text);
- CreateTagsAndErrorsFiles("TAGS","ERRS",new->fn);
- new->tags=ReadTags("TAGS");
- new->diags=ParseDiags("ERRS");
- MarkLineColors(new);
- buf=MAlloc(sizeof(*buf));
- buf->str=StrNew(name);
- buf->ed=new;
- HashAdd(buf,buffers);
- Free(name);
- return Edit(new);
-}
-U8 **FuzzyFile(CEditor *ed,U8 *pat) {
- U8 *pat2=MStrPrint("%s*",pat);
- CDirEntry *ents=FilesFind(pat2);
- Free(pat2);
- CDirEntry *orig=ents;
- I64 cnt=0;
- while(ents) {
- ents=ents->next,cnt++;
- }
- U8 **ret=MAlloc(sizeof(U8*)*(++cnt));
- ents=orig,cnt=0;
- while(ents) {
- ret[cnt++]=StrNew(ents->name);
- ents=ents->next;
- }
- if(orig)
- DirEntryFree(orig);
- return ret;
-}
-I64 GotoSymbol(CEditor *ed) {
- U8 *str=FuzzySelectWindow(ed,&FuzzySymbolSelect);
- if(!str) return ED_RET_OK;
- U8 *orig=str;
- CTrie *tags=ed->tags;
- while(*str&&tags) {
- try {
- tags=tags->ents[TrieChrIdx(*str++)];
- } catch {
- Fs->catch_except=1;
- return ED_RET_OK;
- }
- }
- Free(orig);
- if(tags)
- return OpenFile(tags->fn, tags->ln);
- return ED_RET_OK;
-}
-U8 *FileDialog(CEditor *parent) {
- U8 * fn=NULL;
- loop:
- fn=FuzzySelectWindow(parent, &FuzzyFile,fn);
- if(!fn) return fn;
- if(IsDir(fn)) {
- U8 *dir;
- #if IsWindows
- dir=MStrPrint("%s\\",fn);
- #else
- dir=MStrPrint("%s/",fn);
- #endif
- Free(fn);
- fn=dir;
- goto loop;
- }
- return fn;
-}
-U8 **FuzzyBufferSel(CEditor *ed,U8 *pat) {
- U8 **ret=NULL,*orig=pat;
- loop:
- I64 cnt=buffers->mask+1,cnt2=0;
- while(--cnt>=0) {
- CBuffer *bucket=buffers->body[cnt];
- for(;bucket;bucket=bucket->next) {
- U8 *str=bucket->str;
- pat=orig;
- next:
- if(!*pat) {
- if(ret)
- ret[cnt2]=StrNew(bucket->str);
- cnt2++;
- goto cont;
- }
- U8 buffer[]={*pat++,0};
- str=StrFirstOcc(str,buffer);
- if(str) {
- str++;
- goto next;
- }
- cont:
- }
- }
- if(!ret) {
- ret=MAlloc(sizeof(U8*)*(1+cnt2));
- goto loop;
- }
- return ret;
-}
-I64 BufferSelect(CEditor *ed) {
- U8 *sel=FuzzySelectWindow(ed,&FuzzyBufferSel);
- if(sel) {
- CBuffer *buf=HashFind(sel,buffers);
- I64 ret=Edit(buf->ed);
- Free(sel);
- return ret;
- }
- return ED_RET_OK;
-}
-I64 EdOffset(CEditor *ed) {
- return GetLineOffset(ed,ed->cury)+ed->curx;
-}
-I64 EdClearSelect(CEditor *ed) {
- ed->sel_start=ed->sel_end;
-}
-I64 EdSelLeft(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdLeft(ed);
- ed->sel_end=EdOffset(ed);
-}
-I64 EdSelRight(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdRight(ed);
- ed->sel_end=EdOffset(ed);
-}
-I64 EdSelUp(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdUp(ed);
- ed->sel_end=EdOffset(ed);
-}
-I64 EdSelDown(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdDown(ed);
- ed->sel_end=EdOffset(ed);
-}
-U0 EdDelSel(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) return;
- if(ed->sel_start>ed->sel_end) SwapI64(&ed->sel_end,&ed->sel_start);
- EditorDelText(ed,ed->sel_start,ed->sel_end,TRUE);
- EdJumpToChar(ed,ed->sel_start);
- ed->sel_start=ed->sel_end=-1;
-}
-U8 *EdGetSelText(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) return NULL;
- if(ed->sel_start>ed->sel_end) {
- SwapI64(&ed->sel_end,&ed->sel_start);
- }
- U8 *ret=MAlloc(ed->sel_end-ed->sel_start+1);
- I64 cnt=GetLineCount(ed),idx=0;
- I64 offset=0,reti=0;
- for(;idx!=cnt;idx++) {
- offset=GetLineOffset(ed,idx);
- CRope *text;
- I64 en=RopeLength(text=GetLine(ed,idx)->text);
- if(ed->sel_start>=offset) {
- I64 st=MaxI64(ed->sel_start-offset,0);
- en=MinI64(en,ed->sel_end-offset);
- if(st>en) goto next;
- U8 *lntxt=Rope2Str(text);
- StrNCpy(ret+reti,lntxt+st,en-st);
- Free(lntxt);
- reti+=en-st;
- if(reti>=ed->sel_end-ed->sel_start) {
- goto ret;
- }
- next:
- }
- }
- ret:
- return ret;
-}
-I64 Edit(CEditor *ed) {
- goto mvsrncur;
-loop:
- I64 key=GetKey,cnt,cnt2;
- if(key==ERR) goto loop;
- I64 eoff,soff;
- switch(key) {
- case 'e'&0x1f:
- if(ed->diags)
- if(ED_RET_QUIT==ShowDiagsWindow(ed)) return ED_RET_QUIT;
- break;
- /**
- * [F]ile
- * [C]ode
- */
- case 'c'&0x1f:
- U8 *clip=EdGetSelText(ed);
- SDL_SetClipboardText(clip);
- EdClearSelect(ed);
- goto mvsrncur;
- case 'v'&0x1f:
- EdDelSel(ed);
- clip=SDL_GetClipboardText();
- EditorInsText(ed,clip,GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
- I64 righti=StrLen(clip);
- Free(clip);
- while(--righti>=0) EdRight(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_UP:
- EdSelUp(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_DOWN:
- EdSelDown(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_LEFT:
- EdSelLeft(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_RIGHT:
- EdSelRight(ed);
- goto mvsrncur;
- case ED_KEY_ESCAPE:
- case ALT_KEY('f'):
- if(DrawEditor(ed,ED_DRAW_DFT,,0)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
- goto mvsrncur;
- case ALT_KEY('c'):
- if(DrawEditor(ed,ED_DRAW_DFT,,1)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
- goto mvsrncur;
- case ED_KEY_RESIZE:
- goto mvsrncur;
- case ED_KEY_UP:
- EdClearSelect(ed);
- EdUp(ed);
- goto mvsrncur;
- case ED_KEY_DOWN:
- EdClearSelect(ed);
- EdDown(ed);
- goto mvsrncur;
- case ED_KEY_REDRAW: goto mvsrncur;
- case ED_KEY_LEFT:
-left:
- EdClearSelect(ed);
- EdLeft(ed);
- goto mvsrncur;
- case ED_KEY_RIGHT:
-right:
- EdClearSelect(ed);
- EdRight(ed);
- goto mvsrncur;
- case ED_KEY_END:
- EdClearSelect(ed);
- ed->_curx=ed->curx=0;
- goto mvsrncur;
- case ED_KEY_HOME:
- EdClearSelect(ed);
- CLine *heline=GetLine(ed,ed->cury);
- ed->_curx=ed->curx=RopeLength(heline->text);
- goto mvsrncur;
- case ED_KEY_CTRL_UP:
- EdClearSelect(ed);
- goto pageup;
- case ED_KEY_CTRL_DOWN:
- EdClearSelect(ed);
- goto pagedown;
- case ED_KEY_CTRL_LEFT:
- EdClearSelect(ed);
- EdWordLeft(ed);
- goto mvsrncur;
- case ED_KEY_CTRL_RIGHT:
- EdClearSelect(ed);
- EdWordRight(ed);
- goto mvsrncur;
- case ED_KEY_BACKSPACE:
- if(ed->sel_start!=ed->sel_end)
- EdDelSel(ed);
- else
- EdBackspace(ed);
- goto mvsrncur;
- case ED_KEY_PAGEUP:
-pageup:
- EdPageUp(ed);
- goto mvsrncur;
- case ED_KEY_PAGEDOWN:
-pagedown:
- EdPageDown(ed);
- goto mvsrncur;
- case '\t':
- if(!DrawAutocomplete(ed,TRUE)) {
- EditorInsText(ed," ",GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
- ed->curx+=4;
- }
- goto mvsrncur;
- case 'y'&0x1f:
- Redo(ed);
- goto mvsrncur;
- case 'z'&0x1f:
- Undo(ed);
- goto mvsrncur;
- case 'b'&0x1f:
- BufferSelect(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- case 't'&0x1f:
- GotoSymbol(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- case 'o'&0x1f:
- OpenDoc(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- case 's'&0x1f:
- SaveDoc(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- default:
- if(key==('q'&0x1f)) {return ED_RET_QUIT;}
- if(key==('f'&0x1f)) {
- EdSearch(ed);
- goto mvsrncur;
- }
- soff=GetLineOffset(ed, ed->cury)+ed->curx++;
- U8 buffer[2]= {key,0};
- EditorInsText(ed,buffer,soff,TRUE);
- if(key=='\n') {
- CLine *prev=GetLine(ed,ed->cury);
- EdRight(ed);
- U8 *margin=MStrPrint("%*c",IndentLevel(prev),' ');
- EditorInsText(ed,margin,soff+1,TRUE);
- ed->_curx=ed->curx=4*IndentLevel(prev);
- }
- goto mvsrncur;
- }
-mvsrncur:
- //Move cursor left if at newline
- CLine *lline=GetLine(ed,ed->cury);
- if(ed->curx+1>RopeLength(lline->text)) ed->curx=RopeLength(lline->text)-1;
- DrawEditor(ed,ED_DRAW_DFT);
- goto loop;
-exit:
- return ED_RET_OK;
-}
-/*
-EditorInsText(ed,"if(Potato)\nx{3.14 'abc\\'def\\\\'}\n",0);
-EditorInsText(ed,"Tom\nato\n",4);
-DrawEditor(ed);
-FreeEditor(ed);
-CEditor *ed=EditorNew();
-EditorInsText(ed,"012\n345\n678\n9ab",0);
-EditorDelText(ed,1,2);
-EditorDelText(ed,1,15-1);
-DrawEditor(ed);
-*/
-SDL_InitScr;
-CEditor *ed=EditorNew(TRUE);
-Edit(ed);
-SDL_ExitScr;
-
-
diff --git a/HolyEd/_EDITOR2.HC b/HolyEd/_EDITOR2.HC
deleted file mode 100644
index 9445553..0000000
--- a/HolyEd/_EDITOR2.HC
+++ /dev/null
@@ -1,2674 +0,0 @@
-#include "KEYS2.HC"
-#include "ROPE.HC"
-#include "FONT.HC"
-#define EDIT_UNUSED 0
-#define EDIT_INS_STR 3
-#define EDIT_DEL_STR 4
-class CUndoInfo {
- I64 type;
- I64 at;
- union {
- U8 inserted_char;
- U8 removed_char;
- U8* inserted_str;
- U8* removed_str;
- };
-};
-#define UNDO_INFO_LENGTH 512
-#define TAG_MACRO 1
-#define TAG_UNION 2
-#define TAG_CLASS 3
-#define TAG_VAR 4
-#define TAG_FUNC 5
-CHashTable *TagFiles=HashTableNew(1<<7);
-class CTrie {
- CTrie *ents[26+10+1+1]; //a...z/0-9/_/.
- U8 *fn; //From TagFiles
- U8 *fullname;
- U8 * name;
- I64 ln;
- U8 kind;
-};
-I64 TrieChrIdx(U8 chr) {
- I64 idx;
- switch(chr) {
- case '0'...'9':
- idx=26+chr-'0';
- break;
- case 'a'...'z':
- idx=chr-'a';
- break;
- case 'A'...'Z':
- idx=chr-'A';
- break;
- case '_':
- idx=26+10;
- break;
- case '.':
- idx=26+10+1;
- break;
- default:
- idx=-1;
- }
- return idx;
-}
-CTrie *TrieIns(CTrie *t,U8 *name,CTrie * child) {
- if(!*name) {
- t->name=StrNew(child->name);
- t->fullname=child->fullname;
- t->fn=child->fn;
- t->ln=child->ln;
- t->kind=child->kind;
- Free(child);
- return child;
- }
- I64 idx=TrieChrIdx(*name);
- CTrie *b=t->ents[idx];
- if(!b)
- t->ents[idx]=MAlloc(sizeof(CTrie));
- TrieIns(t->ents[idx],name+1,child);
- return t;
-}
-U0 FreeTrie(CTrie *t) {
- if(!t) return;
- I64 cnt=sizeof(t->ents)/sizeof(*t->ents);
- while(--cnt>=0) {
- FreeTrie(t->ents[cnt]);
- }
- Free(t->name);
- Free(t->fullname);
- Free(t);
-}
-CTrie *TagNew(U8 *fullname,U8 *name,U8 *fn,I64 ln,U8 kind) {
- CTrie *t=MAlloc(sizeof(CTrie));
- t->name=StrNew(name);
- t->fullname=StrNew(fullname);
- t->ln=ln;
- t->kind=kind;
-loop:
- CHash *ff=HashFind(fn,TagFiles);
- if(ff) {
- t->fn=ff->str;
- } else {
- CHash *new=MAlloc(sizeof(CHash));
- new->str=StrNew(fn);
- HashAdd(new,TagFiles);
- goto loop;
- }
- return t;
-}
-CTrie *ReadTags(U8 *file) {
- CTrie *ret=MAlloc(sizeof(CTrie));
- I64 len;
- U8 *text=FileRead(file,&len);
- U8 *en=text+len,*fullname;
- U8 buf1[256],buf2[256],buf3[256];
- U8 *_buf1=buf1,*_buf2=buf2,*_buf3=buf3;
- I64 ln;
-loop:
- if(text!=en) {
- text=StrScan(text,"%s\t%s\t",&_buf1,&_buf2);
- ln=Str2I64(text,,&text);
- fullname=StrNew(buf1);
- U8 type=TAG_VAR;
- if(*text==';') {
- text++;
-attrloop:
- if(*text=='\t') {
- text++;
- if(0==StrNCmp("kind:",text,len=StrLen("kind:"))) {
- text+=len;
- switch(*text) {
- case 'c':
- type=TAG_CLASS;
- break;
- case 'm':
- type=TAG_MACRO;
- break;
- case 'f':
- type=TAG_FUNC;
- break;
- case 'u':
- type=TAG_UNION;
- break;
- case 'v':
- type=TAG_VAR;
- break;
- default:
- throw('InvType');
- }
- text++;
- goto attrloop;
- }
- if(0==StrNCmp("struct:",text,len=StrLen("struct:"))) {
- text+=len;
- U8 *tdelim=StrFirstOcc(text,"\x0d\n\t");
- U8 *ofclass=StrNCpy(MAlloc(tdelim-text+1),text,tdelim-text);
- ofclass[tdelim-text]=0;
- Free(fullname);
- fullname=MStrPrint("%s.%s",ofclass,buf1);
- text=tdelim;
- goto attrloop;
- }
- if(0==StrNCmp("union:",text,len=StrLen("union:"))) {
- text+=len;
- tdelim=StrFirstOcc(text,"\x0d\n\t");
- ofclass=StrNCpy(MAlloc(tdelim-text+1),text,tdelim-text);
- ofclass[tdelim-text]=0;
- Free(fullname);
- fullname=MStrPrint("%s.%s",ofclass,buf1);
- text=tdelim;
- goto attrloop;
- }
- } else if(*text==0x0d) {
- //Cariage return
- text++;
- if(*text++=='\n')
- goto ins;
- }
- else if(*text++=='\n')
- goto ins;
- else {
- "%s\n",text;
- throw('Tag');
- }
- } else if(*text++!='\n') {
- "%s\n",text;
- throw('Tag');
- }
-ins:
- TrieIns(ret,fullname,TagNew(fullname,buf1,buf2,ln,type));
- Free(fullname);
- goto loop;
- }
-en:
- Free(text);
- return ret;
-}
-#define DIAG_WARN 0
-#define DIAG_ERR 1
-class CDiag {
- CDiag *prev,*next;
- I64 type,ln,col;
- //From TagFiles
- U8 *fn,*msg;
-};
-CDiag *ParseDiags(U8 *file) {
- I64 cnt,len;
- U8 *text=FileRead(file,&cnt);
- U8 *ptr=text;
- CDiag *prev=NULL;
- while(*ptr) {
- CDiag *new=MAlloc(sizeof(CDiag));
- new->prev=prev;
- if(prev) prev->next=new;
- new->fn=MAlloc(1024);
- try {
- //fn:ln:col [WARNING|ERROR] [msg]
- //Filename can contain ':' so ensure a number follows the ':'
- U8 *fnstart=ptr;
- loop:
- U8 *colon=StrFirstOcc(ptr,":");
- if(!colon) goto fail;
- if(Bt(&char_bmp_dec_numeric,colon[1])) {
- StrNCpy(new->fn,fnstart,colon-fnstart);
- ptr=colon+1;
- } else {
- ptr=colon+1;
- goto loop;
- }
- ptr=StrScan(ptr,"%d:%d: ",&new->ln,&new->col);
- if(0==StrNCmp(ptr,"WARNING",len=StrLen("WARNING"))) {
- ptr+=len;
- new->type=DIAG_WARN;
- } else if(0==StrNCmp(ptr,"ERROR",len=StrLen("ERROR"))) {
- ptr+=len;
- new->type=DIAG_ERR;
- }
- U8 *nl=StrFirstOcc(ptr,"\n");
- new->msg=StrNCpy(MAlloc(nl-ptr+1),ptr,nl-ptr);
- prev=new;
- ptr=nl+1;
- } catch {
- Fs->catch_except=TRUE;
- goto fail;
- }
- }
- CDiag *first=prev;
- while(prev) {first=prev;prev=prev->prev;}
- Free(text);
- return first;
- fail:
- Free(text);
- return NULL;
-}
-U0 FreeDiags(CDiag *errs) {
- if(!errs) return;
- FreeDiags(errs->next);
- Free(errs->fn);
- Free(errs->msg);
- Free(errs);
-}
-U0 __FuzzyMatch(CTrie *trie,U8 *name,I64 *cnt,CTrie **dumpto) {
- if(!trie) return;
- if(!*name) {
- if(trie->name) {
- if(dumpto)
- dumpto[*cnt]=trie;
- ++*cnt;
- }
- }
- I64 idx=-1;
- if(*name)
- idx=TrieChrIdx(*name);
- I64 cnt2=sizeof(trie->ents)/sizeof(*trie->ents);
- while(--cnt2>=0) {
- if(cnt2!=idx)
- __FuzzyMatch(trie->ents[cnt2],name,cnt,dumpto);
- else
- __FuzzyMatch(trie->ents[cnt2],name+1,cnt,dumpto);
- }
-}
-I64 MatchCmp(U0 *a,U0 *b) {
- CTrie **A=a,**B=b;
- return StrLen(A[0]->fullname)-StrLen(B[0]->fullname);
-}
-CTrie **FuzzyMatch(CTrie *trie,U8 *name,I64 *cnt=NULL) {
- I64 cnt2=0;
- __FuzzyMatch(trie,name,&cnt2,NULL);
- CTrie **ents=MAlloc(sizeof(CTrie*)*(cnt2+1));
- cnt2=0;
- __FuzzyMatch(trie,name,&cnt2,ents);
- if(cnt) *cnt=cnt2;
- ents[cnt2]=NULL;
- QSort(ents(U8*),cnt2,sizeof(CTrie*),&MatchCmp);
- return ents;
-}
-CHashTable *keywords=HashTableNew(1<<5);
-U0 AddKeyword(U8i *text) {
- CHash *h=MAlloc(sizeof(CHash));
- h->str=StrNew(text);
- h->type=1;
- HashAdd(h,keywords);
-}
-U8 *kws[]= {
- "union",
- "catch",
- "class",
- "try",
- "if",
- "else",
- "for",
- "while",
- "extern",
- "_extern",
- "return",
- "sizeof",
- "intern",
- "do",
- "goto",
- "break",
- "switch",
- "start",
- "end",
- "case",
- "default",
- "public",
- "import",
- "_import",
- "lastclass",
- "static",
- "U0",
- "U8i",
- "I8i",
- "U16i",
- "I16i",
- "U32i",
- "I32i",
- "U64i",
- "I64i",
- "F64",
- "Bool",
- "#include",
- "#exe",
- "#define",
- "#assert",
- "#if",
- "#else",
- "#endif",
- "#ifdef",
- "#ifndef",
-};
-I64 cnt=sizeof(kws)/sizeof(*kws);;
-while(--cnt>=0) {
- AddKeyword(kws[cnt]);
-}
-#define ED_RET_OK 1
-#define ED_RET_QUIT 2
-
-#define ED_LNF_COMMENTED_OUT 1
-#define ED_LNF_COMMENTED_START (1<<1)
-#define ED_LNF_COMMENTED_END (1<<2)
-#define ED_LNF_ERR (1<<3)
-#define ED_LNF_WARN (1<<4)
-class CLine {
- CLine *prev,*next;
- I64 line,length,flags;
- CDiag *diag;
- //Used with ED_LNF_COMMENTED_START
- CLine *commentStart;
- CRope *text;
- //Will be invalided when CEditor.line_cache_size is lesser than line number
- I64 cached_offset;
-};
-I64 IndentLevel(CLine *ln) {
- U8 *txt=Rope2Str(ln->text);
- I64 cnt=0;
- while(txt[cnt]==' ') cnt++;
- cnt/=4;
- Free(txt);
- return cnt;
-}
-//Color pairs
-#define CP_BLANK 0
-#define CP_KW 1
-#define CP_WORD 2
-#define CP_TOK 3
-#define CP_NUM 4
-#define CP_STR 5
-#define CP_WHITE 6
-#define CP_LINUM 7
-#define CP_COMMENT 8
-#define CP_AC_SEL 9
-#define CP_AC_UNSEL 10
-#define CP_MENU_SEL 11
-#define CP_MENU_UNSEL 12
-#define CP_FUZZY_SEL_A 13
-#define CP_FUZZY_UNSEL_A 14
-#define CP_FUZZY_SEL_B 15
-#define CP_FUZZY_UNSEL_B 16
-#define CP_LINUM_ERR 17
-#define CP_LINUM_WARN 18
-#define CP_CURSOR 19
-//TODO
-#define SOL_BLACK 0x000000
-#define SOL_WHITE 0xfdf6e3
-#define SOL_YELLOW 0xb58900
-#define SOL_ORANGE 0xcb4b16
-#define SOL_RED 0xdc322f
-#define SOL_MAGENTA 0xd33682
-#define SOL_BLUE 0x286bd2
-#define SOL_CYAN 0x2aa198
-#define SOL_GREEN 0x859900
-U32 union U_RGBA8888 {
- class {
- U8 b;
- U8 g;
- U8 r;
- U8 a;
- };
-};
-class CSDL_ColorPair {
- U_RGBA8888 fg;
- U_RGBA8888 bg;
-};
-CSDL_ColorPair SDL_ColorPairs[64];
-SDL_Window *global_window=NULL;
-SDL_Surface *global_font=NULL;
-#define FONT_X 8
-#define FONT_Y 8
-U0 SDL_InitScr() {
- global_window=SDL_CreateWindow("HolyEd",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_RESIZABLE);
- global_font=SDL_CreateRGBSurface(0,FONT_X*0x100,FONT_Y,32,0,0,0,0);
- SDL_FillRect(global_font, NULL, 0x00000000);
- I64 cnt=0x100;
- while(--cnt>=0) {
- I64 top=8;
- while(--top>=0) {
- I64 bit=0;
- U8 byte=sys_font_std[cnt].u8[top];
- for(;bit!=8;bit++) {
- if(Bt(&byte,bit)) {
- SDL_Rect pixel={cnt*8+bit,top,1,1};
- SDL_FillRect(global_font,&pixel,0xffffffff);
- }
- }
- }
- }
- SDL_SetColorKey(global_font,1,0x00000000);
- SDL_StartTextInput;
-}
-class CSDL_ScrnChr {
- U8 chr;
- I8 cp; //negative for inverse
-};
-class CSDL_TextWin {
- SDL_Surface *text;
- U8 cur_cp; //From SDL_ColorPairs
- I64 x,y,begx,begy,curx,cury;
- //The charactors on the screen.
- CSDL_ScrnChr *char_cache;
- Bool cur_enabled;
- Bool inverse;
-};
-#define FONT_X 8
-#define FONT_Y 8
-#define FONT_X2 16
-#define FONT_Y2 16
-CSDL_TextWin *SDL_NewTextWin(I64 w,I64 h) {
- CSDL_TextWin *ret=MAlloc(sizeof(CSDL_TextWin));
- ret->text=SDL_CreateRGBSurface(0,w*FONT_X2,h*FONT_Y2,32,0,0,0,0);
- ret->cur_cp=CP_WHITE;
- ret->char_cache=MAlloc(sizeof(CSDL_ScrnChr)*w*h);
- return ret;
-}
-U0 SDL_DestroyTextWin(CSDL_TextWin *win) {
- Free(win->char_cache);
- SDL_FreeSurface(win->text);
- Free(win);
-}
-I64 SDL_WinX(CSDL_TextWin *w) {
- I32 x=w->text->w,y=w->text->h;
- return x/FONT_X2;
-}
-I64 SDL_WinY(CSDL_TextWin *w) {
- I32 x=w->text->w,y=w->text->h;
- return y/FONT_Y2;
-}
-//Pass CSDL_TextWin's
-U0 SDL_DrawWin(...) {
- I64 idx=0;
- I32 winx,winy;
- SDL_GetWindowSize(global_window,&winx,&winy);
- winx/=FONT_X2,winy/=FONT_Y2;
- SDL_Surface *winsurf=SDL_GetWindowSurface(global_window);
- SDL_FillRect(winsurf,NULL,SOL_WHITE);
- for(;idx!=argc;idx++) {
- CSDL_TextWin *w=argv[idx];
- I32 rx=w->text->w,ry=w->text->h;
- SDL_Rect sbox={w->begx*FONT_X2,w->begy*FONT_Y2,rx/FONT_X2*FONT_X2,ry/FONT_Y2*FONT_Y2};
- SDL_BlitSurface(w->text,NULL,winsurf,&sbox);
- if(rx/FONT_X2!=winx||ry/FONT_Y2!=winy) {
- "RESETING\n";
- SDL_FreeSurface(w->text);
- w->text=SDL_CreateRGBSurface(0,winx*FONT_X2,winy*FONT_Y2,32,0,0,0,0);
- Free(w->char_cache);
- w->char_cache=MAlloc(sizeof(CSDL_ScrnChr)*winx*winy);
- }
- if(w->cur_enabled) {
- SDL_Rect crect={w->curx*FONT_X2,w->cury*FONT_Y2+FONT_Y2-2,FONT_X2,4};
- SDL_FillRect(winsurf,&crect,0xff000000);
- }
- }
- SDL_UpdateWindowSurface(global_window);
-}
-U0 SDL_AddCh(CSDL_TextWin *win,U8 ch,Bool force_in_view=FALSE) {
- I64 w=SDL_WinX(win);
- if(force_in_view&&ch!='\n') {
- if(win->x+1>=w) return;
- }
- if(ch=='\n') goto nxtln;
- I64 mult=1;
- if(win->inverse) mult=-1;
- if((win->char_cache[win->y*w+win->x].chr==ch)&&(win->char_cache[win->y*w+win->x].cp==mult*win->cur_cp)) goto next;
- SDL_Rect fsrc={ch*FONT_X,0,FONT_X,FONT_Y};
- SDL_Rect dstbox={win->x*FONT_X2,win->y*FONT_Y2,FONT_X2,FONT_Y2};
- U_RGBA8888 bg=SDL_ColorPairs[win->cur_cp].bg;
- U_RGBA8888 fg=SDL_ColorPairs[win->cur_cp].fg;
- if(win->inverse) {
- U_RGBA8888 tmp=bg;
- bg=fg;
- fg=tmp;
- }
- SDL_SetSurfaceColorMod(global_font,fg.r,fg.g,fg.b);
- SDL_FillRect(win->text,&dstbox,bg);
- SDL_BlitScaled(global_font,&fsrc,win->text,&dstbox);
- win->char_cache[win->y*w+win->x].chr=ch;
- win->char_cache[win->y*w+win->x].cp=win->cur_cp*mult;
- next:
- if(++win->x>=w) {
- nxtln:
- win->x=0,win->y++;
- }
- if(win->y<SDL_WinY(win)) {
- } else {
- win->y=SDL_WinY(win)-1;
- }
-}
-U0 SDL_Print(CSDL_TextWin *win,U8 *str) {
- I64 len=StrLen(str),idx=0;
- for(;idx!=len;idx++) {
- SDL_AddCh(win,str[idx],TRUE);
- }
-}
-U0 SDL_ClrToEOL(CSDL_TextWin *w) {
- I64 width=SDL_WinX(w)-w->x;
- U_RGBA8888 white=SOL_WHITE;
- SDL_Rect r={w->x*FONT_X2,w->y*FONT_Y2,width*FONT_X2,FONT_Y2};
- SDL_LockSurface(w->text);
- SDL_FillRect(w->text,&r,SOL_WHITE);
- SDL_UnlockSurface(w->text);
- I64 idx=w->y*SDL_WinX(w)+w->x;
- while(--width>=0)
- w->char_cache[idx+width].chr=' ',w->char_cache[width].cp=CP_BLANK;
-}
-class CEditor {
- CSDL_TextWin *window;
- CUndoInfo undo_info[UNDO_INFO_LENGTH];
- I64 undo_info_cur;
- I64 undo_info_end;
- I64 undo_info_start;
- Bool *dirty_screen_lines;
- I64 vp_start_line;
- I64 x_scroll;
- I64 curx,cury;
- //The expected x position,,we can enter a line that isnt as long as our expected curx
- I64 _curx;
- I64 h,w;
- CLine *lines;
- I64 line_count;
- //
- CLine **line_cache;
- I64 line_cache_size;
- //
- CTrie *tags;
- CDiag *diags;
- U8 *fn;
- I64 margin_top,margin_bottom;
- I64 sel_start,sel_end;
-};
-U8 *EdGetSelText(CEditor *ed);
-U0 EdDelSel(CEditor *ed);
-U0 MarkLineColors(CEditor *ed);
-U0 WriteWithinWin(CSDL_TextWin *win,U8 *text,I64 x_scroll=0);
-I64 OpenFile(U8 *name,I64 ln=0);
-I64 ShowDiagsWindow(CEditor *parent) {
- CDiag *first=parent->diags;
- I64 y_scroll=0,x_scroll=0,curln=0,ret=ED_RET_OK;
- CDiag *iter=first;
- I64 cnt=0;
- while(iter) cnt++,iter=iter->next;
- iter=first;
- CDiag **lines=MAlloc(cnt*sizeof(CDiag*));
- cnt=0;
- while(iter) {lines[cnt++]=iter;iter=iter->next;}
- parent->window->cur_cp=CP_WHITE;
- CSDL_TextWin *win=parent->window;
- draw:
- I64 h=getmaxy(stdscr);
- I64 cap=MinI64(y_scroll+h,cnt);
- I64 cnt2=0;
- dloop:
- if(cnt2+y_scroll>=cnt) {
- clear:
- while(cnt2<SDL_WinY(win)) {
- win->y=cnt2++;
- win->x=0;
- SDL_ClrToEOL(win);
- }
- goto inp;
- }
- if(cnt2+y_scroll==curln) {
- win->cur_cp=CP_FUZZY_SEL_B;
- } else {
- win->cur_cp=CP_FUZZY_UNSEL_A;
- }
- win->y=cnt2,win->x=0;
- I64 off=-x_scroll;
- CDiag *cur=lines[cnt2++ +y_scroll];
- U8 *lncol=MStrPrint("%s:%d:%d: ",cur->fn,cur->ln,cur->col);
- WriteWithinWin(win,lncol,off);
- off+=StrLen(lncol);
- Free(lncol);
-
- if(cur->type==DIAG_ERR) {
- WriteWithinWin(win,"ERROR",off);
- //TODO COLOR
- off+=StrLen("ERROR");
- } else {
- WriteWithinWin(win,"WARNING",off);
- //TODO COLOR
- off+=StrLen("WARNING");
- }
- if(StrFirstOcc(cur.msg,"\r\n")) *StrFirstOcc(cur.msg,"\n\r")=0;
- WriteWithinWin(win,cur->msg,off);
- SDL_ClrToEOL(win);
- if(cnt2+y_scroll<cap) goto dloop;
- goto clear;
- inp:
- SDL_DrawWin(win);
- I64 key=GetKey();
- switch(key) {
- case ED_KEY_ESCAPE: goto exit;
- case ERR: goto inp;
- case ED_KEY_PAGEUP:
- curln=MaxI64(0,curln-SDL_WinY(win));
- break;
- case ED_KEY_PAGEDOWN:
- curln=MinI64(cnt,curln+SDL_WinY(win));
- break;
- case ED_KEY_RIGHT: ++x_scroll; break;
- case ED_KEY_LEFT: x_scroll=MaxI64(0,--x_scroll); break;
- case ED_KEY_UP: curln=MinI64(MaxI64(0,--curln),cnt); break;
- case ED_KEY_DOWN: curln++; break;
- case '\n':
- if(curln<cnt) {
- ret=OpenFile(lines[curln]->fn,lines[curln]->ln);
- goto exit;
- } else {
- goto exit;
- }
- break;
- case ED_KEY_REDRAW:
- case ED_KEY_RESIZE:
- SDL_DrawWin(win);
- break;
- }
- if(curln<y_scroll) y_scroll=curln;
- else if(curln>=SDL_WinY(win)+y_scroll) y_scroll=curln-SDL_WinY(win)+1;
- goto draw;
- exit:
- Free(lines);
- return ret;
-}
-
-I64 UndoBufSize(CEditor* ed) {
- if (ed->undo_info_end > ed->undo_info_start)
- return ed->undo_info_end - ed->undo_info_start;
- else
- return (UNDO_INFO_LENGTH - ed->undo_info_start) + ed->undo_info_end;
-}
-U0 InsUndoInfo(CUndoInfo* info, CEditor* ed) {
- ed->undo_info_end = (ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH;
-
- if (ed->undo_info_cur != UNDO_INFO_LENGTH) {
- ed->undo_info_cur++;
- } else if (ed->undo_info_end == ed->undo_info_start) {
- ed->undo_info_start = (ed->undo_info_start + 1) % UNDO_INFO_LENGTH;
- }
-
- //Destroy old value
- switch (ed->undo_info[ed->undo_info_end]->type) {
- case EDIT_DEL_STR:
- Free(ed->undo_info[ed->undo_info_end]->removed_str);
- break;
-
- case EDIT_INS_STR:
- Free(ed->undo_info[ed->undo_info_end]->inserted_str);
- break;
- }
-
- ed->undo_info[ed->undo_info_end] = *info;
- ed->undo_info_end = (ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH;
-}
-CUndoInfo* GetUndoInfo(CEditor* ed) {
- if ((ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH == ed->undo_info_end)
- if (ed->undo_info_cur)
- return NULL;
-
- I64 i = (ed->undo_info_cur + ed->undo_info_start) % UNDO_INFO_LENGTH;
- I64 s = ed->undo_info_start;
- I64 e = ed->undo_info_end;
-
- if (s == e) goto en;
-
- if (s < e) {
- if (!(s <= i < e)) return NULL;
- } else if (e <= i < s) return NULL;
-
- en:
-
- if (ed->undo_info[i]->type == EDIT_UNUSED)
- return NULL;
-
- return &ed->undo_info[i];
-}
-class CBuffer:CHash {
- CEditor *ed;
-};
-CHashTable *buffers=HashTableNew(1<<5);
-U0 FocusCursor(CEditor *ed,I64 lmargin=0) {
- //https://stackoverflow.com/questions/1811955/ncurses-terminal-size
- I64 w=SDL_WinX(ed->window)-lmargin;
- if(ed->curx<ed->x_scroll) {
- ed->x_scroll=ed->curx;
- } else if(ed->x_scroll+w<=ed->curx) {
- ed->x_scroll=ed->curx-w+1;
- }
- if(ed->cury<ed->vp_start_line) {
- ed->vp_start_line=ed->cury;
- } else if(ed->vp_start_line+SDL_WinY(ed->window)-ed->margin_top<=ed->cury) {
- ed->vp_start_line=ed->cury-SDL_WinY(ed->window)+1+ed->margin_top;
- }
-}
-I64 GetLinum(CEditor *ed,CLine *ln) {
- CLine *s=ed->lines;
- I64 num=0;
- while(s) {
- if(s==ln)
- return num;
- num++;
- s=s->next;
- }
- return -1;
-}
-I64 GetLineCount(CEditor *ed) {
- I64 ret=0;
- CLine *ln=ed->lines;
- while(ln) {
- ln=ln->next,ret++;
- }
- return ret;
-}
-CLine *GetLine(CEditor *ed,I64 ln) {
- if(ed->line_cache_size>ln)
- return ed->line_cache[ln];
- CLine *s=ed->lines;
- if(s->cached_offset!=0) throw('');
- I64 num=0,off=0;
- if(MSize(ed->line_cache)/sizeof(CLine*)<=ln) {
- I64 pow2=1;
- while((1<<pow2)<=ln) pow2++;
- CLine **new=MAlloc((1<<pow2)*sizeof(CLine*));
- MemNCpy(new,ed->line_cache,sizeof(CLine*)*ed->line_cache_size);
- if(ed->line_cache_size){
- s=ed->line_cache[ed->line_cache_size-1];
- off=s->cached_offset;
- num=ed->line_cache_size-1;
- }
- Free(ed->line_cache);
- ed->line_cache=new;
- }
- while(s) {
- ed->line_cache[num]=s;
- s->cached_offset=off;
- if(num==ln) {
- ed->line_cache_size=MaxI64(ln,ed->line_cache_size);
- return s;
- }
- off+=RopeLength(s->text);
- s=s->next;
- num++;
- }
- ed->line_cache_size=num;
- return NULL;
-}
-I64 GetLineOffset(CEditor *ed,I64 ln) {
- CLine *ln2=GetLine(ed,ln);
- if(ln2) return ln2->cached_offset;
- return -1;
-}
-
-U0 DirtyLinesBelow(CEditor *ed,I64 ln) {
- ed->line_cache_size=ln;
- ln-=ed->vp_start_line;
-}
-U0 WriteWithinWin(CSDL_TextWin *win,U8 *text,I64 x_scroll=0) {
- I64 l=StrLen(text)+x_scroll;
- I64 s=x_scroll;
- while(s!=l) {
- if(SDL_WinX(win)>=s>=0) {
- U8 chr=text[s-x_scroll];
- if(chr=='\t')
- SDL_AddCh(win,' ',TRUE);
- else if(chr!='\r'){
- SDL_AddCh(win,chr,TRUE);
- }
- }
- s++;
- }
-}
-U0 WriteWithinView(CEditor *ed,U8 *text,I64 off) {
- I64 l=StrLen(text);
- I64 s=off;
- I64 e=off+l;
- while(s!=e) {
- if(ed->x_scroll+SDL_WinX(ed->window)>=s>=ed->x_scroll) {
- if(text[s-off]=='\t')
- SDL_AddCh(ed->window,' ',TRUE);
- else if(text[s-off]!='\r')
- SDL_AddCh(ed->window,text[s-off],TRUE);
- }
- s++;
- }
-}
-Bool IsEscaped(U8 *sstart,U8 *chr) {
- if(chr-1>=sstart)
- if(chr[-1]=='\\')
- return !IsEscaped(sstart,chr-1);
- return FALSE;
-}
-CLine *SearchForMLCommmentStart(CLine *s) {
- while(s) {
- if(s->flags&ED_LNF_COMMENTED_START)
- if(!(s->flags&ED_LNF_COMMENTED_OUT))
- return s;
- s=s->prev;
- }
- return NULL;
-}
-CLine *SearchForMLCommmentEnd(CLine *s) {
- while(s) {
- if(s->flags&ED_LNF_COMMENTED_END)
- return s;
- s=s->next;
- }
- return NULL;
-}
-U0 __HighlightWrite(CEditor *ed,U8 *text,I64 off,I64 sel_start=I64_MAX,I64 sel_end=I64_MAX) {
- I64 len=StrLen(text),idx;
- for(idx=0;idx!=len;idx++) {
- if(off+idx>=ed->x_scroll) {
- if(sel_start<=off+idx<sel_end) {
- ed->window->inverse=TRUE;
- } else
- ed->window->inverse=FALSE;
- SDL_AddCh(ed->window,text[idx],TRUE);
- }
- }
- ed->window->inverse=FALSE;
-}
-U0 Highlight(CEditor *ed,CLine *ln,Bool dryRun=FALSE,Bool recur=TRUE) {
- I64 ln_off=GetLineOffset(ed,GetLinum(ed,ln));
- I64 sel_start=ed->sel_start;
- I64 sel_end=ed->sel_end;
- if(sel_start==sel_end) goto ignoresel;
- sel_start-=ln_off;
- sel_end-=ln_off;
- //Compute relative to line start
- if(sel_start<0) sel_start=0;
- if(sel_end<0) sel_end=0;
- if(sel_end>RopeLength(ln->text))
- sel_end=RopeLength(ln->text);
- if(sel_start>sel_end) SwapI64(&sel_start,&sel_end);
- ignoresel:
- U8 *text=Rope2Str(ln->text);
- U8 *nl=StrFirstOcc(text,"\n");
- if(nl) *nl=0;
- U8 *buf=MAlloc(StrLen(text)+1);
- I64 idx=0,ns=0;
- if(ln->prev) {
- if(!(ln->prev->flags&ED_LNF_COMMENTED_OUT))
- ln->flags&=~ED_LNF_COMMENTED_OUT;
- if(!(ln->flags&ED_LNF_COMMENTED_END))
- if((ln->prev->flags&ED_LNF_COMMENTED_OUT)||(ln->prev->flags&ED_LNF_COMMENTED_START))
- ln->flags|=ED_LNF_COMMENTED_OUT;
- }
- I64 isCommentedOut1=(ln->flags&ED_LNF_COMMENTED_OUT)||(ln->flags&ED_LNF_COMMENTED_START);
- I64 isMlEnd1=ln->flags&ED_LNF_COMMENTED_END,isMlStart1=ln->flags&ED_LNF_COMMENTED_START;
- ln->flags&=~ED_LNF_COMMENTED_START;
- if((ln->flags&ED_LNF_COMMENTED_END)||(ln->flags&ED_LNF_COMMENTED_OUT)) {
- while(text[idx]) {
- if(0==StrNCmp(text+idx,"*/",2)) {
- idx+=2;
- ed->window->cur_cp=CP_COMMENT;
- StrNCpy(buf,text,idx);
- buf[idx]=0;
- if(!dryRun) __HighlightWrite(ed,buf,0,sel_start,sel_end);
- ln->flags|=ED_LNF_COMMENTED_END;
- ln->flags&=~ED_LNF_COMMENTED_OUT;
- goto s;
- }
- idx++;
- }
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,text,0,sel_start,sel_end);
- ln->flags&=~ED_LNF_COMMENTED_END;
- ln->flags|=ED_LNF_COMMENTED_OUT;
- }
-s:
- U8 *orig=text;
-loop:
- ns=idx;
- //Try lexing name
- if(!Bt(char_bmp_dec_numeric,text[idx]))
- while(Bt(char_bmp_alpha_numeric,text[idx])||text[idx]=='#') idx++;
- if(ns!=idx) {
- StrNCpy(buf,&text[ns],idx-ns);
- buf[idx-ns]=0;
- CHash *kw;
- if(kw=HashFind(buf,keywords)) {
- ed->window->cur_cp=CP_KW;
- } else {
- ed->window->cur_cp=CP_WORD;
- }
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
-
- if(text[idx]=='/') {
- if(text[idx+1]=='/') {
- StrCpy(buf,text+idx);
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
- idx=StrLen(text);
- goto loop;
- } else if(text[idx+1]=='*') {
- idx++;
- while(text[idx]) {
- if(0==StrNCmp(text+idx,"*/",2)) {
- idx+=2;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- idx++;
- }
- ed->window->cur_cp=CP_COMMENT;
- if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
- ln->flags|=ED_LNF_COMMENTED_START;
- //Dry run hgihlight until we find a line end
- CLine *nxtln=ln->next;
- if(!recur) for(; nxtln;) {
- Highlight(ed, nxtln, TRUE); //Will set ED_LNF_COMMENTED_OUT;
- if(nxtln->flags&ED_LNF_COMMENTED_END) break;
- nxtln=nxtln->next;
- }
- }
- }
- //Try lexing a string
- if(StrOcc("'\"",text[idx])) {
- U8 term=text[idx++];
- U8 sseek[2]= {term,0};
-sloop:
- U8 *sfind=StrFirstOcc(text+idx,sseek);
- if(!sfind) {
- ed->window->cur_cp=CP_STR;
- if(!dryRun) __HighlightWrite(ed,text+ns,ns,sel_start,sel_end);
- idx=StrLen(text);
- } else if(IsEscaped(text,sfind)) {
- idx=sfind-orig+1;
- goto sloop;
- } else {
- idx=sfind-orig+1;
- ed->window->cur_cp=CP_STR;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- }
-
- //Lex numbers
- ns=idx;
- while (Bt(char_bmp_white_space,text[idx])) idx++;
- if(ns!=idx) {
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_WHITE;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- U8 *idx2=text+idx;
- Str2I64(text+idx,,&idx2);
- if(idx2!=text+idx) {
- idx=idx2-text;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_NUM;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- Str2F64(idx2,&idx2);
- if(text+idx!=idx2) {
- idx=idx2-text;
- StrNCpy(buf,text+ns,idx-ns);
- buf[idx-ns]=0;
- ed->window->cur_cp=CP_NUM;
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- goto loop;
- }
- if(!text[idx]) goto en;
- ed->window->cur_cp=CP_TOK;
- buf[1]=0;
- buf[0]=text[idx];
- if(!dryRun) __HighlightWrite(ed,buf,ns,sel_start,sel_end);
- idx++;
- goto loop;
-en:
- I64 isMlEnd2=ln->flags&ED_LNF_COMMENTED_END,isMlStart2=ln->flags&ED_LNF_COMMENTED_START;
- I64 isCommentedOut2=(ln->flags&ED_LNF_COMMENTED_OUT)||(ln->flags&ED_LNF_COMMENTED_START);
- if(recur&&(isMlEnd1!=isMlEnd2||isMlStart1!=isMlStart2)) {
- nxtln=ln->next;
- for(;nxtln;nxtln=nxtln->next) {
- Bool comm_end=nxtln->flags&ED_LNF_COMMENTED_END;
- Highlight(ed, nxtln, TRUE);
- if(isMlEnd2) { //Added '*/',quit at next '*/'
- if(comm_end) break;
- } else { //Removed '*/',quit at next '*/'
- if(comm_end) break;
- }
- }
- }
- if(recur&&isCommentedOut2!=isCommentedOut1) {
- nxtln=ln->next;
- for(;nxtln;nxtln=nxtln->next) {
- Highlight(ed,nxtln,TRUE);
- if((nxtln->flags&ED_LNF_COMMENTED_OUT)!=isCommentedOut2) break;
- }
- }
- ed->window->cur_cp=CP_WHITE;
- SDL_ClrToEOL(ed->window);
- Free(buf);
-}
-U0 __EditorInsText(CEditor *ed,U8 *text,I64 at) {
- U8 *buf;
- I64 ln_off=0;
- CLine *ln=ed->lines,*prev=NULL;
- I64 linum=0;
- while(ln) {
- if(ln_off<=at<ln_off+RopeLength(ln->text)) break;
- ln_off+=RopeLength(ln->text);
- prev=ln;
- ln=ln->next,linum++;
- }
- DirtyLinesBelow(ed,GetLinum(ed,ln));
-
- if(ln_off<=at&&!ln) {
- if(prev) {
- ln=prev;
- ln_off-=RopeLength(ln->text);
- } else {
- CLine *nl=MAlloc(sizeof(CLine));
- ed->line_count++;
- nl->prev=prev;
- if(prev) prev->next=nl;
- ln=nl;
- ln->text=RopeAppendText(NULL,"");
- if(!ed->lines) ed->lines=nl;
- }
- }
- ln->text=RopeInsText(ln->text, text, at-ln_off);
- ln->text=RopeCondense(ln->text);
- Highlight(ed, ln, TRUE);
- CLine *start_ln=ln;
-loop:
- U8 *text2=Rope2Str(ln->text);
- U8 *nl3=StrFirstOcc(text2,"\n");
- if(nl3)
- if(nl3[1]) {
- CRope *right;
- RopeSplit(ln->text, nl3-text2+1, &ln->text, &right);
- //Insert a blank line
- nl=MAlloc(sizeof(CLine));
- ed->line_count++;
- nl->prev=ln;
- if(ln) nl->next=ln->next;
- if(nl->prev) nl->prev->next=nl;
- if(nl->next) nl->next->prev=nl;
- nl->text=right;
- ln=nl;
- Free(text2);
- goto loop;
- }
-
- if(!StrLen(text2)) ln->text=RopeAppendText(ln->text, "\n");
- else if(text2[StrLen(text2)-1]!='\n') ln->text=RopeAppendText(ln->text, "\n");
- DirtyLinesBelow(ed, GetLinum(ed,start_ln));
- Free(text2);
-}
-U0 RenumberLines(CEditor *ed,CLine *l=NULL) {
- I64 num=0;
- if(!l) l=ed->lines;
- else num=l->line;
- while(l) {
- l->line=num++;
- l=l->next;
- }
-}
-U0 EditorInsText(CEditor *ed,U8 *text,I64 at,Bool undo=FALSE) {
- EdDelSel(ed); //Clear selection if needed
- __EditorInsText(ed, text, at);
- if(undo) {
- CUndoInfo *prev;
- if(!(prev=GetUndoInfo(ed))) {
- ins1:
- CUndoInfo info;
- info.type=EDIT_INS_STR;
- info.inserted_str=StrNew(text);
- info.at=at;
- InsUndoInfo(&info,ed);
- goto ret;
- } else if(prev->type==EDIT_INS_STR) {
- if(prev->at+StrLen(prev->inserted_str)==at) {
- U8 *new=MStrPrint("%s%s",prev->inserted_str,text);
- Free(prev->inserted_str);
- prev->inserted_str=new;
- }
- }
- goto ins1;
- }
- ret:
- RenumberLines(ed);
-}
-U0 SDL_InitPair(I64 idx,U_RGBA8888 fg,U_RGBA8888 bg) {
- SDL_ColorPairs[idx].fg=fg,SDL_ColorPairs[idx].bg=bg;
-}
-CEditor *EditorNew(Bool gen_rt_tags=FALSE) {
- CEditor *r=MAlloc(sizeof(CEditor));
- SDL_InitPair(CP_KW,SOL_MAGENTA,SOL_WHITE);
- SDL_InitPair(CP_WORD,SOL_BLUE,SOL_WHITE);
- SDL_InitPair(CP_TOK,SOL_GREEN,SOL_WHITE);
- SDL_InitPair(CP_NUM,SOL_YELLOW,SOL_WHITE);
- SDL_InitPair(CP_STR,SOL_RED,SOL_WHITE);
- SDL_InitPair(CP_WHITE,SOL_BLACK,SOL_WHITE);
- SDL_InitPair(CP_LINUM,SOL_WHITE,SOL_BLUE);
- SDL_InitPair(CP_COMMENT,SOL_CYAN,SOL_WHITE);
- SDL_InitPair(CP_AC_SEL,SOL_CYAN,SOL_RED);
- SDL_InitPair(CP_AC_UNSEL,SOL_YELLOW,SOL_BLUE);
- SDL_InitPair(CP_MENU_SEL,SOL_YELLOW,SOL_RED);
- SDL_InitPair(CP_MENU_UNSEL,SOL_WHITE,SOL_BLUE);
- SDL_InitPair(CP_FUZZY_SEL_A,SOL_BLACK,SOL_YELLOW);
- SDL_InitPair(CP_FUZZY_UNSEL_A,SOL_BLACK,SOL_WHITE);
- SDL_InitPair(CP_FUZZY_SEL_B,SOL_RED,SOL_YELLOW);
- SDL_InitPair(CP_FUZZY_UNSEL_B,SOL_RED,SOL_WHITE);
- SDL_InitPair(CP_LINUM_ERR,SOL_WHITE,SOL_RED);
- SDL_InitPair(CP_LINUM_WARN,SOL_WHITE,SOL_YELLOW);
- I32 x,y;
- SDL_GetWindowSize(global_window,&x,&y);
- r->window=SDL_NewTextWin(x/FONT_X2,y/FONT_Y2);
- r->vp_start_line=0;
- r->line_cache=MAlloc(sizeof(CLine*));
- r->line_cache_size=0;
- EditorInsText(r,"",0);
- if(gen_rt_tags) {
- CreateTagsAndErrorsFiles("TAGS","ERRS",r->fn);
- r->tags=ReadTags("TAGS");
- r->diags=ParseDiags("ERRS");
- MarkLineColors(r);
- }
- return r;
-}
-U0 FreeLine(CLine *ln) {
- //Update multiline comments
- if(ln->flags&ED_LNF_COMMENTED_START) {
- CLine *s=SearchForMLCommmentStart(ln->prev);
- CLine* e=SearchForMLCommmentEnd(ln);
-adjust:
- if(s) {
- if(e) {
- e->commentStart=s;
- } else {
- do {
- s->flags|=ED_LNF_COMMENTED_OUT;
- s=s->next;
- } while(s);
- }
- } else if(e) {
- e->commentStart=NULL;
- do {
- e->flags&=~ED_LNF_COMMENTED_OUT;
- e=e->prev;
- } while(e);
- }
- } else if(ln->flags&ED_LNF_COMMENTED_END) {
- s=SearchForMLCommmentStart(ln);
- e=SearchForMLCommmentEnd(ln->next);
- goto adjust;
- }
- if(ln->prev) ln->prev->next=ln->next;
- if(ln->next) ln->next->prev=ln->prev;
- if(ln->text) RopeFree(ln->text);
- Free(ln);
-}
-U0 __EditorDelText(CEditor *ed,I64 soff,I64 eoff) {
- I64 ln_off=0;
- CLine *ln=ed->lines,*prev=NULL;
- Bool merge=TRUE;
- CLine *end_ln;
- while(ln) {
- if(ln_off<=soff<ln_off+RopeLength(ln->text)) {
- CLine *start_ln=ln;
- DirtyLinesBelow(ed,GetLinum(ed, start_ln));
- I64 en=MinI64(RopeLength(ln->text),eoff-ln_off);
- ln->text=RopeDelText(ln->text,soff-ln_off,en);
- eoff-=en-(soff-ln_off);
- ln->text=RopeCondense(ln->text);
- Highlight(ed, ln, TRUE);
- ln_off+=RopeLength(ln->text);
- if(ln_off+RopeLength(ln->text)>=eoff) {
- DirtyLinesBelow(ed,GetLinum(ed, ln));
- //End of deletion is on same line
- //Merge with next line if doesnt contain an endline
- U8 *txt=Rope2Str(ln->text);
- if(!StrFirstOcc(txt,"\n")) {
- Free(txt);
- end_ln=ln->next;
- goto merge;
- }
- Free(txt);
- return;
- }
- break;
- }
- ln_off+=RopeLength(ln->text);
- prev=ln;
- ln=ln->next;
- }
- if(!ln) return;
- while(ln) {
- if(ln_off<=eoff<ln_off+RopeLength(ln->text)) break;
- ln_off+=RopeLength(ln->text);
- prev=ln;
- ln=ln->next;
- }
- end_ln=ln;
-merge:
- //start_ln!=end_ln;
- if(start_ln!=end_ln)
- ln=start_ln->next;
- DirtyLinesBelow(ed,GetLinum(ed, start_ln));
- while(ln!=end_ln) {
- CLine *nxt=ln->next;
- if(ln==ed->lines) ed->lines=nxt;
- ed->line_count--;
- eoff-=RopeLength(ln->text);
- FreeLine(ln);
- ln=nxt;
- }
- if(merge&&end_ln) {
- U8 *t=Rope2Str(end_ln->text);
- start_ln->text=RopeAppendText(start_ln->text,t+eoff-GetLineOffset(ed,GetLinum(ed,end_ln)));
- start_ln->text=RopeCondense(start_ln->text);
- Highlight(ed, start_ln, TRUE);
- Free(t);
- FreeLine(end_ln);
- ed->line_count--;
- }
- //All lines must end in newline.
- if(RopeLength(start_ln->text)==0) {
- addnl:
- start_ln->text=RopeAppendText(start_ln->text,"\n");
- } else if(RopeChar(start_ln->text,RopeLength(start_ln->text)-1)!='\n'){
- goto addnl;
- }
-}
-U8 *EdTextSlice(CEditor *ed,I64 soff,I64 eoff) {
- U8 *ret=MAlloc(eoff-soff+1);
- U8 *retptr=ret;
- I64 off=0;
- CLine *ln=ed->lines;
- sloop:
- if(off<=soff<off+RopeLength(ln->text)) {
- U8 *text=Rope2Str(ln->text);
- if(off<=eoff<off+RopeLength(ln->text)) {
- StrNCpy(ret,text+soff-off,eoff-soff);
- Free(text);
- return ret;
- } else {
- StrCpy(ret,text+soff-off);
- retptr+=StrLen(ret);
- off+=RopeLength(ln->text);
- ln=ln->next;
- }
- } else {
- off+=RopeLength(ln->text);
- ln=ln->next;
- goto sloop;
- }
- eloop:
- if(!ln) goto en;
- text=Rope2Str(ln->text);
- if(off<=eoff<off+RopeLength(ln->text)) {
- StrNCpy(retptr,text,eoff-off);
- Free(text);
- return ret;
- } else {
- off+=RopeLength(ln->text);
- StrCpy(retptr,text);
- retptr+=StrLen(retptr);
- ln=ln->next;
- Free(text);
- goto eloop;
- }
- en:
- return ret;
-}
-U0 EditorDelText(CEditor *ed,I64 soff,I64 eoff,Bool undo=FALSE) {
- if(undo)
- U8 *slice=EdTextSlice(ed,soff,eoff);
- __EditorDelText(ed, soff, eoff);
- if(undo) {
- CUndoInfo *prev=GetUndoInfo(ed);
- if(!prev) {
- ins1:
- CUndoInfo del;
- del.type=EDIT_DEL_STR;
- del.removed_str=StrNew(slice);
- del.at=soff;
- InsUndoInfo(&del,ed);
- goto ret;
- } else if(prev->type==EDIT_DEL_STR&&prev->at==soff) {
- U8 *new=MStrPrint("%s%s",slice,prev->removed_str);
- Free(prev->removed_str);
- prev->removed_str=new;
- goto ret;
- }
- goto ins1;
- }
- ret:
- if(undo) Free(slice);
- RenumberLines(ed);
-}
-U0 EdJumpToChar(CEditor *ed,I64 chr) {
- CLine *ln=ed->lines;
- I64 off=0;
- loop:
- if(!ln) {
- ed->curx=ed->cury=0;
- return;
- }
- I64 len;
- if(off<=chr<off+(len=RopeLength(ln->text))) {
- ed->cury=GetLinum(ed, ln);
- ed->curx=ed->_curx=chr-off;
- return;
- }
- off+=len;
- ln=ln->next;
- goto loop;
-}
-U0 Undo(CEditor *ed) {
- if(ed->undo_info_cur-1<0) return;
- ed->undo_info_cur--;
- CUndoInfo *info=GetUndoInfo(ed);
- switch(info->type) {
- case EDIT_INS_STR:
- EditorDelText(ed,info->at,info->at+StrLen(info->inserted_str));
- EdJumpToChar(ed,info->at);
- break;
- case EDIT_DEL_STR:
- EditorInsText(ed,info->removed_str,info->at);
- EdJumpToChar(ed,info->at+StrLen(info->removed_str));
- break;
- }
-}
-U0 Redo(CEditor *ed) {
- if(ed->undo_info_cur>=UndoBufSize(ed)) return;
- CUndoInfo *info=GetUndoInfo(ed);
- switch(info->type) {
- case EDIT_DEL_STR:
- EditorDelText(ed,info->at,info->at+StrLen(info->removed_str));
- EdJumpToChar(ed,info->at);
- break;
- case EDIT_INS_STR:
- EditorInsText(ed,info->inserted_str,info->at);
- EdJumpToChar(ed,info->at+StrLen(info->inserted_str));
- break;
- }
- ed->undo_info_cur++;
-}
-U0 DrawLinumWithPad(CEditor *ed,I64 num,I64 barwidth) {
- U8 *lnumtxt=MStrPrint("%d: ",num);
- I64 lnumlen=StrLen(lnumtxt);
- SDL_Print(ed->window,lnumtxt);
- Free(lnumtxt);
- while(barwidth>lnumlen++) SDL_AddCh(ed->window,' ');
-}
-#define ED_DRAW_LINUMS 1
-#define ED_DRAW_SEARCH 2
-#define ED_DRAW_DIALOG 4
-#define ED_DRAW_MENUBAR 8
-#define ED_DRAW_DFT (ED_DRAW_LINUMS|ED_DRAW_MENUBAR)
-#define ED_DRAW_NO_RENDER 16
-U0 AddMenuBar(CEditor *ed,I64 active=-1);
-I64 DrawEditor(CEditor *ed,I64 flags=0,U8 *dialogtxt=NULL,I64 mb_active=-1) {
- curs_set(0);
- CLine *diagln=NULL;
- //If we are at a line with a diagnostic,be sure to make a bottom margin
- if(flags&(ED_DRAW_DIALOG|ED_DRAW_SEARCH)) {
- } else {
- diagln=GetLine(ed,ed->cury);
- if(diagln) {
- if(!(diagln->flags&(ED_LNF_ERR|ED_LNF_WARN))) diagln=NULL;
- }
- }
- if(flags&ED_DRAW_MENUBAR) {
- if(AddMenuBar(ed,mb_active)==ED_RET_QUIT) return ED_RET_QUIT;
- ed->margin_top=1;
- }
- if(flags&ED_DRAW_LINUMS) {
- U8 *lnumtxt=MStrPrint("%d: ",ed->line_count);
- I64 lnumlen=StrLen(lnumtxt);
- Free(lnumtxt);
- } else if(flags&ED_DRAW_SEARCH) {
- ed->window->cur_cp=CP_LINUM;
- lnumtxt=MStrPrint("Search: ");
- lnumlen=StrLen(lnumtxt);
- ed->window->y=ed->window->x=0;
- SDL_Print(ed->window,lnumtxt);
- Free(lnumtxt);
- } else if(flags&ED_DRAW_DIALOG) {
- ed->window->cur_cp=CP_LINUM;
- lnumtxt=MStrPrint("%s: ",dialogtxt);
- lnumlen=StrLen(lnumtxt);
- ed->window->y=ed->window->x=0;
- SDL_Print(ed->window,lnumtxt);
- Free(lnumtxt);
- } else
- lnumlen=0;
- FocusCursor(ed,lnumlen);
- //if(ed->x_scroll) Debugger;
- ed->w-=lnumlen;
- CLine *ln=ed->lines;
- while(ln) {
- if(ln->line==ed->vp_start_line) break;
- ln=ln->next;
- }
- I64 cnt=SDL_WinY(ed->window),line=ed->vp_start_line+1,screen_line=ed->margin_top;
- cnt-=(ed->margin_top+ed->margin_bottom);
- while(--cnt>=0&&ln) {
- if(flags&ED_DRAW_LINUMS) {
- ed->window->y=screen_line,ed->window->x=0;
- I64 cp=CP_LINUM;
- if(ln->flags&ED_LNF_ERR) {
- cp=CP_LINUM_ERR;
- } else if(ln->flags&ED_LNF_WARN) {
- cp=CP_LINUM_WARN;
- }
- ed->window->cur_cp=cp;
- DrawLinumWithPad(ed,line++,lnumlen);
- }
- if(1) {
- ed->window->y=screen_line,ed->window->x=lnumlen;
- Highlight(ed,ln,,TRUE);
- }
- ++screen_line;
- ln=ln->next;
- }
- U8 *pad=MStrPrint("%*c",lnumlen,' ');
- while(cnt>=0) {
- ed->window->cur_cp=CP_LINUM;
- ed->window->y=screen_line,ed->window->x=0;
- SDL_Print(ed->window,pad);
- ed->window->cur_cp=CP_WHITE;
- ed->window->y=screen_line++,ed->window->x=lnumlen;
- SDL_ClrToEOL(ed->window);
- cnt--;
- }
- if(diagln) {
- ed->window->y=SDL_WinY(ed->window)-1,ed->window->x=0;
- if(diagln->flags&ED_LNF_ERR) ed->window->cur_cp=CP_LINUM_ERR;
- else if(diagln->flags&ED_LNF_WARN) ed->window->cur_cp=CP_LINUM_WARN;
- else throw('InvDiag');
- SDL_Print(ed->window,diagln->diag->msg);
- SDL_ClrToEOL(ed->window);
- }
- ed->window->cur_enabled=TRUE;
- ed->window->curx=lnumlen+ed->curx-ed->x_scroll;
- ed->window->cury=ed->cury-ed->vp_start_line+ed->margin_top;
- if(flags&ED_DRAW_NO_RENDER);
- else SDL_DrawWin(ed->window);
- return ED_RET_OK;
-}
-U0 EdUp(CEditor *ed) {
- if(ed->cury>0) {
- --ed->cury;
- if(ed->cury<ed->vp_start_line)
- ed->vp_start_line=ed->cury;
- if(ed->_curx>RopeLength(GetLine(ed, ed->cury)->text))
- ed->curx=RopeLength(GetLine(ed, ed->cury)->text);
- else
- ed->curx=ed->_curx;
- } else {
- ed->_curx=ed->curx=0;
- }
-}
-U0 EdDown(CEditor *ed) {
- CLine *dnext=GetLine(ed,ed->cury);
- if(dnext->next) {
- ++ed->cury;
- if(ed->_curx>RopeLength(GetLine(ed, ed->cury)->text))
- ed->curx=RopeLength(GetLine(ed, ed->cury)->text);
- else
- ed->curx=ed->_curx;
- } else {
- ed->_curx=ed->curx=RopeLength(GetLine(ed, ed->cury)->text);
- }
-}
-U0 EdRight(CEditor *ed) {
- CLine *rline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(rline->text);
- I64 x=ed->curx,cnt=0;
- I64 ox=x;
- x++;
- while((--x>=0)&&text[x]==' ') cnt++;
- if(x==-1&&cnt) {
- cnt++;
- cnt/=4;
- I64 cap=4*(cnt+1);
- while(text[ed->curx]==' ') {
- if(ed->curx>=cap) break;
- ed->curx++;
- }
- if(ox==ed->curx) goto next;
- ed->_curx=ed->curx;
- Free(text);
- return;
- }
- next:
- Free(text);
- if(ed->curx+1>=RopeLength(rline->text)) {
- rline=rline->next;
- if(rline) {
- ed->_curx=ed->curx=0;
- ed->cury++;
- } else {
- ed->_curx=ed->curx=RopeLength(GetLine(ed,ed->cury)->text);
- }
- } else ed->_curx=++ed->curx;
-}
-U0 EdLeft(CEditor *ed) {
- CLine *lline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(lline->text);
- I64 x=ed->curx,cnt=1;
- if(x) {
- while(--x&&text[x]==' ') cnt++;
- if(!x&&cnt) {
- cnt/=4;
- if(cnt)
- ed->_curx=ed->curx=4*(cnt-1);
- else
- ed->_curx=ed->curx=0;
- Free(text);
- return;
- }
- }
- Free(text);
- if(ed->curx==0) {
- lline=lline->prev;
- if(lline) {
- ed->_curx=ed->curx=RopeLength(lline->text);
- ed->cury--;
- } else {
- ed->_curx=ed->curx=0;
- }
- } else ed->_curx=--ed->curx;
-}
-U0 EdWordLeft(CEditor *ed) {
- CLine *lline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(lline->text);
- I64 idx=ed->curx;
- Bool hit_word=FALSE;
- if(idx!=0) idx--;
- while(idx>0) {
- if(Bt(char_bmp_alpha_numeric,text[idx])) {
- hit_word=TRUE;
- } else if(hit_word)
- break;
- idx--;
- }
- if(idx==0) {
- lline=lline->prev;
- if(!lline)
- ed->_curx=ed->curx=0;
- else
- ed->_curx=ed->curx=RopeLength(lline->text)-1,ed->cury--; //-1 ignores newline
- } else
- ed->_curx=ed->curx=idx;
- Free(text);
-}
-U0 EdWordRight(CEditor *ed) {
- CLine *lline=GetLine(ed,ed->cury);
- U8 *text=Rope2Str(lline->text);
- I64 idx=ed->curx;
- Bool hit_word=FALSE;
- idx++;
- I64 len=RopeLength(lline->text);
- while(idx<len) {
- if(!text[idx]) break;
- if(Bt(char_bmp_alpha_numeric,text[idx])) {
- hit_word=TRUE;
- } else if(hit_word)
- break;
- idx++;
- }
- if(idx==len) {
- lline=lline->next;
- if(lline) {
- ed->cury++;
- ed->_curx=ed->curx=0;
- }
- } else
- ed->_curx=ed->curx=idx;
- Free(text);
-}
-U0 EdBackspace(CEditor *ed) {
- CLine *bline=GetLine(ed,ed->cury);
- I64 eoff=GetLineOffset(ed,ed->cury);
- I64 ox=ed->curx,oy=ed->cury;
- EdLeft(ed);
- if(ox==0) {
- //Kill Newline on previous line
- if(bline->prev) {
- I64 no=RopeLength(bline->prev->text)-1; //ignore newline
- EditorDelText(ed, eoff-1, eoff,TRUE);
- ed->_curx=ed->curx=no;
- return;
- } else {
- //Do nothing
- }
- } else {
- U8 *text=Rope2Str(bline->text);
- I64 cnt=0,orig=ox;
- while(--ox&&text[ox]==' ') cnt++;
- if(!ox&&cnt) {
- cnt/=4;
- EditorDelText(ed,eoff,eoff+orig,TRUE);
- Free(text);
- ed->curx=ed->_curx=0;
- //text=MStrPrint("%*c",cnt,' ');
- //EditorInsText(ed,text,eoff);
- //ed->curx=ed->_curx=StrLen(text);
- } else {
- EditorDelText(ed, eoff+orig-1, eoff+orig,TRUE);
- }
- Free(text);
- }
-}
-U0 EdPageDown(CEditor *ed) {
- //Check if there is enough room for a page down
- CLine *lline=GetLine(ed,ed->cury);
- I64 cnt=SDL_WinY(ed->window),cnt2=0;
- while(lline&&--cnt>=0) {
- lline=lline->next;
- cnt2++;
- }
- if(!lline) cnt2--;
- ed->vp_start_line+=cnt2;
- ed->cury+=cnt2;
- lline=GetLine(ed,ed->cury);
- if(RopeLength(lline->text)>=ed->_curx) ed->curx=RopeLength(lline->text);
-}
-U0 EdPageUp(CEditor *ed) {
- ed->vp_start_line-=SDL_WinY(ed->window);
- ed->vp_start_line=MaxI64(ed->vp_start_line,0);
- CLine *lline=GetLine(ed,ed->vp_start_line);
- ed->cury=ed->vp_start_line;
- if(RopeLength(lline->text)>=ed->_curx) ed->curx=RopeLength(lline->text);
-}
-U0 FreeEditor(CEditor *ed);
-I64 EdSearch(CEditor *ed) {
- static U8 prevs[1024];
- CEditor *sed=EditorNew();
- goto resize;
-loop:
- I64 key=GetKey;
- switch(key) {
- case ERR:
- goto loop;
- case ED_KEY_RESIZE:
-resize:
- SDL_DrawWin(ed->window);
- sed->window->begy=SDL_WinY(ed->window)-1;
- goto mvsrncur;
- case ED_KEY_CTRL_UP:
- case ED_KEY_UP: //TODO
- goto mvsrncur;
- case ED_KEY_CTRL_DOWN:
- case ED_KEY_DOWN: //TODO
- goto mvsrncur;
- case ED_KEY_RIGHT:
- EdRight(sed);
- goto mvsrncur;
- case ED_KEY_LEFT:
- EdLeft(sed);
- goto mvsrncur;
- case ED_KEY_REDRAW: goto mvsrncur;
- case ED_KEY_CTRL_LEFT:
-left:
- EdWordLeft(sed);
- goto mvsrncur;
- case ED_KEY_CTRL_RIGHT:
- EdWordRight(sed);
- goto mvsrncur;
- case ED_KEY_BACKSPACE:
- //Check for a tab
- EdBackspace(sed);
- goto mvsrncur;
- case ED_KEY_INSERT: //TODO
- goto mvsrncur;
- case ED_KEY_DELETE: //TODO
- goto mvsrncur;
- default:
- if(key=='\n') {
- U8 *needle=Rope2Str(sed->lines->text); //Only one line
- if(StrFirstOcc(needle,"\n")) *StrFirstOcc(needle,"\n")=0;
- if(StrLen(needle))
- StrCpy(prevs,needle);
- else {
- Free(needle);
- needle=StrNew(prevs);
- }
- I64 origln=ed->cury;
- I64 curln=origln;
- CLine *ln=GetLine(ed, ed->cury);
- I64 lnoff=ed->curx;
- Bool wrapped_around=FALSE;
-loop2:
- while(ln) {
- U8 *txt=Rope2Str(ln->text);
- U8 *find=StrIMatch(txt+lnoff,needle);
- Free(txt);
- if(find) {
- ed->cury=curln;
- ed->_curx=ed->curx=find-txt+StrLen(needle);
- Free(needle);
- goto en;
- }
- if(wrapped_around&&curln==origln) goto fail;
- lnoff=0;
- ln=ln->next;
- curln++;
- }
- ln=ed->lines;
- curln=0;
- wrapped_around=TRUE;
- goto loop2;
-fail:
- Free(needle);
- goto en;
- }
- I64 soff=GetLineOffset(sed, sed->cury)+sed->curx++;
- U8 buffer[2]= {key,0};
- EditorInsText(sed,buffer,soff,TRUE);
- }
-mvsrncur:
- DrawEditor(ed,ED_DRAW_DFT|ED_DRAW_NO_RENDER);
- sed->window->y=SDL_WinY(ed->window)-1;
- DrawEditor(sed,ED_DRAW_SEARCH|ED_DRAW_NO_RENDER);
- SDL_DrawWin(ed.window,sed.window);
- goto loop;
-en:
- DrawEditor(ed);
- FreeEditor(sed);
-}
-I64 Edit(CEditor *ed);
-//interactive tells us to enter the autcomplete
-Bool DrawAutocomplete(CEditor *parent,Bool interactive=FALSE) {
- Bool ret=FALSE;
- I64 wx1=0;
- I64 wy1=0;
- I64 sw=SDL_WinX(parent->window);
- I64 sh=SDL_WinY(parent->window);
- CLine *ln=GetLine(parent, parent->cury);
- U8 *text=Rope2Str(ln->text);
- I64 idx=parent->curx;
- if(idx==0) goto fin;
- --idx;
-loop0:
- if(idx==0) goto begin;
- switch(text[idx]) {
- case 'a'...'z':
- case 'A'...'Z':
- case '0'...'9':
- case '_':
- idx--;
- goto loop0;
- default:
- idx++;
- }
-begin:
- if(idx==parent->curx) goto fin;
- I64 screenx=wx1+parent->curx-parent->x_scroll;
- I64 screeny=wy1+parent->cury-parent->vp_start_line+parent->margin_top;
- I64 len=parent->curx-idx;
- U8 *sub=StrNCpy(MAlloc(len+1),text+idx,len);
- if(StrLen(sub)) ret=TRUE;
- I64 cnt;
- I64 active=-1;
-loop:
- CTrie **ents=FuzzyMatch(parent->tags, sub, &cnt);
- if(!cnt) goto free;
- I64 maxlen=StrLen(ents[cnt-1]->fullname); //Ents are sorted by length
- if(screenx+1<sw&&screeny+1<sh) {
- CSDL_TextWin *ac=SDL_NewTextWin(MinI64(maxlen,sw-screenx-wx1),MinI64(cnt,sh-screeny-wy1));
- ac->begx=screenx+1,ac->begy=screeny+1;
- I64 iter=0;
- for(; iter<cnt; iter++) {
- len=StrLen(ents[iter]->fullname);
- I64 chr=0;
- if(iter==active)
- ac->cur_cp=CP_AC_SEL;
- else
- ac->cur_cp=CP_AC_UNSEL;
- ac->y=iter,ac->x=0;
- I64 cap=SDL_WinX(ac);
- WriteWithinWin(ac,ents[iter]->fullname);
- while(len++<cap) {
- SDL_AddCh(ac,' ');
- }
- }
- DrawEditor(parent, ED_DRAW_DFT|ED_DRAW_NO_RENDER);
- SDL_DrawWin(parent->window, ac);
- SDL_DestroyTextWin(ac);
- }
- if(interactive) {
-winput:
- I64 key=GetKey();
- switch(key) {
- case ERR:
- goto winput;
- case ED_KEY_UP:
- active=MaxI64(0,--active);
- goto loop;
- case ED_KEY_DOWN:
- active=MinI64(cnt-1,++active);
- goto loop;
- case '\n':
- if(active==-1) active=0;
- I64 off=GetLineOffset(parent,parent->cury);
- EditorDelText(parent, off+idx,off+parent->curx,TRUE);
- EditorInsText(parent, ents[active]->name, off+idx,TRUE);
- parent->_curx=parent->curx=(idx+StrLen(ents[active]->name));
- goto free;
- default:
- goto free;
- }
- }
-free:
- Free(ents),Free(sub);
-fin:
- Free(text);
- SDL_DrawWin(parent->window);
- return ret;
-}
-class CMenuEnt {
- U8 *name;
- U8 key;
- I64(*callback)(CEditor *ed);
-};
-U8 *Editor2Str(CEditor *ed,I64 *cnt) {
- CLine *lns=ed->lines;
- I64 len=0;
- while(lns) {
- len+=RopeLength(lns->text);
- lns=lns->next;
- }
- U8 *ret=MAlloc(len+1);
- lns=ed->lines,len=0;
- while(lns) {
- U8 *tmp=Rope2Str(lns->text);
- StrCpy(ret+len,tmp);
- Free(tmp);
- len+=RopeLength(lns->text);
- lns=lns->next;
- }
- if(cnt) *cnt=len;
- return ret;
-}
-U8 *FileDialog(CEditor *parent);
-I64 GotoSymbol(CEditor *ed);
-I64 SaveDocAs(CEditor *ed);
-/**
- * This will color the lines based on diagnostitc
- */
-U0 MarkLineColors(CEditor *ed) {
- if(!ed->fn) return;
- CLine *line=ed->lines;
- while(line) {
- line->flags&=~(ED_LNF_WARN|ED_LNF_ERR);
- line=line->next;
- }
- CDiag *diag=ed->diags;
- while(diag) {
- if(0!=StrCmp(diag->fn,ed->fn)) goto next;
- line=GetLine(ed,diag->ln-1); //Diag lines are 1 indexes
- if(line) {
- //Errors>warning
- if(line->flags&ED_LNF_ERR) goto next;
- if(diag->type==DIAG_ERR) {
- line->flags&=~ED_LNF_WARN;
- line->flags|=ED_LNF_ERR;
- line->diag=diag;
- } else {
- line->flags|=ED_LNF_WARN;
- line->diag=diag;
- }
- } else ;//???
- next:
- diag=diag->next;
- }
-}
-I64 SaveDoc(CEditor *ed) {
- if(!ed->fn) {
- SaveDocAs(ed);
- } else {
- CSDL_TextWin *msgs=SDL_NewTextWin(SDL_WinX(ed->window),SDL_WinY(ed->window));
- SDL_Print(msgs,"SAVING FILE\n");
- SDL_DrawWin(msgs);
- U8 *etxt=Editor2Str(ed,&cnt);
- FileWrite(ed->fn,etxt,cnt);
- Free(etxt);
- FreeTrie(ed->tags);
- FreeDiags(ed->diags);
- SDL_Print(msgs,"Generating tags and diagnostics.\n");
- SDL_DrawWin(msgs);
- CreateTagsAndErrorsFiles("TAGS","ERRS",ed->fn);
- SDL_Print(msgs,"Parsing Tags.\n");
- SDL_DrawWin(msgs);
- ed->tags=ReadTags("TAGS");
- ed->diags=ParseDiags("ERRS");
- SDL_Print(msgs,"Garbage collecting.\n");
- SDL_DrawWin(msgs);
- GC_Collect();
- MarkLineColors(ed);
- SDL_DrawWin(ed->window);
- }
- return ED_RET_OK;
-}
-
-I64 SaveDocAs(CEditor *ed) {
- U8 *new=FileDialog(ed);
- if(new) {
- Free(ed->fn);
- ed->fn=new;
- SaveDoc(ed);
- }
- return ED_RET_OK;
-}
-I64 OpenDoc(CEditor *ed) {
- U8 *new=FileDialog(ed);
- if(new) {
- I64 ret=OpenFile(new);
- return ret;
- }
- return ED_RET_OK;
-}
-U0 DrawMenuDropdown(CEditor *ed,CMenuEnt *ent,I64 off,I64 active=-1) {
- I64 x=0;
- I64 he=SDL_WinY(ed->window);
- I64 w=SDL_WinX(ed->window);
- I64 mwidth=0;
- I64 h=0;
- while(ent[h].name) {
- mwidth=MaxI64(mwidth,StrLen(ent[h].name));
- h++;
- }
- if(!h) return;
- CSDL_TextWin *win=SDL_NewTextWin(MinI64(mwidth,w-off),MinI64(h, he-1));
- win->begy=1;
- win->begx=off;
- I64 i;
- for(i=0; i!=h; i++) {
- if(active==i) win->cur_cp=CP_AC_SEL;
- else win->cur_cp=CP_AC_UNSEL;
- win->y=i,win->x=0;
- SDL_Print(win,ent[i].name);
- I64 len=StrLen(ent[i].name);
- while(len++<mwidth) SDL_AddCh(win,' ');
- }
- DrawEditor(ed,ED_DRAW_DFT|ED_DRAW_NO_RENDER);
- SDL_DrawWin(ed->window,win);
- SDL_DestroyTextWin(win);
-}
-I64 BufferSelect(CEditor *ed);
-U0 EdCopy(CEditor *ed) {
- U8 *clip=EdGetSelText(ed);
- SDL_SetClipboardText(clip);
- Free(clip);
- ed->sel_start=ed->sel_end=-1;
-}
-U0 EdPaste(CEditor *ed) {
- U8 *clip=SDL_GetClipboardText;
- EditorInsText(ed,clip,GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
- Free(clip);
-}
-U0 EdCut(CEditor *ed) {
- U8 *clip=EdGetSelText(ed);
- SDL_SetClipboardText(clip);
- EdDelSel(ed);
- Free(clip);
-}
-//Draws at first line
-U0 AddMenuBar(CEditor *ed,I64 active=-1) {
- I64 ret=ED_RET_OK;
- ed->margin_top=1;
- CMenuEnt File[]= {
- {"[S]ave",'s',&SaveDoc},
- {"Save [A]s",'a',&SaveDocAs},
- {"[O]pen File",'o',&OpenDoc},
- {"[B]uffer Select",'b',&BufferSelect},
- {NULL,0,NULL},
- };
- CMenuEnt Edit[]={
- {"[C]opy",'c',&EdCopy},
- {"Cu[t]",'t',&EdCut},
- {"[P]aste",'p',&EdPaste},
- {NULL,0,NULL},
- };
- CMenuEnt Code[]= {
- {"[G]oto Symbol",'g',&GotoSymbol},
- {"[C]ompile Check",'c',&ShowDiagsWindow},
- {NULL,0,NULL},
- };
- I64 x=getbegx(stdscr);
- I64 y=getbegy(stdscr);
- I64 w=getmaxx(stdscr);
- class {
- CMenuEnt *spec;
- U8 *name;
- U8 key;
- } cats[]= {
- {&File,"[F]ile",'f'},
- {&Edit,"[E]dit",'e'},
- {&Code,"[C]ode",'c'},
- };
- I64 cnt=sizeof(cats)/sizeof(*cats),cur,active_sub=0;
- goto draw;
-loop:
- I64 key=GetKey();
- switch(key) {
- case ERR: goto loop;
- case ED_KEY_ESCAPE: goto en;
- case ED_KEY_UP:
- active_sub=MaxI64(0,--active_sub);
- break;
- case ED_KEY_DOWN:
- if(cats[active].spec[++active_sub].name==NULL) --active_sub;
- break;
- case ED_KEY_LEFT:
- active=MaxI64(0,--active),active_sub=0;
- break;
- case ED_KEY_RIGHT:
- active=MinI64(cnt-1,++active),active_sub=0;
- break;
- case ED_KEY_REDRAW: goto draw;
- case '\n':
- if(cats[active].spec[active_sub].callback)
- ret=(cats[active].spec[active_sub].callback[0])(ed);
- goto en;
- default:
- I64 s=0;
- if(active!=-1)
- for(; cats[active].spec[s].name; s++) {
- if(cats[active].spec[s].key==key) {
- ret=(cats[active].spec[s].callback[0])(ed);
- goto en;
- }
- }
- }
-draw:
- ed->window->x=ed->window->y=0;
- I64 off=0,sel_off=-1;
- for(cur=0; cur!=cnt; cur++) {
- if(cur==active) {
- ed->window->cur_cp=CP_MENU_SEL;
- sel_off=cur;
- } else
- ed->window->cur_cp=CP_MENU_UNSEL;
- SDL_Print(ed->window,cats[cur].name);
- if(cur>=active)
- ; //Do Nothing
- else
- off+=StrLen(cats[cur].name);
- }
- SDL_ClrToEOL(ed->window);
- if(sel_off!=-1) {
- DrawEditor(ed, ED_DRAW_DFT&(~ED_DRAW_MENUBAR));
- if(DrawMenuDropdown(ed,cats[active].spec, off,active_sub)==ED_RET_QUIT) return ED_RET_QUIT;
- }
- if(active!=-1)
- goto loop;
-en:
- return ret;
-}
-U0 FreeEditor(CEditor *ed) {
- CLine *ln=ed->lines;
- while(ln) {
- CLine *n=ln->next;
- FreeLine(ln);
- ln=n;
- }
- SDL_DestroyTextWin(ed->window);
- Free(ed->dirty_screen_lines);
- Free(ed->line_cache);
- if(ed->tags) FreeTrie(ed->tags);
- if(ed->diags) FreeDiags(ed->diags);
- Free(ed);
-}
-U8 *RemoveNL(U8 *t) {
- U8 *f;
- if(f=StrFirstOcc(t,"\n")) *f=0;
- return t;
-}
-U8 **FuzzySymbolSelect(CEditor *ed,U8 *str) {
- I64 cnt;
- CTrie **t=FuzzyMatch(ed->tags, str,&cnt);
- U8 **ret=MAlloc((cnt+1)*sizeof(U8*));
- while(--cnt>=0) {
- ret[cnt]=StrNew(t[cnt]->fullname);
- }
- Free(t);
- return ret;
-}
-U8 *FuzzySelectWindow(CEditor *parent,U8** (*match_cb)(CEditor *ed,U8 *str),U8 *init=NULL) {
- CEditor *ed=EditorNew();
- if(init) EditorInsText(ed,init,0);
- I64 active=-1,idx;
- if(!init)
- U8 **matches=(*match_cb)(parent,"");
- else
- matches=(*match_cb)(parent,init);
- goto draw;
- loop:
- I64 key=GetKey();
- switch(key) {
- case ERR: goto loop;
- case ED_KEY_ESCAPE:
- for(idx=0;matches[idx];idx++)
- Free(matches[idx]);
- Free(matches);
- return NULL;
- case ED_KEY_UP:
- active=MaxI64(0,--active);
- goto draw;
- case ED_KEY_DOWN:
- if(active==-1) {active=0; goto draw;}
- if(active>=SDL_WinY(ed->window)-1) goto loop;
- if(!matches[active]) goto loop;
- if(!matches[active+1]) goto loop;
- active++;
- goto draw;
- case ED_KEY_CTRL_LEFT:
- EdWordLeft(ed);
- goto draw;
- case ED_KEY_CTRL_RIGHT:
- EdWordRight(ed);
- goto draw;
- case ED_KEY_LEFT:
- left:
- EdLeft(ed);
- goto draw;
- case ED_KEY_BACKSPACE:
- EdBackspace(ed);
- goto update;
- case ED_KEY_REDRAW: goto draw;
- case ED_KEY_RIGHT:
- right:
- EdRight(ed);
- goto draw;
- case '\n':
- U8 *ret=NULL;
- for(idx=0;matches[idx];idx++)
- if(active!=idx) Free(matches[idx]);
- if(active==-1) {
- ret=RemoveNL(Rope2Str(ed->lines->text));
- } else {
- ret=matches[active];
- }
- Free(matches);
- parent->margin_bottom=0;
- SDL_DrawWin(parent->window);
- return ret;
- default:
- U8 buffer[]={key,0};
- EditorInsText(ed, buffer,ed->curx,TRUE);
- update:
- active=-1;
- for(idx=0;matches[idx];idx++)
- Free(matches[idx]);
- Free(matches);
- U8 *t=RemoveNL(Rope2Str(ed->lines->text));
- matches=(*match_cb)(parent,t);
- Free(t);
- if(key!=ED_KEY_BACKSPACE)
- goto right;
- }
- draw:
- FocusCursor(ed);
- if(active==-1)
- ed->window->cur_cp=CP_FUZZY_SEL_A;
- else
- ed->window->cur_cp=CP_FUZZY_UNSEL_A;
- t=RemoveNL(Rope2Str(ed->lines->text));
- ed->window->y=ed->window->x=0;
- SDL_ClrToEOL(ed->window);
- WriteWithinView(ed,t, 0);
- idx=1;
- for(;idx<SDL_WinY(ed->window);idx++) {
- if(!matches[idx-1]) break;
- U8 *mat=matches[idx-1];
- U8 *tc=t;
- I64 offset=0;
- ed->window->y=idx,ed->window->x=0;
- hl:
- if(active==idx-1)
- ed->window->cur_cp=CP_FUZZY_SEL_A;
- else
- ed->window->cur_cp=CP_FUZZY_UNSEL_A;
- U8 buffer2[]={*(tc++),0};
- U8 *chr=StrFirstOcc(mat,buffer2);
- if(!chr) {
- WriteWithinView(ed,mat, offset);
- mat+=StrLen(mat);
- } else {
- U8 *slice=StrNCpy(MAlloc(chr-mat+1),mat,chr-mat);
- WriteWithinView(ed,slice, offset);
- mat+=StrLen(slice);
- offset+=StrLen(slice);
- Free(slice);
- if(active==idx-1)
- ed->window->cur_cp=CP_FUZZY_SEL_B;
- else
- ed->window->cur_cp=CP_FUZZY_UNSEL_B;
- WriteWithinView(ed,buffer2, offset++);
- mat++;
- }
- if(*mat) goto hl;
- SDL_ClrToEOL(ed->window);
- }
- for(;idx<SDL_WinY(ed->window);idx++) {
- ed->window->y=idx,ed->window.x=0;
- SDL_ClrToEOL(ed->window);
- }
- ed->window->cury=0,ed->window->curx=ed->curx-ed->x_scroll;
- ed->window->cur_enabled=TRUE;
- SDL_DrawWin(ed->window);
- ed->window->cur_enabled=FALSE;
- Free(t);
- goto loop;
-}
-I64 OpenFile(U8 *name,I64 ln=0) {
- loop:
- CDirEntry *find=FilesFind(name,FUF_SINGLE);
- if(find) {
- DirEntryFree(find);
- name=FileNameAbs(name);
- } else {
- name=StrNew(name);
- FileWrite(name,"",0);
- goto loop;
- }
- CBuffer *buf;
- if(buf=HashFind(name,buffers)) {
- Free(name);
- buf->ed->cury=MinI64(ln,GetLineCount(buf->ed));
- return Edit(buf->ed);
- }
- I64 cnt;
- U8 *text=FileRead(name,&cnt);
- if(!text) return ED_RET_OK;
- CEditor *new=EditorNew();
- EditorInsText(new,text,0);
- new->fn=StrNew(name);
- new->cury=MinI64(ln,GetLineCount(new));
- Free(text);
- CreateTagsAndErrorsFiles("TAGS","ERRS",new->fn);
- new->tags=ReadTags("TAGS");
- new->diags=ParseDiags("ERRS");
- MarkLineColors(new);
- buf=MAlloc(sizeof(*buf));
- buf->str=StrNew(name);
- buf->ed=new;
- HashAdd(buf,buffers);
- Free(name);
- return Edit(new);
-}
-U8 **FuzzyFile(CEditor *ed,U8 *pat) {
- U8 *pat2=MStrPrint("%s*",pat);
- CDirEntry *ents=FilesFind(pat2);
- Free(pat2);
- CDirEntry *orig=ents;
- I64 cnt=0;
- while(ents) {
- ents=ents->next,cnt++;
- }
- U8 **ret=MAlloc(sizeof(U8*)*(++cnt));
- ents=orig,cnt=0;
- while(ents) {
- ret[cnt++]=StrNew(ents->name);
- ents=ents->next;
- }
- if(orig)
- DirEntryFree(orig);
- return ret;
-}
-I64 GotoSymbol(CEditor *ed) {
- U8 *str=FuzzySelectWindow(ed,&FuzzySymbolSelect);
- if(!str) return ED_RET_OK;
- U8 *orig=str;
- CTrie *tags=ed->tags;
- while(*str&&tags) {
- try {
- tags=tags->ents[TrieChrIdx(*str++)];
- } catch {
- Fs->catch_except=1;
- return ED_RET_OK;
- }
- }
- Free(orig);
- if(tags)
- return OpenFile(tags->fn, tags->ln);
- return ED_RET_OK;
-}
-U8 *FileDialog(CEditor *parent) {
- U8 * fn=NULL;
- loop:
- fn=FuzzySelectWindow(parent, &FuzzyFile,fn);
- if(!fn) return fn;
- if(IsDir(fn)) {
- U8 *dir;
- #if IsWindows
- dir=MStrPrint("%s\\",fn);
- #else
- dir=MStrPrint("%s/",fn);
- #endif
- Free(fn);
- fn=dir;
- goto loop;
- }
- return fn;
-}
-U8 **FuzzyBufferSel(CEditor *ed,U8 *pat) {
- U8 **ret=NULL,*orig=pat;
- loop:
- I64 cnt=buffers->mask+1,cnt2=0;
- while(--cnt>=0) {
- CBuffer *bucket=buffers->body[cnt];
- for(;bucket;bucket=bucket->next) {
- U8 *str=bucket->str;
- pat=orig;
- next:
- if(!*pat) {
- if(ret)
- ret[cnt2]=StrNew(bucket->str);
- cnt2++;
- goto cont;
- }
- U8 buffer[]={*pat++,0};
- str=StrFirstOcc(str,buffer);
- if(str) {
- str++;
- goto next;
- }
- cont:
- }
- }
- if(!ret) {
- ret=MAlloc(sizeof(U8*)*(1+cnt2));
- goto loop;
- }
- return ret;
-}
-I64 BufferSelect(CEditor *ed) {
- U8 *sel=FuzzySelectWindow(ed,&FuzzyBufferSel);
- if(sel) {
- CBuffer *buf=HashFind(sel,buffers);
- I64 ret=Edit(buf->ed);
- Free(sel);
- return ret;
- }
- return ED_RET_OK;
-}
-I64 EdOffset(CEditor *ed) {
- return GetLineOffset(ed,ed->cury)+ed->curx;
-}
-I64 EdClearSelect(CEditor *ed) {
- ed->sel_start=ed->sel_end;
-}
-I64 EdSelLeft(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdLeft(ed);
- ed->sel_end=EdOffset(ed);
-}
-I64 EdSelRight(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdRight(ed);
- ed->sel_end=EdOffset(ed);
-}
-I64 EdSelUp(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdUp(ed);
- ed->sel_end=EdOffset(ed);
-}
-I64 EdSelDown(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) ed->sel_start=EdOffset(ed);
- EdDown(ed);
- ed->sel_end=EdOffset(ed);
-}
-U0 EdDelSel(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) return;
- if(ed->sel_start>ed->sel_end) SwapI64(&ed->sel_end,&ed->sel_start);
- EditorDelText(ed,ed->sel_start,ed->sel_end,TRUE);
- EdJumpToChar(ed,ed->sel_start);
- ed->sel_start=ed->sel_end=-1;
-}
-U8 *EdGetSelText(CEditor *ed) {
- Bool in_select=ed->sel_start!=ed->sel_end;
- if(!in_select) return NULL;
- if(ed->sel_start>ed->sel_end) {
- SwapI64(&ed->sel_end,&ed->sel_start);
- }
- U8 *ret=MAlloc(ed->sel_end-ed->sel_start+1);
- I64 cnt=GetLineCount(ed),idx=0;
- I64 offset=0,reti=0;
- for(;idx!=cnt;idx++) {
- offset=GetLineOffset(ed,idx);
- CRope *text;
- I64 en=RopeLength(text=GetLine(ed,idx)->text);
- {
- I64 st=MaxI64(ed->sel_start-offset,0);
- en=MinI64(en,ed->sel_end-offset);
- if(st>en) goto next;
- U8 *lntxt=Rope2Str(text);
- StrNCpy(ret+reti,lntxt+st,en-st);
- Free(lntxt);
- reti+=en-st;
- if(reti>=ed->sel_end-ed->sel_start) {
- goto ret;
- }
- next:
- }
- }
- ret:
- return ret;
-}
-I64 Edit(CEditor *ed) {
- goto mvsrncur;
-loop:
- I64 key=GetKey,cnt,cnt2;
- if(key==ERR) goto loop;
- I64 eoff,soff;
- switch(key) {
- case 'e'&0x1f:
- if(ed->diags)
- if(ED_RET_QUIT==ShowDiagsWindow(ed)) return ED_RET_QUIT;
- break;
- /**
- * [F]ile
- * [C]ode
- */
- case 'x'&0x1f:
- U8 *clip=EdGetSelText(ed);
- EdDelSel(ed);
- SDL_SetClipboardText(clip);
- Free(clip);
- goto mvsrncur;
- case 'c'&0x1f:
- clip=EdGetSelText(ed);
- SDL_SetClipboardText(clip);
- EdClearSelect(ed);
- goto mvsrncur;
- case 'v'&0x1f:
- EdDelSel(ed);
- clip=SDL_GetClipboardText();
- EditorInsText(ed,clip,GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
- I64 righti=StrLen(clip);
- Free(clip);
- while(--righti>=0) EdRight(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_UP:
- EdSelUp(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_DOWN:
- EdSelDown(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_LEFT:
- EdSelLeft(ed);
- goto mvsrncur;
- case ED_KEY_SHIFT_RIGHT:
- EdSelRight(ed);
- goto mvsrncur;
- case ED_KEY_ESCAPE:
- case ALT_KEY('f'):
- if(DrawEditor(ed,ED_DRAW_DFT,,0)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
- goto mvsrncur;
- case ALT_KEY('e'):
- if(DrawEditor(ed,ED_DRAW_DFT,,1)==ED_RET_QUIT) return ED_RET_QUIT;
- goto mvsrncur;
- case ALT_KEY('c'):
- if(DrawEditor(ed,ED_DRAW_DFT,,2)==ED_RET_QUIT) return ED_RET_QUIT; //First menu item
- goto mvsrncur;
- case ED_KEY_RESIZE:
- goto mvsrncur;
- case ED_KEY_UP:
- EdClearSelect(ed);
- EdUp(ed);
- goto mvsrncur;
- case ED_KEY_DOWN:
- EdClearSelect(ed);
- EdDown(ed);
- goto mvsrncur;
- case ED_KEY_REDRAW: goto mvsrncur;
- case ED_KEY_LEFT:
-left:
- EdClearSelect(ed);
- EdLeft(ed);
- goto mvsrncur;
- case ED_KEY_RIGHT:
-right:
- EdClearSelect(ed);
- EdRight(ed);
- goto mvsrncur;
- case ED_KEY_END:
- EdClearSelect(ed);
- ed->_curx=ed->curx=0;
- goto mvsrncur;
- case ED_KEY_HOME:
- EdClearSelect(ed);
- CLine *heline=GetLine(ed,ed->cury);
- ed->_curx=ed->curx=RopeLength(heline->text);
- goto mvsrncur;
- case ED_KEY_CTRL_UP:
- EdClearSelect(ed);
- goto pageup;
- case ED_KEY_CTRL_DOWN:
- EdClearSelect(ed);
- goto pagedown;
- case ED_KEY_CTRL_LEFT:
- EdClearSelect(ed);
- EdWordLeft(ed);
- goto mvsrncur;
- case ED_KEY_CTRL_RIGHT:
- EdClearSelect(ed);
- EdWordRight(ed);
- goto mvsrncur;
- case ED_KEY_BACKSPACE:
- if(ed->sel_start!=ed->sel_end)
- EdDelSel(ed);
- else
- EdBackspace(ed);
- goto mvsrncur;
- case ED_KEY_PAGEUP:
-pageup:
- EdPageUp(ed);
- goto mvsrncur;
- case ED_KEY_PAGEDOWN:
-pagedown:
- EdPageDown(ed);
- goto mvsrncur;
- case '\t':
- if(!DrawAutocomplete(ed,TRUE)) {
- EditorInsText(ed," ",GetLineOffset(ed,ed->cury)+ed->curx,TRUE);
- ed->curx+=4;
- }
- goto mvsrncur;
- case 'y'&0x1f:
- Redo(ed);
- goto mvsrncur;
- case 'z'&0x1f:
- Undo(ed);
- goto mvsrncur;
- case 'b'&0x1f:
- BufferSelect(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- case 't'&0x1f:
- GotoSymbol(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- case 'o'&0x1f:
- OpenDoc(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- case 's'&0x1f:
- SaveDoc(ed);
- SDL_DrawWin(ed->window);
- goto mvsrncur;
- default:
- if(key==('q'&0x1f)) {return ED_RET_QUIT;}
- if(key==('f'&0x1f)) {
- EdSearch(ed);
- goto mvsrncur;
- }
- soff=GetLineOffset(ed, ed->cury)+ed->curx++;
- U8 buffer[2]= {key,0};
- EditorInsText(ed,buffer,soff,TRUE);
- if(key=='\n') {
- CLine *prev=GetLine(ed,ed->cury);
- EdRight(ed);
- U8 *margin=MStrPrint("%*c",IndentLevel(prev),' ');
- EditorInsText(ed,margin,soff+1,TRUE);
- ed->_curx=ed->curx=4*IndentLevel(prev);
- }
- goto mvsrncur;
- }
-mvsrncur:
- //Move cursor left if at newline
- CLine *lline=GetLine(ed,ed->cury);
- if(ed->curx+1>RopeLength(lline->text)) ed->curx=RopeLength(lline->text)-1;
- DrawEditor(ed,ED_DRAW_DFT);
- goto loop;
-exit:
- return ED_RET_OK;
-}
-/*
-EditorInsText(ed,"if(Potato)\nx{3.14 'abc\\'def\\\\'}\n",0);
-EditorInsText(ed,"Tom\nato\n",4);
-DrawEditor(ed);
-FreeEditor(ed);
-CEditor *ed=EditorNew();
-EditorInsText(ed,"012\n345\n678\n9ab",0);
-EditorDelText(ed,1,2);
-EditorDelText(ed,1,15-1);
-DrawEditor(ed);
-*/
-SDL_InitScr;
-CEditor *ed=EditorNew(TRUE);
-Edit(ed);
-U0 FreeBuffer(U0 *buf) {
- FreeEditor(buf(CBuffer*)->ed);
-}
-U0 SDL_ExitScr() {
- SDL_DestroyWindow(global_window);
- SDL_FreeSurface(global_font);
- global_window=NULL,global_font=NULL;
- SDL_StopTextInput;
- HashTableDel(buffers,(&FreeBuffer)(U0*));
-}
-SDL_ExitScr;
-
-
-
-
-
-
-
diff --git a/README.MD b/README.MD
index acfb32a..a978ca0 100644
--- a/README.MD
+++ b/README.MD
@@ -3,11 +3,13 @@ This compiler contains a bounds checker and a debugger,but in order to use these
This compiler is currently mostly a compiler,but it needs a better runtime. To get started,`#include "HolyEd/EDITOR.HC"` and use the goto-symbol function `Alt+c g or Ctrl-t` to explore the source.(you will need the compiler's source code for `HolyEd/EDITOR.HC`).
+There is a `Debian_pkg.sh` and `FreeBSD_pkg.sh` for building packages for those platforms. You can use 3Days.nsi with NSIS to build an installer for windows.
+
# Debugger(BSAT Before Space and Time)
Start the compiler with `-d`(or `-b` for bounds checking) and call `Debugger;`
# Building
-You will need yasm,gnu bison,gcc and make. Other than that all dependencies are included in `ext/` A modified [Oregon trail port from TinkerOS ](https://github.com/tinkeros/OT1975) is provided in the source code. Do `make installer` to make an installer for linux via `ext/epm`. This will require fltk for a graphical installer.
+You will need yasm,gnu bison,gcc and make and sdl2. Other than that all dependencies are included in `ext/` A modified [Oregon trail port from TinkerOS ](https://github.com/tinkeros/OT1975) is provided in the source code. Do `make installer` to make an installer for linux via `ext/epm`. This will require fltk for a graphical installer.
# Editor
This comes with a barebones editor,you can run it using `#include "HolyEd/EDITOR.HC"` Press `alt+f` to access the file menu and `alt+c` to access the code menu(Which gives a fuzzy symbol select and compile check). If you are using windows terminal you may want to change the cursor shape to a block because the background is white
@@ -54,6 +56,8 @@ I64 x=#exe{StreamPrint("10");};
- Garbage collection is disabled when running HolyC code.
- (Finer) syntax checking is done only when compiling a statement or function.
- `#include` uses the file path scheme of the OS,so you should
+ - There is no lexical scoping.
+ - Like TempleOS,pointers can be nested 3 levels.
```
#if IsWindows
#include "C:\\File.HC"
diff --git a/ed_screenshot.png b/ed_screenshot.png
index ed29b5c..d2fce1e 100644
--- a/ed_screenshot.png
+++ b/ed_screenshot.png
Binary files differ