afb@j.cc.purdue.edu.UUCP (11/20/87)
This is the first part of the sources for Matt Dillon's editor, DME. See comp.binaries.amiga for documentation, which is not included here to save net.traffic. I was unable to compile this program due to lack of a needed support library, SUP32.LIB, which I wish Matt would send us. Matthew Bradburn afb@j.cc.purdue.edu bradburn@purccvm.bitnet # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # TODO # defs.h # globals.c # main.c # text1.c # This archive created: Thu Nov 19 16:55:32 1987 # By: Matthew Bradburn (Purdue University) cat << \SHAR_EOF > Makefile # Note: In terms of compiling, if you do not have my latest # support library you may have to do some hacking to get the # code to link. # # The precompiled symbol table, SYMBOLS.M, is *only* the AMIGA includes # .. */*.h (exec/*.h, etc....). When generating a precompiled symbol # table remember to use the +L compiler option. CFLAGS= +L +Ivd0:include/symbols.m OBJS= globals.o command.o keyboard.o main.o text1.o text2.o subs.o refs.o ASMS= globals.asm command.asm keyboard.asm main.asm text1.asm text2.asm subs.asm refs.asm SRCS= globals.c command.c keyboard.c main.c text1.c text2.c subs.c refs.c HDR= defs.h .c.o: cc $(CFLAGS) -o $@ $*.c .c.asm: cc $(CFLAGS) -A -o ram:$@ $*.c all: $(OBJS) ln +Q $(OBJS) -lsup32 -lc32 -O ram:dme asm: $(ASMS) arc: -delete ram:dme.arc arc a ram:dme dme.doc ram:dme dme.info README SAMPLE.EDRC srcarc: -delete ram:dmesrc.arc arc a ram:dmesrc Makefile TODO $(SRCS) $(HDR) clean: -delete $(OBJS) ram:dme SHAR_EOF cat << \SHAR_EOF > TODO ni = not implemented yet STATUS ITEM ni ascii-numeric variable support SEMI command line variable expansion. ni exception handling (abort if, repeat, keymap, etc..... trap vector?) ni kill/string buffer ni text markers ni character oriented blocks ni highlight blocks ni block operations across windows ni stackable search/replace strings ni cancel all user keymaps ni clipboard support ni anchored search as opposed to normal search ni keyboard repeat buffering too many repeats. (1) help! key ni provision to show mapping for a single key ni CD for each window ni menu add ni Scroll Gadgets in Formatted Save ni Case ignore for FIND, FIND-REPLACE NO slave the editor to a shell. (1) Implementable as a keymap and the REF command. fsave (formatted save) When it encounters one linefeed with the next character not whitespace, it writes a space. If the next character is whitespace it leaves it alone (write one linefeed). If the next character is a linefeed, write one linefeed then copy linefeeds up to the next non-linefeed. This will almost allow "word-processor" output... with columns! Very simple, very small, and it will save me from the horrors of PageSetter's editor. You may want to do funky things to the name like "fsaveas" or "fbsave" or whatever. I'll even add it if you don't have time. SHAR_EOF cat << \SHAR_EOF > defs.h /* * DEFS.H * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved * */ #include <exec/types.h> #include <exec/io.h> #include <devices/keymap.h> #include <devices/console.h> #include <exec/memory.h> #include <intuition/intuition.h> #include <typedefs.h> #include "xmisc.h" #define MAXTOGGLE 256 #define QMOVE (0x6B|0x80) #define COLT(n) (XTbase + (n) * Xsize) #define ROWT(n) (YTbase + (n) * Ysize) #define COL(n) (Xbase + (n) * Xsize) #define ROW(n) (Ybase + (n) * Ysize) typedef unsigned char ubyte; typedef struct WBStartup WBS; typedef struct DiskObject DISKOBJ; extern WBS *Wbs; extern DISKOBJ *Do; extern short Xsize, Ysize; extern short XTbase, YTbase; extern short Rows, Columns; extern short Xbase, Ybase; extern short Xpixs, Ypixs; extern ubyte *av[]; extern char Wdisable; typedef struct _ED { struct _ED *next, **prev; WIN *Win; long Topline, Topcolumn; long Line, Column; long Lines, Maxlines; ubyte **List; ubyte Name[64]; ubyte Wtitle[130]; char Modified; ubyte Tabstop; ubyte Margin; char Insertmode; char Wordwrap; char iconmode; /* window in icon mode */ short Winx, Winy, Winwidth, Winheight; short IWinx, IWiny; long BSline, BEline; /* block start and end lines */ short BSchar, BEchar; /* char start on BSline, end on BEline */ long dirlock; /* directory lock */ } ED; #ifndef NULL #define NULL 0 #endif #ifdef E #undef E #endif extern ED E, *Ep, *Base; extern char Overide; extern char Savetabs; extern char memoryfail, Nsu, Msgchk; extern ubyte CtlC; extern ubyte Current[256]; extern ubyte Space[32]; extern short Clen; extern char Abortcommand, MShowTitle; extern char Comlinemode; extern RP *Rp; extern WIN *Win; extern char *Partial; extern char *String; extern ubyte *allocl(), *allocb(); extern ubyte *AllocMem(), *strcpy(), *malloc(); extern char *keyspectomacro(); extern void search_operation(); SHAR_EOF cat << \SHAR_EOF > globals.c /* * GLOBALS.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" ED E, *Ep; /* Current Window */ ED *Base; /* Doubly linked list of Files */ char Nsu; /* Used in formatter to disable screen updates */ char Msgchk; /* Force message queue check for break */ ubyte CtlC; /* Keycode for 'c' */ char Savetabs; /* SaveTabs mode? */ char memoryfail; /* out of memory flag */ ubyte Current[256]; /* Current Line buffer and length */ ubyte Space[32] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 }; short Clen; char *Partial; /* Partial command line when executing ESCIMM */ char *String; /* String Capture variable */ char Comlinemode; char Abortcommand; SHAR_EOF cat << \SHAR_EOF > main.c /* * MAIN.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved. * */ #include "defs.h" #define IDCMPFLAGS CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE extern WIN *OpenWindow(); NW Nw = { 0, 1, 640, 199, -1, -1, IDCMPFLAGS, ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP, NULL, NULL, (ubyte *)" WAIT ", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN }; short Sharedrefs; short Oldtlen = 999; /* Old Title Length */ struct MsgPort *Sharedport; DISKOBJ *Do; WBS *Wbs; WIN *Win; RP *Rp; short Xsize, Ysize; /* font character sizes */ short Rows, Columns; /* character rows/cols available */ short Xbase, Ybase; /* offset pixel base for display */ short XTbase,YTbase; /* used for text display */ short Xpixs, Ypixs; /* actual # X/Y pixels available */ short Mx, My; ubyte *av[8]; char Quitflag; char Overide; char SizeOveride; char Wdisable = 1; /* Disable icon save */ char MShowTitle, MForceTitle; short Nwwidth, Nwheight, Nwtopedge, Nwleftedge, Nwtmpwidth, Nwtmpheight; int Enable_Abort; extern ED E, *Ep, *Base; extern char memoryfail; extern WIN *opensharedwindow(); extern IMESS *GetMsg(); static char *Ffile; main(mac, mav) char *mav[]; { register IMESS *im; register WIN *win; char nf, ni; /* # files on command line */ char notdone; char iawm = 0; char dontwait = 0; short i; short Code; init_command(); Nwwidth = Nw.Width; Nwheight = Nw.Height; Nwtopedge = Nw.TopEdge; Nwleftedge = Nw.LeftEdge; Enable_Abort= 0; String = (char *)malloc(1); *String = 0; if (!openlibs(INTUITION_LIB|GRAPHICS_LIB)) exiterr("cannot open intuition or graphics library"); if (mac == 0) { long oldlock; Wdisable = 0; Wbs = (WBS *)mav; if (!openlibs(ICON_LIB)) exiterr("unable to open icon library"); oldlock = CurrentDir(Wbs->sm_ArgList[0].wa_Lock); /* tool */ Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name); CurrentDir(oldlock); if (Do == NULL) exiterr("unable to get disk object"); mac = 99; } resethash(); if (Do) { ops(Do->do_ToolTypes, 1); nf = Wbs->sm_NumArgs - 1; E.dirlock = Wbs->sm_ArgList[0].wa_Lock; } else { nf = ops(mav+1, 0); } for (ni = 0, i = 1; i < mac; ++i) { register char *str; register DISKOBJ *dso; long oldlock; if (Wbs) { if (i > nf) break; str = Wbs->sm_ArgList[i].wa_Name; oldlock = CurrentDir(Wbs->sm_ArgList[i].wa_Lock); if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) { ops(dso->do_ToolTypes, 1); FreeDiskObject(dso); } E.dirlock = CurrentDir(oldlock); } else { str = mav[i]; if (*str == '-') continue; } do_newwindow(nf > 1, ni * 10); ++ni; av[0] = (ubyte *)"newfile"; av[1] = (ubyte *)str; do_edit(); MForceTitle = 1; window_title(); } if (nf == 0) /* no files to edit */ do_newwindow(nf > 1, ni * 10); mountrequest(0); av[0] = NULL; av[1] = (ubyte *)"s:.edrc"; do_source(); av[0] = NULL; av[1] = (ubyte *)((Ffile) ? Ffile : ".edrc"); do_source(); mountrequest(1); title("DME V1.28f \251Copyright 1987 Matthew Dillon, All Rights Reserved "); loop: if (!E.iconmode) text_cursor(1); for (notdone = 1; !Quitflag && notdone;) { char mmove = 0; short mqual; if (!E.iconmode) window_title(); if (dontwait) --dontwait; else WaitPort(Win->UserPort); /* * NOTE: due to operation of breakcheck(), the userport signal * may not be set even if there are messages pending. */ while (im = (IMESS *)GetMsg(Win->UserPort)) { Msgchk = 1; Abortcommand = 0; Code = im->Code; if (im->IDCMPWindow != Win) { Overide = 0; if (Comlinemode) escapecomlinemode(); text_sync(); MShowTitle = 0; if (!E.iconmode) window_title(); if (text_switch(im->IDCMPWindow) == 0) { ReplyMsg(im); continue; } if (!E.iconmode) { set_window_params(); window_title(); } } Mx = im->MouseX; My = im->MouseY; switch(im->Class) { case NEWSIZE: if (!E.iconmode) { if (Comlinemode) escapecomlinemode(); set_window_params(); if (!text_sync()) text_redisplay(); text_cursor(1); } break; case MOUSEBUTTONS: switch(Code) { case SELECTDOWN: case MENUDOWN: if (E.iconmode || iawm) { uniconify(); break; } ReportMouse(-1, Win); uniconify(); text_cursor(0); keyctl(NULL, im->Code|0x80, im->Qualifier); text_cursor(1); break; case SELECTUP: case MENUUP: ReportMouse(0, Win); break; } break; case RAWKEY: if ((im->Qualifier & 0x80) == 0) { if (E.iconmode) { uniconify(); break; } text_cursor(0); keyctl(im, im->Code, im->Qualifier); text_cursor(1); } break; case CLOSEWINDOW: if (Comlinemode) escapecomlinemode(); text_sync(); notdone = 0; break; case ACTIVEWINDOW: if (!E.iconmode) iawm = 1; break; case MOUSEMOVE: mmove = 1; mqual = im->Qualifier; break; } if (im) ReplyMsg(im); if (notdone == 0 || Quitflag) { dontwait = 2; goto boom; } } iawm = 0; if (mmove) { uniconify(); mmove = 0; text_cursor(0); keyctl(NULL, QMOVE, mqual); text_cursor(1); } closesharedwindow(NULL); } boom: if (E.Modified && !Overide) { uniconify(); Overide = 1; title("*** File has been modified ***"); Quitflag = 0; goto loop; } SetWindowTitles(Win, "", -1); text_uninit(); /* uninitialize text portion */ closesharedwindow(Win); if (Base) { Quitflag = 0; Win = E.Win; /* make arbitrary other window act. */ Rp = Win->RPort; if (!E.iconmode) set_window_params(); text_load(); MShowTitle = 0; goto loop; } closesharedwindow(NULL); if (Do) FreeDiskObject(Do); closelibs(-1); dealloc_hash(); } do_iconify() { if (!Comlinemode) iconify(); } do_tomouse() { text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize); } iconify() { if (!E.iconmode) { E.Winx = Win->LeftEdge; E.Winy = Win->TopEdge; E.Winwidth = Win->Width; E.Winheight = Win->Height; Nw.Height = 10; Nw.Width = 20 + 5*8 + strlen(E.Name)*8; Nw.LeftEdge= E.IWinx; Nw.TopEdge = E.IWiny; if (Nw.LeftEdge + Nw.Width > Win->WScreen->Width) Nw.LeftEdge = Win->WScreen->Width - Nw.Width; if (Nw.TopEdge + Nw.Height > Win->WScreen->Height) Nw.TopEdge = Win->WScreen->Height - Nw.Height; Nw.Title = Ep->Wtitle; Nw.Flags &= ~(WINDOWSIZING|WINDOWDEPTH|ACTIVATE); Nw.Flags |= BORDERLESS; sprintf(Ep->Wtitle, "%s %s ", E.Name, ((E.Modified) ? "(mod)":"")); closesharedwindow(Win); Win = E.Win = Ep->Win = opensharedwindow(&Nw); Nw.Flags |= WINDOWSIZING|WINDOWDEPTH|ACTIVATE; Nw.Flags &= ~BORDERLESS; Rp = Win->RPort; } E.iconmode = 1; } uniconify() { if (E.iconmode) { E.IWinx = Win->LeftEdge; E.IWiny = Win->TopEdge; closesharedwindow(Win); Nw.LeftEdge = E.Winx; Nw.TopEdge = E.Winy; Nw.Width = E.Winwidth; Nw.Height = E.Winheight; Nw.Title = Ep->Wtitle; Win = E.Win = Ep->Win = opensharedwindow(&Nw); Rp = Win->RPort; set_window_params(); if (!text_sync()) text_redisplay(); text_cursor(1); MShowTitle = 0; window_title(); } E.iconmode = 0; } do_newwindow(makesmall, deltaheight) { WIN *win; int msadj = makesmall; if (SizeOveride) msadj = 0; if (Ep) text_sync(); Nw.Title = (ubyte *)" OK "; Nw.Width = (Nwtmpwidth) ? Nwtmpwidth : Nwwidth; Nw.Height= (Nwtmpheight)? Nwtmpheight: Nwheight; Nwtmpwidth = Nwtmpheight = 0; Nw.LeftEdge = Nwleftedge; Nw.TopEdge = Nwtopedge; if (msadj > 0) { /* deltaheight must be valid */ Nw.TopEdge = deltaheight + 16; Nw.LeftEdge= 10*8; Nw.Flags &= ~ACTIVATE; Nw.Width = 40*8; Nw.Height= 10*8; if (Nw.TopEdge + Nw.Height > 200) Nw.TopEdge = deltaheight = 200 - Nw.Height; } win = opensharedwindow(&Nw); Nw.Flags |= ACTIVATE; if (win) { Win = win; /* set new window */ Rp = Win->RPort; set_window_params(); text_init(); /* initialize */ text_load(); if (makesmall != -1) /* if deltaheight valid */ E.IWiny = deltaheight + 16; } } WIN * TOpenWindow(nw) NW *nw; { WIN *win; while ((win = OpenWindow(nw)) == NULL) { if (nw->Width < 50 || nw->Height < 50) break; nw->Width -= 10; nw->Height-= 10; } return(win); } WIN * opensharedwindow(nw) NW *nw; { WIN *win; if (Sharedport) nw->IDCMPFlags = NULL; else nw->IDCMPFlags = IDCMPFLAGS; win = TOpenWindow(nw); if (win) { if (Sharedport) { win->UserPort = Sharedport; ModifyIDCMP(win, IDCMPFLAGS); } else { Sharedport = win->UserPort; } ++Sharedrefs; } return(win); } closesharedwindow(win) WIN *win; { static WIN *wunlink; register IMESS *im; char notoktoclosenow = 0; if (win) { SetWindowTitles(win, "", -1); Forbid(); win->UserPort = NULL; ModifyIDCMP(win, GADGETUP); /* NEVER occurs */ notoktoclosenow = 1; Permit(); if (notoktoclosenow) { win->UserData = (char *)wunlink; wunlink = win; } else { CloseWindow(win); } --Sharedrefs; } else { if (Sharedrefs == 0 && Sharedport) { DeletePort(Sharedport); Sharedport = NULL; } for (win = wunlink; win; win = wunlink) { wunlink = (WIN *)win->UserData; CloseWindow(win); } wunlink = NULL; } } getyn(text) char *text; { int result; ITEXT *body, *pos, *neg; body = (ITEXT *)AllocMem(sizeof(ITEXT), 0); pos = (ITEXT *)AllocMem(sizeof(ITEXT), 0); neg = (ITEXT *)AllocMem(sizeof(ITEXT), 0); bzero(body, sizeof(ITEXT)); bzero(pos , sizeof(ITEXT)); bzero(neg , sizeof(ITEXT)); body->BackPen = pos->BackPen = neg->BackPen = 1; body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE; body->LeftEdge = 10; body->TopEdge = 12; body->IText = (ubyte *)text; pos->LeftEdge = AUTOLEFTEDGE; pos->TopEdge = AUTOTOPEDGE; pos->IText = (ubyte *)"OK"; neg->LeftEdge = AUTOLEFTEDGE; neg->TopEdge = AUTOTOPEDGE; neg->IText = (ubyte *)"CANCEL"; result = AutoRequest(Win,body,pos,neg,0,0,320,58); FreeMem(body, sizeof(ITEXT)); FreeMem(pos , sizeof(ITEXT)); FreeMem(neg , sizeof(ITEXT)); return(result); } title(buf) char *buf; { SetWindowTitles(Win, buf, -1); Oldtlen = 999; MShowTitle = 3; } window_title() { register int len, maxlen; if (memoryfail) { title(" -- NO MEMORY -- "); memoryfail = 0; text_redisplay(); } if (MForceTitle) { MShowTitle = 0; MForceTitle = 0; } if (MShowTitle) { --MShowTitle; return(0); } { register char *mod; mod = (E.Modified) ? " (modified)" : " "; sprintf(Ep->Wtitle, "%3ld/%-3ld %3ld %s%s ", text_lineno(), text_lines(), text_colno()+1, text_name(), mod); if (!text_imode()) strcat(Ep->Wtitle, "Ovr "); len = strlen(Ep->Wtitle); if (len < Columns && Columns < 128) { bset(Ep->Wtitle+len, Columns - len + 1, ' '); Ep->Wtitle[Columns + 1] = 0; } Win->Title = Ep->Wtitle; SetAPen(Rp, 0); SetBPen(Rp, 1); Move(Rp, 30, Win->RPort->Font->tf_Baseline+1); maxlen = (Win->Width-96)/Win->RPort->Font->tf_XSize; if (maxlen < 0) maxlen = 0; if (len > maxlen) len = Oldtlen = maxlen; if (Oldtlen > maxlen) Oldtlen = maxlen; Text(Rp, Ep->Wtitle, len); /* No flash */ while (Oldtlen - len >= (int)sizeof(Space)) { Text(Rp, Space, sizeof(Space)); Oldtlen -= sizeof(Space); } if (Oldtlen - len > 0) Text(Rp, Space, Oldtlen - len); Oldtlen = len; /* Oldtlen might have been < */ SetAPen(Rp, 1); SetBPen(Rp, 0); } } set_window_params() { Xsize = Rp->Font->tf_XSize; Ysize = Rp->Font->tf_YSize; Xbase = Win->BorderLeft; Ybase = Win->BorderTop; Xpixs = Win->Width - Win->BorderRight - Xbase; Ypixs = Win->Height- Win->BorderBottom- Ybase; Columns = Xpixs / Xsize; Rows = Ypixs / Ysize; XTbase = Xbase; YTbase = Ybase + Rp->Font->tf_Baseline; } exiterr(str) char *str; { if (Output()) { Write(Output(),str,strlen(str)); Write(Output(),"\n",1); } exit(1); } /* * Check break by scanning pending messages in the I stream for a ^C. * Msgchk forces a check, else the check is only made if the signal is * set in the I stream (the signal is reset). */ breakcheck() { IMESS *im; register struct List *list = &Win->UserPort->mp_MsgList; if (Msgchk || (SetSignal(0,0) & (1<<Win->UserPort->mp_SigBit))) { Msgchk = 0; SetSignal(0,1<<Win->UserPort->mp_SigBit); im = (IMESS *)list->lh_Head; Forbid(); for (; im != &list->lh_Tail; im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ) { if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 && im->Code == CtlC) { Permit(); SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C); return(1); } } Permit(); } return(0); } breakreset() { SetSignal(0, SIGBREAKF_CTRL_C); } /* * leftedge n * topedge n * width n * height n * tmpwidth n * tmpheight n */ void do_windowparm() { int val = atoi(av[1]); if (av[0][0] == 't' && av[0][1] == 'm') { /* tmpwidth/tmpheight */ if (av[0][3] == 'w') Nwtmpwidth = val; if (av[0][3] == 'h') Nwtmpheight= val; return; } switch(av[0][0]) { case 'l': Nwleftedge = val; break; case 't': Nwtopedge = val; break; case 'w': Nwwidth = val; break; case 'h': Nwheight = val; break; } } /* * resize cols rows */ do_resize() { int cols = atoi(av[1]); int rows = atoi(av[2]); short width = (cols*Win->RPort->Font->tf_XSize) + Win->BorderLeft + Win->BorderRight; short height= (rows*Win->RPort->Font->tf_YSize) + Win->BorderTop + Win->BorderBottom; if (width < 16 || height < 16 || width > Win->WScreen->Width - Win->LeftEdge || height > Win->WScreen->Height - Win->TopEdge) { title ("window too big (try moving to upper left corner and retrying)"); return(0); } SizeWindow(Win, width - Win->Width, height - Win->Height); Delay(50*2); /* wait 2 seconds */ } ops(av, iswb) register char *av[]; { register short nonops; register short i; register long val; register char *str; for (i = nonops = 0; str = av[i]; ++i) { if (iswb) { if (strncmp(str, "ARG", 3) == 0) { while (*str && *str != '-') ++str; } } if (*str == '-') { val = atoi(str+2); switch(str[1]) { case 'f': Ffile = str+2; break; case 'b': SizeOveride = 1; break; case 't': Nwtopedge = val; break; case 'l': Nwleftedge= val; break; case 'w': SizeOveride = 1; Nwwidth = val; break; case 'h': SizeOveride = 1; Nwheight = val; break; } } else { ++nonops; } } return(nonops); } SHAR_EOF cat << \SHAR_EOF > text1.c /* * TEXT1.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" #define nomemory() {memoryfail = 1;} char RecallBuf[256]; text_init() { register ED *e; long dirlock; text_switch(NULL); dirlock = E.dirlock; e = (ED *)allocb(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 = (ubyte **)allocl(E.Maxlines); E.List[0] = allocb(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, "unnamed"); Ep = e; text_cursor(1); return(1); } text_switch(win) WIN *win; { register ED *e; register ED *next, **prev; if (win) text_sync(); if (Ep) { 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; ubyte *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 = allocb(Clen+1)) { E.Modified = 1; Overide = 0; 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; Overide = 0; } } 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_colno() { return(E.Column); } text_lineno() { return(E.Line+1); } text_lines() { return(E.Lines); } text_cols() { return((int)Clen); } text_imode() { return(E.Insertmode); } text_tabsize() { return((int)E.Tabstop); } ubyte * 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) { 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 ubyte *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) ubyte *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) { 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_scrolldown() { if (E.Topline + Rows < E.Lines) { if (Nsu == 0) { text_sync(); ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); ++E.Topline; ++E.Line; text_load(); text_displayseg(Rows-1, 1); } } else { Abortcommand = 1; } } do_scrollup() { if (E.Topline) { if (Nsu == 0) { text_sync(); ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); --E.Topline; --E.Line; text_load(); text_displayseg(0, 1); } } else { Abortcommand = 1; } } do_down() { if (E.Line + 1 < E.Lines) { 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(); 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() { ubyte *ptr; if (E.Line + 1 == E.Lines) { E.Modified = 1; if (makeroom(32) && (ptr = allocb(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() { 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 { 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_recall() { av[0] = (ubyte *)"escimm"; av[1] = (ubyte *)RecallBuf; do_esc(); } 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 (Partial) { free(Partial); Partial = NULL; } if (Comlinemode) { strcpy(RecallBuf, Current); 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; text_load(); text_sync(); } do_bottom() { text_sync(); E.Line = E.Lines - 1; 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 ubyte *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; text_load(); text_sync(); } do_screentop() { text_sync(); E.Line = E.Topline; text_load(); text_sync(); } do_screenbottom() { text_sync(); E.Line = E.Topline + Rows - 1; if (E.Line < 0 || E.Line >= E.Lines) E.Line = E.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; 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]); } } 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(); } } SHAR_EOF # End of shell archive exit 0