/* * TEXT1.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" #define TU titleupdate = 1 #define nomemory() {memoryfail = 1; TU;} text_init() { register ED *e; long dirlock; text_switch(NULL); dirlock = E.dirlock; e = (ED *)MAllocate(sizeof(ED)); if (e == NULL) return(0); bzero(&E, sizeof(E)); 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 = (u_char **)MAllocate(sizeof(char *) * E.Maxlines); E.List[0] = MAllocate(1); E.List[0][0] = Current[0] = Clen = 0; E.BSline = E.BEline = -1; E.IWiny = 16; E.dirlock = dirlock; /* workbench support */ *e = E; llink(&Base, e); strcpy(E.Name, "ram:unnamed"); Ep = e; text_cursor(1); return(1); } text_switch(win) WIN *win; { register ED *e; register ED *next, **prev; if (Ep) { text_sync(); E.next = Ep->next; E.prev = Ep->prev; strcpy(E.Wtitle, Ep->Wtitle); *Ep = E; } if (win) { for (e = Base; e; e = e->next) { if (e->Win == win) { Ep = e; Win = win; Rp = Win->RPort; E = *e; text_load(); return(1); } } return(0); } } text_sync() { char redraw = 0; short len; u_char *ptr; for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len) Current[len] = '\0'; Clen = len + 1; if (!ComLineMode) { if (strlen(E.List[E.Line]) != Clen) { if (ptr = MAllocate(Clen+1)) { E.Modified = 1; FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1); E.List[E.Line] = ptr; } else { nomemory(); strcpy(Current, E.List[E.Line]); Clen = strlen(Current); } } else { if (strcmp(E.List[E.Line], Current)) E.Modified = 1; } strcpy(E.List[E.Line], Current); } if (Nsu == 0) { if (E.Column - E.Topcolumn >= Columns || E.Column < E.Topcolumn) { redraw = 1; E.Topcolumn = E.Column - (Columns>>1); if (E.Topcolumn < 0) E.Topcolumn = 0; } if (E.Line - E.Topline >= Rows || E.Line < E.Topline) { redraw = 1; E.Topline = E.Line - (Rows>>1); if (E.Topline < 0) E.Topline = 0; } } while (E.Column > Clen) Current[Clen++] = ' '; Current[Clen] = '\0'; if (redraw) text_redisplay(); return((int)redraw); } text_load() { if (ComLineMode) return(0); strcpy(Current, E.List[E.Line]); Clen = strlen(Current); while (E.Column > Clen) Current[Clen++] = ' '; Current[Clen] = '\0'; } text_titleupdate() { int r = titleupdate; titleupdate = 0; return(r); } text_lineno() { return(E.Line + 1); } text_lines() { return(E.Lines); } text_colno() { return(E.Column); } text_cols() { return((int)Clen); } text_imode() { return(E.Insertmode); } text_tabsize() { return((int)E.Tabstop); } u_char * text_name() { return(E.Name); } text_uninit() { register int i; register ED *e; for (i = 0; i < E.Lines; ++i) FreeMem(E.List[i], strlen(E.List[i])+1); FreeMem(E.List, E.Maxlines * sizeof(char *)); lunlink(Ep); FreeMem(Ep, sizeof(ED)); if (Base) { E = *Base; Ep= Base; text_load(); } else { Ep = NULL; } } inversemode(n) { if (n) { SetAPen(Rp, 3); SetDrMd(Rp, JAM2|INVERSVID); } else { SetAPen(Rp, 1); SetDrMd(Rp, JAM2); } } text_cursor(n) { movetocursor(); inversemode(n); if (Current[E.Column]) Text(Rp, Current+E.Column, 1); else Text(Rp, " ", 1); inversemode(0); } text_position(col, row) { TU; text_sync(); if (col == 0) col = -1; E.Column = E.Topcolumn + col; if (E.Column > 254) E.Column = 254; if (E.Column < 0) E.Column = 0; E.Line = E.Topline + row; if (E.Line >= E.Lines) E.Line = E.Lines - 1; if (E.Line < 0) E.Line = 0; text_load(); text_sync(); } text_displayseg(start, n) { register short i, c; register u_char *ptr; char ib; if (Nsu) return(0); for (i = start; i < start+n && E.Topline + i < E.Lines; ++i) { if (ComLineMode) { if (E.Topline + i != E.Line) continue; ptr = Current; } else { ptr = E.List[E.Topline + i]; } for (c = E.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); SetAPen(Rp, 1); text_displayseg(0,Rows); } text_redisplaycurrline() { int row = E.Line - E.Topline; if (Nsu) return(0); SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1); SetAPen(Rp, 1); text_displayseg(row, 1); } text_write(str) u_char *str; { short len = strlen(str); short i; if (Clen + len >= 255) { text_sync(); text_load(); } if (E.Insertmode == 0) { i = len; if (E.Column + len < 255) { bmov(str, Current + E.Column, len); if (E.Column + len >= Clen) Clen = E.Column + len; Current[Clen] = 0; goto bin; } goto ok; } if (Clen + len < 255) { bmov(Current + E.Column, Current + E.Column + len, Clen+1-E.Column); bmov(str, Current + E.Column, len); Clen += len; ScrollRaster(Rp, -len * Xsize, 0 , COL(E.Column - E.Topcolumn), ROW(E.Line - E.Topline), COL(Columns) - 1, ROW(E.Line - E.Topline + 1) - 1 ); i = (E.Column - E.Topcolumn + len > Columns) ? Columns - E.Column + E.Topcolumn : len; bin: Move(Rp, COLT(E.Column - E.Topcolumn), ROWT(E.Line - E.Topline)); Text(Rp, str, i); E.Column += len; if (E.Column - E.Topcolumn >= Columns) text_sync(); } ok: if (ComLineMode == 0 && E.Wordwrap) do_reformat(0); } do_up() { if (E.Line) { TU; text_sync(); --E.Line; text_load(); if (E.Line < E.Topline) { if (Nsu == 0) { ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); --E.Topline; text_displayseg(0, 1); } } } else { Abortcommand = 1; } } do_down() { if (E.Line + 1 < E.Lines) { TU; text_sync(); ++E.Line; text_load(); if (E.Line - E.Topline >= Rows) { if (Nsu == 0) { ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); ++E.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; 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 && E.Topline >= E.Lines - Rows) return(0); text_sync(); TU; E.Line += n; E.Topline += n; if (E.Line >= E.Lines) E.Line = E.Lines - 1; if (E.Line < 0) E.Line = 0; if (E.Topline >= E.Lines) E.Topline = E.Lines - Rows - 1; if (E.Topline < 0) E.Topline = 0; text_load(); if (!text_sync()) text_redisplay(); break; case 's': pctg = atoi(av[1]); break; } } do_downadd() { u_char *ptr; if (E.Line + 1 == E.Lines) { E.Modified = 1; if (makeroom(32) && (ptr = MAllocate(1))) { E.List[E.Lines] = ptr; *ptr = 0; ++E.Lines; } else { nomemory(); } } do_down(); } do_left() { if (E.Column) { --E.Column; if (E.Column < E.Topcolumn) text_sync(); } else { Abortcommand = 1; } } do_right() { if (E.Column != 254) { if (Current[E.Column] == 0) { Current[E.Column] = ' '; Current[E.Column+1]= '\0'; ++Clen; } ++E.Column; if (E.Column - E.Topcolumn >= Columns) text_sync(); } else { Abortcommand = 1; } } do_tab() { register short n; for (n = E.Tabstop-(E.Column % E.Tabstop); n > 0; --n) do_right(); } do_backtab() { register short n; n = E.Column % E.Tabstop; if (!n) n = E.Tabstop; for (; n > 0; --n) do_left(); } do_return() { u_char buf[256]; if (ComLineMode) { strcpy(buf, Current); escapecomlinemode(); do_command(buf); } else { E.Column = 0; text_sync(); do_downadd(); } } do_bs() { if (E.Column) { bmov(Current + E.Column, Current + E.Column - 1, Clen - E.Column + 1); --E.Column; --Clen; if (E.Column < E.Topcolumn) { text_sync(); } else { ScrollRaster(Rp, Xsize, 0, COL(E.Column - E.Topcolumn), ROW(E.Line - E.Topline), COL(Columns)-1, ROW(E.Line - E.Topline + 1)-1 ); if (Clen >= E.Topcolumn + Columns) { Move(Rp, COLT(Columns-1), ROWT(E.Line - E.Topline)); Text(Rp, Current + E.Topcolumn + Columns - 1, 1); } } if (ComLineMode == 0 && E.Wordwrap) do_reformat(0); } else { Abortcommand = 1; } } /* * esc, escimm */ int Savetopline, Savecolumn, Savetopcolumn; do_esc() { 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 = E.Topline; Savecolumn = E.Column; Savetopcolumn = E.Topcolumn; E.Column = Clen; E.Topcolumn = 0; E.Topline = E.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() { if (ComLineMode) { ComLineMode = 0; returnoveride(0); E.Topline = Savetopline; E.Column = Savecolumn; E.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() { if (Current[E.Column]) { bmov(Current + E.Column + 1, Current + E.Column, Clen - E.Column); --Clen; ScrollRaster(Rp, Xsize, 0, COL(E.Column - E.Topcolumn), ROW(E.Line - E.Topline), COL(Columns)-1, ROW(E.Line - E.Topline + 1) - 1 ); if (Clen >= E.Topcolumn + Columns) { Move(Rp, COLT(Columns-1), ROWT(E.Line-E.Topline)); Text(Rp, Current+E.Topcolumn+Columns-1, 1); } if (ComLineMode == 0 && E.Wordwrap) do_reformat(0); } } do_top() { text_sync(); E.Line = 0; TU; text_load(); text_sync(); } do_bottom() { text_sync(); E.Line = E.Lines - 1; TU; text_load(); text_sync(); } do_firstcolumn() { if (E.Column) { E.Column = 0; text_sync(); } } do_firstnb() { for (E.Column = 0; Current[E.Column] == ' '; ++E.Column); if (Current[E.Column] == 0) E.Column = 0; text_sync(); } do_lastcolumn() { short i; text_sync(); i = (ComLineMode) ? Clen : strlen(E.List[E.Line]); if (i != E.Column) { E.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 u_char *ptr = av[1]; i = 0; n = -1; switch(*ptr) { case 'b': case 's': case 'B': case 'S': n = E.BSline; break; case 'e': case 'E': n = E.BEline; break; case '+': i = 1; case '-': n = E.Line; default: n += atoi(ptr+i); } if (n >= E.Lines) n = E.Lines - 1; if (n < 0) n = 0; text_sync(); E.Line = n; TU; text_load(); text_sync(); } do_screentop() { text_sync(); TU; E.Line = E.Topline; text_load(); text_sync(); } do_screenbottom() { text_sync(); TU; E.Line = E.Topline + Rows - 1; if (E.Line < 0 || E.Line >= E.Lines) E.Line = E.Lines - 1; text_load(); text_sync(); } static u_char Fstr[256]; static u_char 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 u_char *ptr; register int i, col; TU; text_sync(); if (!flen) { title("No find pattern"); Abortcommand = 1; return; } col = E.Column; if (col >= strlen(E.List[E.Line])) col = strlen(E.List[E.Line]); for (i = E.Line;;) { ptr = E.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 >= E.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(E.List[i]); } } MShowTitle = 1; title("Pattern Not Found"); Abortcommand = 1; return; found: E.Line = i; E.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(); } }