/* * STevie - ST editor for VI enthusiasts. ...Tim Thompson...twitch!tjt... */ #include #include #include "stevie.h" edit() { int c, c1, c2; char *p, *q; Prenum = 0; /* position the display and the cursor at the top of the file. */ Topchar = Filemem; Curschar = Filemem; Cursrow = Curscol = 0; for ( ;; ) { /* Figure out where the cursor is based on Curschar. */ cursupdate(); if ( State == INSERT ) message("Insert Mode"); /* printf("Curschar=(%d,%d) row/col=(%d,%d)", Curschar,*Curschar,Cursrow,Curscol); */ windgoto(Cursrow,Curscol); windrefresh(); c = vgetc(); if ( State != INSERT ) message(""); switch(State) { case NORMAL: /* We're in the normal (non-insert) mode. */ /* Pick up any leading digits and compute 'Prenum' */ if ( (Prenum>0 && isdigit(c)) || (isdigit(c) && c!='0') ){ Prenum = Prenum*10 + (c-'0'); break; } /* execute the command */ normal(c); Prenum = 0; break; case INSERT: /* We're in insert mode. */ switch(c){ case '\033': /* an ESCape ends input mode */ /* If we're past the end of the file, (which should */ /* only happen when we're editing a new file or a */ /* file that doesn't have a newline at the end of */ /* the line), add a newline automatically. */ if ( Curschar >= Fileend ) { insertchar('\n'); Curschar--; } /* Don't end up on a '\n' if you can help it. */ if ( Curschar>Filemem && *Curschar=='\n' && *(Curschar-1)!='\n' ) { Curschar--; } State = NORMAL; message(""); Uncurschar = Insstart; Undelchars = Ninsert; /* Undobuff[0] = '\0'; */ /* construct the Redo buffer */ p=Redobuff; q=Insbuff; while ( q= 0 ) break; message("Expecting a hexidecimal character (0-9 or a-f)"); beep(); sleep(1); } return(c); } getout() { windgoto(Rows-1,0); windrefresh(); putchar('\r'); putchar('\n'); windexit(0); } cursupdate() { char *p; int inc, c, nlines; /* special case: file is completely empty */ if ( Fileend == Filemem ) { Topchar = Curschar = Filemem; } else if ( Curschar < Topchar ) { nlines = cntlines(Curschar,Topchar); /* if the cursor is above the top of */ /* the screen, put it at the top of the screen.. */ Topchar = Curschar; /* ... and, if we weren't very close to begin with, */ /* we scroll so that the line is close to the middle. */ if ( nlines > Rows/3 ) scrolldown(Rows/3); else { /* make sure we have the current line completely */ /* on the screen, by setting Topchar to the */ /* beginning of the current line (in a strange way). */ if ( (p=prevline(Topchar))!=NULL && (p=nextline(p))!=NULL ) { Topchar = p; } } updatescreen(); } else if ( Curschar >= Botchar && Curschar < Fileend ) { nlines = cntlines(Botchar,Curschar); /* If the cursor is off the bottom of the screen, */ /* put it at the top of the screen.. */ Topchar = Curschar; /* ... and back up */ if ( nlines > Rows/3 ) scrolldown((2*Rows)/3); else scrolldown(Rows-2); updatescreen(); } Cursrow = Curscol = Cursvcol = 0; for ( p=Topchar; p= Columns ) { Curscol -= Columns; Cursrow++; } } } scrolldown(nlines) int nlines; { int n; char *p; /* Scroll up 'nlines' lines. */ for ( n=nlines; n>0; n-- ) { if ( (p=prevline(Topchar)) == NULL ) break; Topchar = p; } } /* * oneright * oneleft * onedown * oneup * * Move one char {right,left,down,up}. Return 1 when * sucessful, 0 when we hit a boundary (of a line, or the file). */ oneright() { char *p; p = Curschar; if ( (*p++)=='\n' || p>=Fileend || *p == '\n' ) return(0); Curschar++; return(1); } oneleft() { char *p; p = Curschar; if ( *p=='\n' || p==Filemem || *(p-1) == '\n' ) return(0); Curschar--; return(1); } beginline() { while ( oneleft() ) ; } oneup(n) { char *p, *np; int savevcol, k; savevcol = Cursvcol; p = Curschar; for ( k=0; k 0 ) break; /* to update the cursor, etc. */ else return(0); } p = np; } Curschar = p; /* This makes sure Topchar gets updated so the complete line */ /* is one the screen. */ cursupdate(); /* try to advance to the same (virtual) column */ /* that we were at before. */ Curschar = coladvance(p,savevcol); return(1); } onedown(n) { char *p, *np; int k; p = Curschar; for ( k=0; k 0 ) break; else return(0); } p = np; } /* try to advance to the same (virtual) column */ /* that we were at before. */ Curschar = coladvance(p,Cursvcol); return(1); }