Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!lll-crg!lll-lcc!qantel!hplabs!tektronix!orca!pogo!jutz From: jutz@pogo.UUCP (Curt Jutzi) Newsgroups: net.sources Subject: MicroEmacs (6 of 7) Message-ID: <2415@pogo.UUCP> Date: Thu, 20-Mar-86 12:16:54 EST Article-I.D.: pogo.2415 Posted: Thu Mar 20 12:16:54 1986 Date-Received: Sat, 22-Mar-86 23:27:30 EST Distribution: net Organization: Tektronix, Beaverton OR Lines: 1004 *** REPLACE THIS LINE WITH YOUR MESSAGE *** CTRL|'G', ctrlg, CTRL|'H', backdel, CTRL|'I', tab, CTRL|'J', indent, CTRL|'K', kill, CTRL|'L', refresh, CTRL|'M', newline, CTRL|'N', forwline, CTRL|'O', openline, CTRL|'P', backline, CTRL|'Q', quote, /* Often unreachable */ CTRL|'R', backsearch, CTRL|'S', forwsearch, /* Often unreachable */ CTRL|'T', twiddle, CTRL|'V', forwpage, CTRL|'W', killregion, CTRL|'Y', yank, CTRL|'Z', quickexit, /* quick save and exit */ CTLX|CTRL|'B', listbuffers, CTLX|CTRL|'C', quit, /* Hard quit. */ CTLX|CTRL|'F', filename, CTLX|CTRL|'L', lowerregion, CTLX|CTRL|'O', deblank, CTLX|CTRL|'N', mvdnwind, CTLX|CTRL|'P', mvupwind, CTLX|CTRL|'R', fileread, CTLX|CTRL|'S', filesave, /* Often unreachable */ CTLX|CTRL|'U', upperregion, CTLX|CTRL|'V', filevisit, CTLX|CTRL|'W', filewrite, CTLX|CTRL|'X', swapmark, CTLX|CTRL|'Z', shrinkwind, CTLX|'!', spawn, /* Run 1 command. */ CTLX|'=', showcpos, CTLX|'(', ctlxlp, CTLX|')', ctlxrp, CTLX|'1', onlywind, CTLX|'2', splitwind, CTLX|'B', usebuffer, CTLX|'E', ctlxe, CTLX|'F', setfillcol, CTLX|'K', killbuffer, CTLX|'N', nextwind, CTLX|'P', prevwind, CTLX|'Z', enlargewind, META|CTRL|'H', delbword, META|'!', reposition, META|'.', setmark, META|'>', gotoeob, META|'<', gotobob, META|'B', backword, META|'C', capword, META|'D', delfword, META|'F', forwword, META|'L', lowerword, META|'U', upperword, META|'V', backpage, META|'W', copyregion, META|'X', metacmds, META|0x7F, delbword, 0x7F, backdel }; #define NKEYTAB (sizeof(keytab)/sizeof(keytab[0])) #if RAINBOW #include "rainbow.h" /* * Mapping table from the LK201 function keys to the internal EMACS character. */ short lk_map[][2] = { Up_Key, CTRL+'P', Down_Key, CTRL+'N', Left_Key, CTRL+'B', Right_Key, CTRL+'F', Shift+Left_Key, META+'B', Shift+Right_Key, META+'F', Control+Left_Key, CTRL+'A', Control+Right_Key, CTRL+'E', Prev_Scr_Key, META+'V', Next_Scr_Key, CTRL+'V', Shift+Up_Key, META+'<', Shift+Down_Key, META+'>', Cancel_Key, CTRL+'G', Find_Key, CTRL+'S', Shift+Find_Key, CTRL+'R', Insert_Key, CTRL+'Y', Options_Key, CTRL+'D', Shift+Options_Key, META+'D', Remove_Key, CTRL+'W', Shift+Remove_Key, META+'W', Select_Key, CTRL+'@', Shift+Select_Key, CTLX+CTRL+'X', Interrupt_Key, CTRL+'U', Keypad_PF2, META+'L', Keypad_PF3, META+'C', Keypad_PF4, META+'U', Shift+Keypad_PF2, CTLX+CTRL+'L', Shift+Keypad_PF4, CTLX+CTRL+'U', Keypad_1, CTLX+'1', Keypad_2, CTLX+'2', Do_Key, CTLX+'E', Keypad_4, CTLX+CTRL+'B', Keypad_5, CTLX+'B', Keypad_6, CTLX+'K', Resume_Key, META+'!', Control+Next_Scr_Key, CTLX+'N', Control+Prev_Scr_Key, CTLX+'P', Control+Up_Key, CTLX+CTRL+'P', Control+Down_Key, CTLX+CTRL+'N', Help_Key, CTLX+'=', Shift+Do_Key, CTLX+'(', Control+Do_Key, CTLX+')', Keypad_0, CTLX+'Z', Shift+Keypad_0, CTLX+CTRL+'Z', Main_Scr_Key, CTRL+'C', Keypad_Enter, CTLX+'!', Exit_Key, CTLX+CTRL+'C', Shift+Exit_Key, CTRL+'Z' }; #define lk_map_size (sizeof(lk_map)/2) #endif main(argc, argv) char *argv[]; { register int c; register int f; register int n; register int mflag; char bname[NBUFN]; strcpy(bname, "main"); /* Work out the name of */ if (argc > 1) /* the default buffer. */ makename(bname, argv[1]); edinit(bname); /* Buffers, windows. */ vtinit(); /* Displays. */ if (argc > 1) { update(); /* You have to update */ readin(argv[1]); /* in case "[New file]" */ } lastflag = 0; /* Fake last flags. */ loop: update(); /* Fix up the screen */ c = getkey(); if (mpresf != FALSE) { mlerase(); update(); if (c == ' ') /* ITS EMACS does this */ goto loop; } f = FALSE; n = 1; if (c == (CTRL|'U')) { /* ^U, start argument */ f = TRUE; n = 4; /* with argument of 4 */ mflag = 0; /* that can be discarded. */ mlwrite("Arg: 4"); while ((c=getkey()) >='0' && c<='9' || c==(CTRL|'U') || c=='-'){ if (c == (CTRL|'U')) n = n*4; /* * If dash, and start of argument string, set arg. * to -1. Otherwise, insert it. */ else if (c == '-') { if (mflag) break; n = 0; mflag = -1; } /* * If first digit entered, replace previous argument * with digit and set sign. Otherwise, append to arg. */ else { if (!mflag) { n = 0; mflag = 1; } n = 10*n + c - '0'; } mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1)); } /* * Make arguments preceded by a minus sign negative and change * the special argument "^U -" to an effective "^U -1". */ if (mflag == -1) { if (n == 0) n++; n = -n; } } if (c == (CTRL|'X')){ /* ^X is a prefix */ c = CTLX | getctl(); } if (kbdmip != NULL) { /* Save macro strokes. */ if (c!=(CTLX|')') && kbdmip>&kbdm[NKBDM-6]) { ctrlg(FALSE, 0); goto loop; } if (f != FALSE) { *kbdmip++ = (CTRL|'U'); *kbdmip++ = n; } *kbdmip++ = c; } execute(c, f, n); /* Do it. */ goto loop; } /* * Initialize all of the buffers and windows. The buffer name is passed down * as an argument, because the main routine may have been told to read in a * file by default, and we want the buffer name to be right. */ edinit(bname) char bname[]; { register BUFFER *bp; register WINDOW *wp; bp = bfind(bname, TRUE, 0); /* First buffer */ blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */ wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */ if (bp==NULL || wp==NULL || blistp==NULL) exit(1); curbp = bp; /* Make this current */ wheadp = wp; curwp = wp; wp->w_wndp = NULL; /* Initialize window */ wp->w_bufp = bp; bp->b_nwnd = 1; /* Displayed. */ wp->w_linep = bp->b_linep; wp->w_dotp = bp->b_linep; wp->w_doto = 0; wp->w_markp = NULL; wp->w_marko = 0; wp->w_toprow = 0; wp->w_ntrows = term.t_nrow-1; /* "-1" for mode line. */ wp->w_force = 0; wp->w_flag = WFMODE|WFHARD; /* Full. */ } /* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ execute(c, f, n) { register KEYTAB *ktp; register int status; ktp = &keytab[0]; /* Look in key table. */ while (ktp < &keytab[NKEYTAB]) { if (ktp->k_code == c) { thisflag = 0; status = (*ktp->k_fp)(f, n); lastflag = thisflag; return (status); } ++ktp; } /* * If a space was typed, fill column is defined, the argument is non- * negative, and we are now past fill column, perform word wrap. */ if (c == ' ' && fillcol > 0 && n>=0 && getccol(FALSE) > fillcol) wrapword(); if ((c>=0x20 && c<=0x7E) /* Self inserting. */ || (c>=0xA0 && c<=0xFE)) { if (n <= 0) { /* Fenceposts. */ lastflag = 0; return (n<0 ? FALSE : TRUE); } thisflag = 0; /* For the future. */ status = linsert(n, c); lastflag = thisflag; return (status); } lastflag = 0; /* Fake last flags. */ return (FALSE); } /* * Read in a key. * Do the standard keyboard preprocessing. Convert the keys to the internal * character set. */ getkey() { register int c; c = (*term.t_getchar)(); #if RAINBOW if (c & Function_Key) { int i; for (i = 0; i < lk_map_size; i++) if (c == lk_map[i][0]) return lk_map[i][1]; } else if (c == Shift + 015) return CTRL | 'J'; else if (c == Shift + 0x7F) return META | 0x7F; #endif if (c == METACH) { /* Apply M- prefix */ c = getctl(); return (META | c); } if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ c = CTRL | (c+'@'); return (c); } /* * Get a key. * Apply control modifications to the read key. */ getctl() { register int c; c = (*term.t_getchar)(); if (c>='a' && c<='z') /* Force to upper */ c -= 0x20; if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ c = CTRL | (c+'@'); return (c); } /* * Fancy quit command, as implemented by Norm. If the current buffer has * changed do a write current buffer and exit emacs, otherwise simply exit. */ quickexit(f, n) { if ((curbp->b_flag&BFCHG) != 0 /* Changed. */ && (curbp->b_flag&BFTEMP) == 0) /* Real. */ filesave(f, n); quit(f, n); /* conditionally quit */ } /* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ quit(f, n) { register int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ || (s=mlyesno("Quit")) == TRUE) { /* User says it's OK. */ vttidy(); exit(GOOD); } return (s); } /* * Begin a keyboard macro. * Error if not at the top level in keyboard processing. Set up variables and * return. */ ctlxlp(f, n) { if (kbdmip!=NULL || kbdmop!=NULL) { mlwrite("Not now"); return (FALSE); } mlwrite("[Start macro]"); kbdmip = &kbdm[0]; return (TRUE); } /* * End keyboard macro. Check for the same limit conditions as the above * routine. Set up the variables and return to the caller. */ ctlxrp(f, n) { if (kbdmip == NULL) { mlwrite("Not now"); return (FALSE); } mlwrite("[End macro]"); kbdmip = NULL; return (TRUE); } /* * Execute a macro. * The command argument is the number of times to loop. Quit as soon as a * command gets an error. Return TRUE if all ok, else FALSE. */ ctlxe(f, n) { register int c; register int af; register int an; register int s; if (kbdmip!=NULL || kbdmop!=NULL) { mlwrite("Not now"); return (FALSE); } if (n <= 0) return (TRUE); do { kbdmop = &kbdm[0]; do { af = FALSE; an = 1; if ((c = *kbdmop++) == (CTRL|'U')) { af = TRUE; an = *kbdmop++; c = *kbdmop++; } s = TRUE; } while (c!=(CTLX|')') && (s=execute(c, af, an))==TRUE); kbdmop = NULL; } while (s==TRUE && --n); return (s); } /* * Abort. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Sometimes called as a routine, to do general aborting of stuff. */ ctrlg(f, n) { (*term.t_beep)(); if (kbdmip != NULL) { kbdm[0] = (CTLX|')'); kbdmip = NULL; } return (ABORT); } /* * * META.C MODULE * */ #include #include "ed.h" #define NMETA_CMDS 52 int replace_string(); /* replace string global */ int query_replace(); /* query replace */ extern BUFFER *bfind(); /* buffer find */ extern int forwsearch(); /* forward search */ extern int backsearch(); /* backward search */ extern int ctlxlp(); /* Begin macro */ extern int ctlxrp(); /* End macro */ extern int ctlxe(); /* Execute macro */ extern int fileread(); /* Get a file, read only */ extern int filevisit(); /* Get a file, read write */ extern int filewrite(); /* Write a file */ extern int filesave(); /* Save current file */ extern int quit(); /* Quit */ extern int gotobol(); /* Move to start of line */ extern int forwchar(); /* Move forward by characters */ extern int gotoeol(); /* Move to end of line */ extern int backchar(); /* Move backward by characters */ extern int forwline(); /* Move forward by lines */ extern int backline(); /* Move backward by lines */ extern int forwpage(); /* Move forward by pages */ extern int backpage(); /* Move backward by pages */ extern int gotobob(); /* Move to start of buffer */ extern int gotoeob(); /* Move to end of buffer */ extern int setmark(); /* Set mark */ extern int swapmark(); /* Swap "." and mark */ extern int nextwind(); /* Move to the next window */ extern int prevwind(); /* Move to the previous window */ extern int onlywind(); /* Make current window only one */ extern int splitwind(); /* Split current window */ extern int mvdnwind(); /* Move window down */ extern int mvupwind(); /* Move window up */ extern int enlargewind(); /* Enlarge display window. */ extern int shrinkwind(); /* Shrink window. */ extern int listbuffers(); /* Display list of buffers */ extern int usebuffer(); /* Switch a window to a buffer */ extern int killbuffer(); /* Make a buffer go away. */ extern int reposition(); /* Reposition window */ extern int refresh(); /* Refresh the screen */ extern int deblank(); /* Delete blank lines */ extern int quote(); /* Insert literal */ extern int backword(); /* Backup by words */ extern int forwword(); /* Advance by words */ extern int forwdel(); /* Forward delete */ extern int backdel(); /* Backward delete */ extern int kill(); /* Kill forward */ extern int yank(); /* Yank back from killbuffer. */ extern int upperword(); /* Upper case word. */ extern int lowerword(); /* Lower case word. */ extern int upperregion(); /* Upper case region. */ extern int lowerregion(); /* Lower case region. */ extern int capword(); /* Initial capitalize word. */ extern int delfword(); /* Delete forward word. */ extern int delbword(); /* Delete backward word. */ extern int killregion(); /* Kill region. */ extern int copyregion(); /* Copy region to kill buffer. */ struct Meta_Disc { char *meta_str; int (*meta_fctn)(); } Meta_Commands[NMETA_CMDS] = { { "replace-string",replace_string }, { "query-replace",query_replace }, { "forward-search",forwsearch }, { "backward-search",backsearch }, { "begin-macro",ctlxlp }, { "end-macro",ctlxrp }, { "execute-macro",ctlxe }, { "read-file",fileread }, { "visit-file",filevisit }, { "write-file",filewrite }, { "save-file",filesave }, { "begin-of-line",gotobol }, { "end-of-line",gotoeol }, { "top-of-buffer",gotobob }, { "bottom-of-buffer",gotoeob }, { "set-mark",setmark }, { "swap-mark",swapmark }, { "next-window",nextwind }, { "previous-window",prevwind }, { "only-window",onlywind }, { "split-window",splitwind }, { "move-window-down",mvdnwind }, { "move-window-up",mvupwind }, { "enlarge-window",enlargewind }, { "shrink-window",shrinkwind }, { "list-buffers",listbuffers }, { "use-buffer",usebuffer }, { "kill-buffer",killbuffer }, { "reposition-window",reposition }, { "refresh-screen",refresh }, { "delete-blank-lines",deblank }, { "insert-literial",quote }, { "backward-word",backword }, { "forward-word",forwword }, { "kill-to-end-of-line",kill }, { "yank-from-killbuffer",yank }, { "case-word-upper",upperword }, { "case-word-lower",lowerword }, { "case-region-upper",upperregion }, { "case-region-lower",lowerregion }, { "case-word-capitalize",capword }, { "delete-next-word",delfword }, { "delete-previous-word",delbword }, { "kill-region",killregion }, { "copy-region",copyregion }, { "quit",quit }, { "backward-character",backchar }, { "forward-character",forwchar }, { "forward-line",forwline }, { "backward-line",backline }, { "forward-page",forwpage }, { "backward-page",backpage } }; /* test routine */ metacmds() { register int s; char buff[64]; s = mlreply("Meta-X: ",buff,sizeof(buff)); if (s == ABORT) return(ABORT); if ((s = findpos(buff)) < 0) { mlwrite("Meta-X command does not exist"); createhelpbuffer(); return(ABORT); } else { (*(Meta_Commands[s].meta_fctn))(NULL,1); } } /* Find Position() * * This procedure matches the string typed in at the command line * with one of the functions in the META-X list. If none is found * then it returns with a -1, else it returns with the index into * the Meta_Commands (list). */ findpos(buff) char *buff; { register int i; for (i=0;iw_dotp; cbo = curwp->w_doto; while (clp != curbp->b_linep) { if (cbo == llength(clp)) { clp = lforw(clp); cbo = 0; c = '\n'; } else c = lgetc(clp, cbo++); if (eq(c, old_str[0]) != FALSE) { tlp = clp; tbo = cbo; pp = &old_str[1]; while (*pp != 0) { if (tlp == curbp->b_linep) goto fail; if (tbo == llength(tlp)) { tlp = lforw(tlp); tbo = 0; c = '\n'; } else c = lgetc(tlp, tbo++); if (eq(c, *pp++) == FALSE) goto fail; } curwp->w_dotp = tlp; curwp->w_doto = tbo; curwp->w_flag |= WFMOVE; repl_cnt++; replace_occ(strlen(old_str),new_str); } fail:; } mlwrite(" %d Strings Replaced ",repl_cnt); return (FALSE); } /* Query Replace() * * This routine reads in an old and new string and does a query * replacement of all those occurances. Most of this routine is * a copy of the Search command ('forwardsearch'); */ query_replace() { register LINE *clp; register int cbo; register LINE *tlp; register int tbo; register int c; register int ch; register char *pp; register int s; register int repl_cnt; register char old_str[64]; register char new_str[64]; repl_cnt = 0; s = mlreply("Old String: ",old_str,sizeof(old_str)); if ((s == ABORT) || (s != TRUE)) return (s); if ((s = mlreply("New String: ",new_str,sizeof(new_str))) == ABORT) return (s); mlwrite(",n,N : ,y,Y : ^G"); clp = curwp->w_dotp; cbo = curwp->w_doto; while (clp != curbp->b_linep) { if (cbo == llength(clp)) { clp = lforw(clp); cbo = 0; c = '\n'; } /* if */ else c = lgetc(clp, cbo++); if (eq(c, old_str[0]) != FALSE) { tlp = clp; tbo = cbo; pp = &old_str[1]; while (*pp != 0) { if (tlp == curbp->b_linep) goto fail; if (tbo == llength(tlp)) { tlp = lforw(tlp); tbo = 0; c = '\n'; } /* if */ else c = lgetc(tlp, tbo++); if (eq(c, *pp++) == FALSE) goto fail; } /* while */ curwp->w_dotp = tlp; curwp->w_doto = tbo; curwp->w_flag |= WFMOVE; update(); tryagain:; ch = (*term.t_getchar)(); switch (ch) { case 0x07 : { ctrlg(FALSE, 0); mlwrite("Aborted"); (*term.t_flush)(); return(0); goto fail; } break; case 0x020 : case 0x079 : case 0x059 : { repl_cnt++; replace_occ(strlen(old_str),new_str); } break; case 0x01b : case 0x06e : case 0x04E : { } break; default : { ctrlg(FALSE, 0); (*term.t_flush)(); mlwrite(" TRY AGAIN! ,n,N : ,y,Y : ^G"); update(); goto tryagain; } } /* switch */ } /* if */ fail:; } /* while */ mlwrite(" %d Strings Replaced ",repl_cnt); return (FALSE); } /* * REPLACE_OCCURANCE * * This routine is called by the Replace String and the Query Replace * routines. * This routine takes the current cursor location, deletes the old * string and replaces it with the new string */ replace_occ(old_length,new_str) int old_length; char *new_str; { register int i; register int len; backdel(TRUE,old_length); len = strlen(new_str); for (i=0;i #include "ed.h" #if AMIGA #define NEW 1006 #define LEN 1 static long terminal; #endif #if VMS #include #include #include #include #include #define NIBUF 128 /* Input buffer size */ #define NOBUF 1024 /* MM says bug buffers win! */ #define EFN 0 /* Event flag */ char obuf[NOBUF]; /* Output buffer */ int nobuf; /* # of bytes in above */ char ibuf[NIBUF]; /* Input buffer */ int nibuf; /* # of bytes in above */ int ibufi; /* Read index */ int oldmode[2]; /* Old TTY mode bits */ int newmode[2]; /* New TTY mode bits */ short iochan; /* TTY I/O channel */ #endif #if CPM #include #endif #if MSDOS #undef LATTICE #include #endif #if RAINBOW #include "rainbow.h" #endif #if V7 #include /* for stty/gtty functions */ struct sgttyb ostate; /* saved tty state */ struct sgttyb nstate; /* values for editor mode */ #endif /* * This function is called once to set up the terminal device streams. * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns * a channel to it and sets it raw. On CPM it is a no-op. */ ttopen() { #if AMIGA terminal = Open("RAW:1/1/639/199/MicroEmacs", NEW); #endif #if VMS struct dsc$descriptor idsc; struct dsc$descriptor odsc; char oname[40]; int iosb[2]; int status; odsc.dsc$a_pointer = "SYS$INPUT"; odsc.dsc$w_length = strlen(odsc.dsc$a_pointer); odsc.dsc$b_dtype = DSC$K_DTYPE_T; odsc.dsc$b_class = DSC$K_CLASS_S; idsc.dsc$b_dtype = DSC$K_DTYPE_T; idsc.dsc$b_class = DSC$K_CLASS_S; do { idsc.dsc$a_pointer = odsc.dsc$a_pointer; idsc.dsc$w_length = odsc.dsc$w_length; odsc.dsc$a_pointer = &oname[0]; odsc.dsc$w_length = sizeof(oname); status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc); if (status!=SS$_NORMAL && status!=SS$_NOTRAN) exit(status); if (oname[0] == 0x1B) { odsc.dsc$a_pointer += 4; odsc.dsc$w_length -= 4; } } while (status == SS$_NORMAL); status = SYS$ASSIGN(&odsc, &iochan, 0, 0); if (status != SS$_NORMAL) exit(status); status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0, oldmode, sizeof(oldmode), 0, 0, 0, 0); if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status); newmode[0] = oldmode[0]; newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO; status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, newmode, sizeof(newmode), 0, 0, 0, 0);