/* * TEXT1.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" #define nomemory() { memoryfail = 1; } char RecallBuf[256]; setpen(line) { register short pen = (Ep == BEp && line >= BSline && line <= BEline) ? 2 : 1; if (Comlinemode) pen = 1; if (pen != Rp->FgPen) SetAPen(Rp, pen); } text_init() { register ED *e; register ED *ep = Ep; text_switch(NULL); e = (ED *)allocb(sizeof(ED)); if (e == NULL) return(0); bzero(e, sizeof(ED)); e->Win = Win; if (ep) { e->Insertmode = ep->Insertmode; e->Tabstop = ep->Tabstop; e->Wordwrap = ep->Wordwrap; } else { e->Insertmode = 1; e->Tabstop = 4; } e->Lines = 1; e->Maxlines = 32; e->List = (ubyte **)allocl(e->Maxlines); e->List[0] = allocb(1); e->List[0][0] = Current[0] = Clen = 0; e->IWiny = 16; e->dirlock = (ep) ? ep->dirlock : Dirlock; llink(&Base, e); strcpy(e->Name, "unnamed"); Ep = e; text_cursor(1); return(1); } text_switch(win) WIN *win; { register ED *e; if (win) text_sync(); if (win) { for (e = Base; e; e = e->next) { if (e->Win == win) { Ep = e; Win = win; Rp = Win->RPort; text_load(); if (!Ep->iconmode) { set_window_params(); window_title(); } return(1); } } return(0); } } text_sync() { register ED *ep = Ep; char redraw = 0; short len; ubyte *ptr; for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len) Current[len] = '\0'; Clen = len + 1; if (!Comlinemode) { if (strlen(ep->List[ep->Line]) != Clen) { if (ptr = allocb(Clen+1)) { ep->Modified = 1; Overide = 0; FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1); ep->List[ep->Line] = ptr; } else { nomemory(); strcpy(Current, ep->List[ep->Line]); Clen = strlen(Current); } } else { if (strcmp(ep->List[ep->Line], Current)) { ep->Modified = 1; Overide = 0; } } strcpy(ep->List[ep->Line], Current); } if (Nsu == 0) { if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) { redraw = 1; ep->Topcolumn = ep->Column - (Columns>>1); if (ep->Topcolumn < 0) ep->Topcolumn = 0; } if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) { redraw = 1; ep->Topline = ep->Line - (Rows>>1); if (ep->Topline < 0) ep->Topline = 0; } } while (ep->Column > Clen) Current[Clen++] = ' '; Current[Clen] = '\0'; if (redraw) text_redisplay(); return((int)redraw); } text_load() { if (Comlinemode) return(0); strcpy(Current, Ep->List[Ep->Line]); Clen = strlen(Current); while (Ep->Column > Clen) Current[Clen++] = ' '; Current[Clen] = '\0'; } text_colno() { return(Ep->Column); } text_lineno() { return(Ep->Line+1); } text_lines() { return(Ep->Lines); } text_cols() { return((int)Clen); } text_imode() { return(Ep->Insertmode); } text_tabsize() { return((int)Ep->Tabstop); } ubyte * text_name() { return(Ep->Name); } text_uninit() { register int i; register ED *ep = Ep; freelist(ep->List, ep->Lines); FreeMem(ep->List, ep->Maxlines * sizeof(char *)); if (BEp == ep) { BEp = NULL; BSline = BEline = -1; } lunlink(ep); FreeMem(ep, sizeof(ED)); if (Base) { Ep = Base; text_load(); } else { Ep = NULL; } } inversemode(n) { if (n) { SetAPen(Rp, 3); SetDrMd(Rp, JAM2|INVERSVID); } else { setpen(Ep->Line); SetDrMd(Rp, JAM2); } } text_cursor(n) { movetocursor(); inversemode(n); if (Current[Ep->Column]) Text(Rp, Current+Ep->Column, 1); else Text(Rp, " ", 1); inversemode(0); } text_position(col, row) { register ED *ep = Ep; text_sync(); if (col == 0) col = -1; ep->Column = ep->Topcolumn + col; if (ep->Column > 254) ep->Column = 254; if (ep->Column < 0) ep->Column = 0; ep->Line = ep->Topline + row; if (ep->Line >= ep->Lines) ep->Line = ep->Lines - 1; if (ep->Line < 0) ep->Line = 0; text_load(); text_sync(); } displayblock(on) { register long start = Ep->Topline; register long lines = BEline - BSline + 1; if (start < BSline) start = BSline; if (!on) { BSline = BEline = -1; BEp = NULL; } if (Ep == BEp) text_displayseg(start - Ep->Topline, lines); } text_redrawblock(ok) { WIN *savewin = NULL; if (BEp) { if (BEp != Ep) { savewin = Ep->Win; text_switch(BEp->Win); } if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) { if (!ok) { BEp = NULL; BSline = BEline = -1; } text_displayseg(0, Rows); } if (savewin) text_switch(savewin); } if (!ok) { BEp = NULL; BSline = BEline = -1; } } text_displayseg(start, n) { register short i, c; register ubyte *ptr; register ED *ep = Ep; char ib; if (Nsu) return(0); for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) { if (Comlinemode) { if (ep->Topline + i != ep->Line) continue; ptr = Current; SetAPen(Rp, 1); } else { ptr = ep->List[ep->Topline + i]; setpen(i+ep->Topline); } for (c = ep->Topcolumn; c && *ptr; ++ptr, --c); c = strlen(ptr); if (c) { Move(Rp, COLT(0), ROWT(i)); Text(Rp, ptr, (c > Columns) ? Columns : c); } } } text_redisplay() { if (Nsu) return(0); SetAPen(Rp, 0); if (Comlinemode) RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs); else RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs); text_displayseg(0,Rows); } text_redisplaycurrline() { int row = Ep->Line - Ep->Topline; if (Nsu) return(0); SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1); text_displayseg(row, 1); } text_write(str) ubyte *str; { register short len = strlen(str); register short i; register ED *ep = Ep; if (Clen + len >= 255) { text_sync(); text_load(); } if (ep->Insertmode == 0) { i = len; if (ep->Column + len < 255) { bmov(str, Current + ep->Column, len); if (ep->Column + len >= Clen) Clen = ep->Column + len; Current[Clen] = 0; goto bin; } goto ok; } if (Clen + len < 255) { bmov(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column); bmov(str, Current + ep->Column, len); Clen += len; ScrollRaster(Rp, -len * Xsize, 0 , COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline), COL(Columns) - 1, ROW(ep->Line - ep->Topline + 1) - 1 ); i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len; bin: setpen(ep->Line); Move(Rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline)); Text(Rp, str, i); ep->Column += len; if (ep->Column - ep->Topcolumn >= Columns) text_sync(); } ok: if (Comlinemode == 0 && ep->Wordwrap) do_reformat(0); } do_up() { if (Ep->Line) { text_sync(); --Ep->Line; text_load(); if (Ep->Line < Ep->Topline) { if (Nsu == 0) { ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); --Ep->Topline; text_displayseg(0, 1); } } } else { Abortcommand = 1; } } do_scrolldown() { if (Ep->Topline + Rows < Ep->Lines) { if (Nsu == 0) { text_sync(); ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); ++Ep->Topline; ++Ep->Line; text_load(); text_displayseg(Rows-1, 1); } } else { Abortcommand = 1; } } do_scrollup() { if (Ep->Topline) { if (Nsu == 0) { text_sync(); ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); --Ep->Topline; --Ep->Line; text_load(); text_displayseg(0, 1); } } else { Abortcommand = 1; } } do_down() { if (Ep->Line + 1 < Ep->Lines) { text_sync(); ++Ep->Line; text_load(); if (Ep->Line - Ep->Topline >= Rows) { if (Nsu == 0) { ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); ++Ep->Topline; text_displayseg(Rows-1, 1); } } } else { Abortcommand = 1; } } /* * PAGEUP * PAGEDOWN * PAGESET n (n = 0 to 100 for percentage of #rows to scroll, minimum 1) * can be > 100. */ do_page() { register int n, multiplier = 1; register ED *ep = Ep; static short pctg = 80; switch(av[0][4]) { case 'u': multiplier = -1; case 'd': n = multiplier * Rows * pctg / 100; if (!n) n = multiplier; if (n > 0 && ep->Topline >= ep->Lines - Rows) return(0); text_sync(); ep->Line += n; ep->Topline += n; if (ep->Line >= ep->Lines) ep->Line = ep->Lines - 1; if (ep->Line < 0) ep->Line = 0; if (ep->Topline >= ep->Lines) ep->Topline = ep->Lines - Rows - 1; if (ep->Topline < 0) ep->Topline = 0; text_load(); if (!text_sync()) text_redisplay(); break; case 's': pctg = atoi(av[1]); break; } } do_downadd() { ubyte *ptr; if (Ep->Line + 1 == Ep->Lines) { Ep->Modified = 1; if (makeroom(32) && (ptr = allocb(1))) { Ep->List[Ep->Lines] = ptr; *ptr = 0; ++Ep->Lines; } else { nomemory(); } } do_down(); } do_left() { if (Ep->Column) { --Ep->Column; if (Ep->Column < Ep->Topcolumn) text_sync(); } else { Abortcommand = 1; } } do_right() { if (Ep->Column != 254) { if (Current[Ep->Column] == 0) { Current[Ep->Column] = ' '; Current[Ep->Column+1]= '\0'; ++Clen; } ++Ep->Column; if (Ep->Column - Ep->Topcolumn >= Columns) text_sync(); } else { Abortcommand = 1; } } do_tab() { register short n; for (n = Ep->Tabstop-(Ep->Column % Ep->Tabstop); n > 0; --n) do_right(); } do_backtab() { register short n; n = Ep->Column % Ep->Tabstop; if (!n) n = Ep->Tabstop; for (; n > 0; --n) do_left(); } do_return() { ubyte buf[256]; char *partial; if (Comlinemode) { strcpy(buf, Current); strcpy(RecallBuf, Current); partial = Partial; Partial = NULL; escapecomlinemode(); if (partial) { if (do_command(buf)) do_command(partial); free(partial); } else { do_command(buf); } } else { Ep->Column = 0; text_sync(); do_downadd(); } } do_bs() { register ED *ep = Ep; if (ep->Column) { bmov(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1); --ep->Column; --Clen; if (ep->Column < ep->Topcolumn) { text_sync(); } else { ScrollRaster(Rp, Xsize, 0, COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline), COL(Columns)-1, ROW(ep->Line - ep->Topline + 1)-1 ); if (Clen >= ep->Topcolumn + Columns) { setpen(ep->Line); Move(Rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline)); Text(Rp, Current + ep->Topcolumn + Columns - 1, 1); } } if (Comlinemode == 0 && ep->Wordwrap) do_reformat(0); } else { Abortcommand = 1; } } /* * esc, escimm */ int Savetopline, Savecolumn, Savetopcolumn; do_recall() { av[0] = (ubyte *)"escimm"; av[1] = (ubyte *)RecallBuf; do_esc(); } do_esc() { register ED *ep = Ep; if (Comlinemode) return(escapecomlinemode()); text_sync(); if (av[0][3] == 'i') strcpy(Current, av[1]); else Current[0] = 0; Clen = strlen(Current); Comlinemode = 1; returnoveride(1); Savetopline = ep->Topline; Savecolumn = ep->Column; Savetopcolumn = ep->Topcolumn; ep->Column = Clen; ep->Topcolumn = 0; ep->Topline = ep->Line - Rows + 1; SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs); SetAPen(Rp, 1); Move(Rp, COL(0), ROW(Rows-1) - 1); Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1); text_displayseg(Rows-1,1); } escapecomlinemode() { register ED *ep = Ep; if (Partial) { free(Partial); Partial = NULL; } if (Comlinemode) { strcpy(RecallBuf, Current); Comlinemode = 0; returnoveride(0); ep->Topline = Savetopline; ep->Column = Savecolumn; ep->Topcolumn = Savetopcolumn; text_load(); SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs); SetAPen(Rp, 1); text_displayseg(Rows-2,2); } } do_del() { register ED *ep = Ep; if (Current[ep->Column]) { bmov(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column); --Clen; ScrollRaster(Rp, Xsize, 0, COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline), COL(Columns)-1, ROW(ep->Line - ep->Topline + 1) - 1 ); if (Clen >= ep->Topcolumn + Columns) { setpen(ep->Line); Move(Rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline)); Text(Rp, Current+ep->Topcolumn+Columns-1, 1); } if (Comlinemode == 0 && ep->Wordwrap) do_reformat(0); } } do_top() { text_sync(); Ep->Line = 0; text_load(); text_sync(); } do_bottom() { text_sync(); Ep->Line = Ep->Lines - 1; text_load(); text_sync(); } do_firstcolumn() { if (Ep->Column) { Ep->Column = 0; text_sync(); } } do_firstnb() { for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column); if (Current[Ep->Column] == 0) Ep->Column = 0; text_sync(); } do_lastcolumn() { short i; text_sync(); i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]); if (i != Ep->Column) { Ep->Column = i; text_sync(); } } /* * GOTO [+/-]N * GOTO BLOCK start of block * GOTO START start of block * GOTO END end of block */ do_goto() { register short n, i; register ubyte *ptr = av[1]; i = 0; n = -1; switch(*ptr) { case 'b': case 's': case 'B': case 'S': n = -1; if (Ep == BEp) n = BSline; break; case 'e': case 'E': n = -1; if (Ep == BEp) n = BEline; break; case '+': i = 1; case '-': n = Ep->Line; default: n += atoi(ptr+i); } if (n >= Ep->Lines) n = Ep->Lines - 1; if (n < 0) n = 0; text_sync(); Ep->Line = n; text_load(); text_sync(); } do_screentop() { text_sync(); Ep->Line = Ep->Topline; text_load(); text_sync(); } do_screenbottom() { text_sync(); Ep->Line = Ep->Topline + Rows - 1; if (Ep->Line < 0 || Ep->Line >= Ep->Lines) Ep->Line = Ep->Lines - 1; text_load(); text_sync(); } static ubyte Fstr[256]; static ubyte Rstr[256]; static short Srch_sign; static char Doreplace; /* * findstr, repstr */ do_findstr() { if (av[0][0] == 'f') strcpy(Fstr, av[1]); else strcpy(Rstr, av[1]); } /* * findr, nextr, prevr */ do_findr() { Doreplace = 1; Srch_sign = 1; switch(av[0][0]) { case 'f': strcpy(Fstr, av[1]); strcpy(Rstr, av[2]); break; case 'p': Srch_sign = -1; break; } search_operation(); } /* * find, next, prev */ do_find() { Doreplace = 0; Srch_sign = 1; switch(av[0][0]) { case 'f': strcpy(Fstr, av[1]); break; case 'p': Srch_sign = -1; break; } search_operation(); } void search_operation() { int flen = strlen(Fstr); int rlen = strlen(Rstr); char senabled = 0; register ubyte *ptr; register int i, col; register ED *ep = Ep; text_sync(); if (!flen) { title("No find pattern"); Abortcommand = 1; return; } col = ep->Column; if (col >= strlen(ep->List[ep->Line])) col = strlen(ep->List[ep->Line]); for (i = ep->Line;;) { ptr = ep->List[i]; if (Srch_sign > 0) { while (ptr[col]) { if (Fstr[0] == ptr[col] && strncmp(Fstr,ptr+col,flen) == 0 && senabled) { goto found; } senabled = 1; ++col; } senabled = 1; if (++i >= ep->Lines) break; col = 0; } else { while (col >= 0) { if (Fstr[0] == ptr[col] && strncmp(Fstr,ptr+col,flen) == 0 && senabled) { goto found; } senabled = 1; --col; } senabled = 1; if (--i < 0) break; col = strlen(ep->List[i]); } } title("Pattern Not Found"); Abortcommand = 1; return; found: ep->Line = i; ep->Column = col; text_load(); if (Doreplace) { if (rlen > flen && rlen-flen+strlen(ptr) > 254) { title("Replace: Line Too Long"); Abortcommand = 1; return; } if (Clen-col-flen >= 0) { bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1); bmov(Rstr, Current+col, rlen); Clen += rlen-flen; } text_sync(); text_redisplaycurrline(); } else { text_sync(); } }