jimomura@lsuc.UUCP (Jim Omura) (05/04/86)
========== os.9/public.domain #101, from jimomura, 2144 chars, Sun Mar 23 10:57:26 1986 ---------- TITLE: 'microEMACS' part 32 'uevt52.c' /* * The routines in this file * provide support for VT52 style terminals * over a serial line. The serial I/O services are * provided by routines in "termio.c". It compiles * into nothing if not a VT52 style device. The * bell on the VT52 is terrible, so the "beep" * routine is conditionalized on defining BEL. */ #include <stdio.h> #include "ueed.h" #ifdef VT52 #define NROW 24 /* Screen size. */ #define NCOL 80 /* Edit if you want to. */ #define BIAS 0x20 /* Origin 0 coordinate bias. */ #define ESC 0x1B /* ESC character. */ #define BEL 0x07 /* ascii bell character */ extern int ttopen(); /* Forward references. */ extern int ttgetc(); extern int ttputc(); extern int ttflush(); extern int ttclose(); extern int vt52move(); extern int vt52eeol(); extern int vt52eeop(); extern int vt52beep(); extern int vt52open(); /* * Dispatch table. All the * hard fields just point into the * terminal I/O code. */ TERM term = { NROW-1, NCOL, vt52open, ttclose, ttgetc, ttputc, ttflush, vt52move, vt52eeol, vt52eeop, vt52beep }; vt52move(row, col) { ttputc(ESC); ttputc('Y'); ttputc(row+BIAS); ttputc(col+BIAS); } vt52eeol() { ttputc(ESC); ttputc('K'); } vt52eeop() { ttputc(ESC); ttputc('J'); } vt52beep() { #ifdef BEL ttputc(BEL); ttflush(); #endif } #endif vt52open() { #ifdef V7 register char *cp; char *getenv(); if ((cp = getenv("TERM")) == NULL) { puts("Shell variable TERM not defined!"); exit(1); } if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) { puts("Terminal type not 'vt52'or 'z19' !"); exit(1); } #endif ttopen(); } ========== os.9/public.domain #102, from jimomura, 11749 chars, Sun Mar 23 11:30:37 1986 ---------- TITLE: 'microEMACS' part 33 'uewindow.c' /* * Window management. Some of the functions are internal, and some are * attached to keys that the user actually types. */ #include <stdio.h> #include "ueed.h" /* * Reposition dot in the current window to line "n". If the argument is * positive, it is that line. If it is negative it is that line from the * bottom. If it is 0 the window is centered (this is what the standard * redisplay code does). With no argument it defaults to 1. Bound to M-!. * Because of the default, it works like in Gosling. */ reposition(f, n) { curwp->w_force = n; curwp->w_flag |= WFFORCE; return (TRUE); } /* * Refresh the screen. With no argument, it just does the refresh. With an * argument it recenters "." in the current window. Bound to "C-L". */ refresh(f, n) { if (f == FALSE) sgarbf = TRUE; else { curwp->w_force = 0; /* Center dot. */ curwp->w_flag |= WFFORCE; } return (TRUE); } #ifndef OS9 /* * The command make the next window (next => down the screen) the current * window. There are no real errors, although the command does nothing if * there is only 1 window on the screen. Bound to "C-X C-N". */ nextwind(f, n) { register WINDOW *wp; if ((wp = curwp->w_wndp) == NULL) wp = wheadp; curwp = wp; curbp = wp->w_bufp; return (TRUE); } /* * This command makes the previous window (previous => up the screen) the * current window. There arn't any errors, although the command does not do a * lot if there is 1 window. */ prevwind(f, n) { register WINDOW *wp1; register WINDOW *wp2; wp1 = wheadp; wp2 = curwp; if (wp1 == wp2) wp2 = NULL; while (wp1->w_wndp != wp2) wp1 = wp1->w_wndp; curwp = wp1; curbp = wp1->w_bufp; return (TRUE); } /* * This command moves the current window down by "arg" lines. Recompute the * top line in the window. The move up and move down code is almost completely * the same; most of the work has to do with reframing the window, and picking * a new dot. We share the code by having "move down" just be an interface to * "move up". Magic. Bound to "C-X C-N". */ mvdnwind(f, n) int n; { return (mvupwind(f, -n)); } /* * Move the current window up by "arg" lines. Recompute the new top line of * the window. Look to see if "." is still on the screen. If it is, you win. * If it isn't, then move "." to center it in the new framing of the window * (this command does not really move "."; it moves the frame). Bound to * "C-X C-P". */ mvupwind(f, n) int n; { register LINE *lp; register int i; lp = curwp->w_linep; if (n < 0) { while (n++ && lp!=curbp->b_linep) lp = lforw(lp); } else { while (n-- && lback(lp)!=curbp->b_linep) lp = lback(lp); } curwp->w_linep = lp; curwp->w_flag |= WFHARD; /* Mode line is OK. */ for (i = 0; i < curwp->w_ntrows; ++i) { if (lp == curwp->w_dotp) return (TRUE); if (lp == curbp->b_linep) break; lp = lforw(lp); } lp = curwp->w_linep; i = curwp->w_ntrows/2; while (i-- && lp != curbp->b_linep) lp = lforw(lp); curwp->w_dotp = lp; curwp->w_doto = 0; return (TRUE); } /* * This command makes the current window the only window on the screen. Bound * to "C-X 1". Try to set the framing so that "." does not have to move on the * display. Some care has to be taken to keep the values of dot and mark in * the buffer structures right if the distruction of a window makes a buffer * become undisplayed. */ onlywind(f, n) { register WINDOW *wp; register LINE *lp; register int i; while (wheadp != curwp) { wp = wheadp; wheadp = wp->w_wndp; if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } free((char *) wp); } while (curwp->w_wndp != NULL) { wp = curwp->w_wndp; curwp->w_wndp = wp->w_wndp; if (--wp->w_bufp->b_nwnd == 0) { wp->w_bufp->b_dotp = wp->w_dotp; wp->w_bufp->b_doto = wp->w_doto; wp->w_bufp->b_markp = wp->w_markp; wp->w_bufp->b_marko = wp->w_marko; } free((char *) wp); } lp = curwp->w_linep; i = curwp->w_toprow; while (i!=0 && lback(lp)!=curbp->b_linep) { --i; lp = lback(lp); } curwp->w_toprow = 0; curwp->w_ntrows = term.t_nrow-1; curwp->w_linep = lp; curwp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Split the current window. A window smaller than 3 lines cannot be split. * The only other error that is possible is a "malloc" failure allocating the * structure for the new window. Bound to "C-X 2". */ splitwind(f, n) { register WINDOW *wp; register LINE *lp; register int ntru; register int ntrl; register int ntrd; register WINDOW *wp1; register WINDOW *wp2; if (curwp->w_ntrows < 3) { mlwrite("Cannot split a %d line window", curwp->w_ntrows); return (FALSE); } if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) { mlwrite("Cannot allocate WINDOW block"); return (FALSE); } ++curbp->b_nwnd; /* Displayed twice. */ wp->w_bufp = curbp; wp->w_dotp = curwp->w_dotp; wp->w_doto = curwp->w_doto; wp->w_markp = curwp->w_markp; wp->w_marko = curwp->w_marko; wp->w_flag = 0; wp->w_force = 0; ntru = (curwp->w_ntrows-1) / 2; /* Upper size */ ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */ lp = curwp->w_linep; ntrd = 0; while (lp != curwp->w_dotp) { ++ntrd; lp = lforw(lp); } lp = curwp->w_linep; if (ntrd <= ntru) { /* Old is upper window. */ if (ntrd == ntru) /* Hit mode line. */ lp = lforw(lp); curwp->w_ntrows = ntru; wp->w_wndp = curwp->w_wndp; curwp->w_wndp = wp; wp->w_toprow = curwp->w_toprow+ntru+1; wp->w_ntrows = ntrl; } else { /* Old is lower window */ wp1 = NULL; wp2 = wheadp; while (wp2 != curwp) { wp1 = wp2; wp2 = wp2->w_wndp; } if (wp1 == NULL) wheadp = wp; else wp1->w_wndp = wp; wp->w_wndp = curwp; wp->w_toprow = curwp->w_toprow; wp->w_ntrows = ntru; ++ntru; /* Mode line. */ curwp->w_toprow += ntru; curwp->w_ntrows = ntrl; while (ntru--) lp = lforw(lp); } curwp->w_linep = lp; /* Adjust the top lines */ wp->w_linep = lp; /* if necessary. */ curwp->w_flag |= WFMODE|WFHARD; wp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Enlarge the current window. Find the window that loses space. Make sure it * is big enough. If so, hack the window descriptions, and ask redisplay to do * all the hard work. You don't just set "force reframe" because dot would * move. Bound to "C-X Z". */ enlargewind(f, n) { register WINDOW *adjwp; register LINE *lp; register int i; if (n < 0) return (shrinkwind(f, -n)); if (wheadp->w_wndp == NULL) { mlwrite("Only one window"); return (FALSE); } if ((adjwp=curwp->w_wndp) == NULL) { adjwp = wheadp; while (adjwp->w_wndp != curwp) adjwp = adjwp->w_wndp; } if (adjwp->w_ntrows <= n) { mlwrite("Impossible change"); return (FALSE); } if (curwp->w_wndp == adjwp) { /* Shrink below. */ lp = adjwp->w_linep; for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i) lp = lforw(lp); adjwp->w_linep = lp; adjwp->w_toprow += n; } else { /* Shrink above. */ lp = curwp->w_linep; for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i) lp = lback(lp); curwp->w_linep = lp; curwp->w_toprow -= n; } curwp->w_ntrows += n; adjwp->w_ntrows -= n; curwp->w_flag |= WFMODE|WFHARD; adjwp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Shrink the current window. Find the window that gains space. Hack at the * window descriptions. Ask the redisplay to do all the hard work. Bound to * "C-X C-Z". */ shrinkwind(f, n) { register WINDOW *adjwp; register LINE *lp; register int i; if (n < 0) return (enlargewind(f, -n)); if (wheadp->w_wndp == NULL) { mlwrite("Only one window"); return (FALSE); } if ((adjwp=curwp->w_wndp) == NULL) { adjwp = wheadp; while (adjwp->w_wndp != curwp) adjwp = adjwp->w_wndp; } if (curwp->w_ntrows <= n) { mlwrite("Impossible change"); return (FALSE); } if (curwp->w_wndp == adjwp) { /* Grow below. */ lp = adjwp->w_linep; for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i) lp = lback(lp); adjwp->w_linep = lp; adjwp->w_toprow -= n; } else { /* Grow above. */ lp = curwp->w_linep; for (i=0; i<n && lp!=curbp->b_linep; ++i) lp = lforw(lp); curwp->w_linep = lp; curwp->w_toprow += n; } curwp->w_ntrows -= n; adjwp->w_ntrows += n; curwp->w_flag |= WFMODE|WFHARD; adjwp->w_flag |= WFMODE|WFHARD; return (TRUE); } /* * Pick a window for a pop-up. Split the screen if there is only one window. * Pick the uppermost window that isn't the current window. An LRU algorithm * might be better. Return a pointer, or NULL on error. */ WINDOW * wpopup() { register WINDOW *wp; if (wheadp->w_wndp == NULL /* Only 1 window */ && splitwind(FALSE, 0) == FALSE) /* and it won't split */ return (NULL); wp = wheadp; /* Find window to use */ while (wp!=NULL && wp==curwp) wp = wp->w_wndp; return (wp); } #endif ========== os.9/public.domain #103, from jimomura, 9000 chars, Sun Mar 23 11:47:11 1986 ---------- TITLE: 'microEMACS' part 34 'ueword.c' /* * The routines in this file implement commands that work word at a time. * There are all sorts of word mode commands. If I do any sentence and/or * paragraph mode commands, they are likely to be put in this file. */ #include <stdio.h> #include "ueed.h" /* Word wrap on n-spaces. Back-over whatever precedes the point on the current * line and stop on the first word-break or the beginning of the line. If we * reach the beginning of the line, jump back to the end of the word and start * a new line. Otherwise, break the line at the word-break, eat it, and jump * back to the end of the word. * NOTE: This function may leaving trailing blanks. * Returns TRUE on success, FALSE on errors. */ wrapword(n) int n; { register int cnt, oldp; oldp = curwp->w_dotp; cnt = -1; do { cnt++; if (! backchar(NULL, 1)) return(FALSE); } while (! inword()); if (! backword(NULL, 1)) return(FALSE); if (oldp == (int) (curwp->w_dotp && curwp->w_doto)) { if (! backdel(NULL, 1)) return(FALSE); if (! newline(NULL, 1)) return(FALSE); } return(forwword(NULL, 1) && forwchar(NULL, cnt)); } /* * Move the cursor backward by "n" words. All of the details of motion are * performed by the "backchar" and "forwchar" routines. Error if you try to * move beyond the buffers. */ backword(f, n) { if (n < 0) return (forwword(f, -n)); if (backchar(FALSE, 1) == FALSE) return (FALSE); while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); } } return (forwchar(FALSE, 1)); } /* * Move the cursor forward by the specified number of words. All of the motion * is done by "forwchar". Error if you try and move beyond the buffer's end. */ forwword(f, n) { if (n < 0) return (backword(f, -n)); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move, * convert any characters to upper case. Error if you try and move beyond the * end of the buffer. Bound to "M-U". */ upperword(f, n) { register int c; if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='a' && c<='z') { c -= 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move * convert characters to lower case. Error if you try and move over the end of * the buffer. Bound to "M-L". */ lowerword(f, n) { register int c; if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='A' && c<='Z') { c += 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return (TRUE); } /* * Move the cursor forward by the specified number of words. As you move * convert the first character of the word to upper case, and subsequent * characters to lower case. Error if you try and move past the end of the * buffer. Bound to "M-C". */ capword(f, n) { register int c; if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } if (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='a' && c<='z') { c -= 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='A' && c<='Z') { c += 'a'-'A'; lputc(curwp->w_dotp, curwp->w_doto, c); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } } return (TRUE); } /* * Kill forward by "n" words. Remember the location of dot. Move forward by * the right number of words. Put dot back where it was and issue the kill * command for the right number of characters. Bound to "M-D". */ delfword(f, n) { register int size; register LINE *dotp; register int doto; if (n < 0) return (FALSE); dotp = curwp->w_dotp; doto = curwp->w_doto; size = 0; while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); ++size; } while (inword() != FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); ++size; } } curwp->w_dotp = dotp; curwp->w_doto = doto; return (ldelete(size, TRUE)); } /* * Kill backwards by "n" words. Move backwards by the desired number of words, * counting the characters. When dot is finally moved to its resting place, * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". */ delbword(f, n) { register int size; if (n < 0) return (FALSE); if (backchar(FALSE, 1) == FALSE) return (FALSE); size = 0; while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } } if (forwchar(FALSE, 1) == FALSE) return (FALSE); return (ldelete(size, TRUE)); } /* * Return TRUE if the character at dot is a character that is considered to be * part of a word. The word character list is hard coded. Should be setable. */ inword() { register int c; if (curwp->w_doto == llength(curwp->w_dotp)) return (FALSE); c = lgetc(curwp->w_dotp, curwp->w_doto); if (c>='a' && c<='z') return (TRUE); if (c>='A' && c<='Z') return (TRUE); if (c>='0' && c<='9') return (TRUE); if (c=='$' || c=='_') /* For identifiers */ return (TRUE); return (FALSE); } R:Are you there? Goodbye..'jimomura' Off at Wed Apr 30 18:40:26 1986 DROPPED BY HOST please log in: please see your representative -- James Omura, Barrister & Solicitor, Toronto ihnp4!utzoo!lsuc!jimomura Byte Information eXchange: jimomura (416) 652-3880