home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-11-20 | 37.0 KB | 1,491 lines |
- Article 90 of comp.sources.misc:
- Path: tut!osu-cis!cbosgd!mandrill!hal!ncoast!allbery
- From: nwd@j.cc.purdue.edu (Daniel Lawrence)
- Newsgroups: comp.sources.misc
- Subject: MicroEmacs 3.9 (Part 13 of 16)
- Message-ID: <5689@ncoast.UUCP>
- Date: 17 Nov 87 02:35:24 GMT
- Sender: allbery@ncoast.UUCP
- Lines: 1476
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/microemacs-3.9/12
-
- # This is a shar archive.
- # Remove everything above this line.
- # Run the file through sh, not csh.
- # (type `sh mes.13')
- # If you do not see the message
- # `mes.13 completed!'
- # then the file was incomplete.
- echo extracting - vt52.c
- sed 's/^X//' > vt52.c << 'FRIDAY_NIGHT'
- X/*
- X * The routines in this file
- X * provide support for VT52 style terminals
- X * over a serial line. The serial I/O services are
- X * provided by routines in "termio.c". It compiles
- X * into nothing if not a VT52 style device. The
- X * bell on the VT52 is terrible, so the "beep"
- X * routine is conditionalized on defining BEL.
- X */
- X#define termdef 1 /* don't define "term" external */
- X
- X#include <stdio.h>
- X#include "estruct.h"
- X#include "edef.h"
- X
- X#if VT52
- X
- X#define NROW 24 /* Screen size. */
- X#define NCOL 80 /* Edit if you want to. */
- X#define MARGIN 8 /* size of minimim margin and */
- X#define SCRSIZ 64 /* scroll size for extended lines */
- X#define NPAUSE 100 /* # times thru update to pause */
- X#define BIAS 0x20 /* Origin 0 coordinate bias. */
- X#define ESC 0x1B /* ESC character. */
- X#define BEL 0x07 /* ascii bell character */
- X
- Xextern int ttopen(); /* Forward references. */
- Xextern int ttgetc();
- Xextern int ttputc();
- Xextern int ttflush();
- Xextern int ttclose();
- Xextern int vt52move();
- Xextern int vt52eeol();
- Xextern int vt52eeop();
- Xextern int vt52beep();
- Xextern int vt52open();
- Xextern int vt52rev();
- Xextern int vt52cres();
- Xextern int vt52kopen();
- Xextern int vt52kclose();
- X
- X#if COLOR
- Xextern int vt52fcol();
- Xextern int vt52bcol();
- X#endif
- X
- X/*
- X * Dispatch table. All the
- X * hard fields just point into the
- X * terminal I/O code.
- X */
- XTERM term = {
- X NROW-1,
- X NROW-1,
- X NCOL,
- X NCOL,
- X MARGIN,
- X SCRSIZ,
- X NPAUSE,
- X &vt52open,
- X &ttclose,
- X &vt52kopen,
- X &vt52kclose,
- X &ttgetc,
- X &ttputc,
- X &ttflush,
- X &vt52move,
- X &vt52eeol,
- X &vt52eeop,
- X &vt52beep,
- X &vt52rev,
- X &vt52cres
- X#if COLOR
- X , &vt52fcol,
- X &vt52bcol
- X#endif
- X};
- X
- Xvt52move(row, col)
- X{
- X ttputc(ESC);
- X ttputc('Y');
- X ttputc(row+BIAS);
- X ttputc(col+BIAS);
- X}
- X
- Xvt52eeol()
- X{
- X ttputc(ESC);
- X ttputc('K');
- X}
- X
- Xvt52eeop()
- X{
- X ttputc(ESC);
- X ttputc('J');
- X}
- X
- Xvt52rev(status) /* set the reverse video state */
- X
- Xint status; /* TRUE = reverse video, FALSE = normal video */
- X
- X{
- X /* can't do this here, so we won't */
- X}
- X
- Xvt52cres() /* change screen resolution - (not here though) */
- X
- X{
- X return(TRUE);
- X}
- X
- Xspal() /* change palette string */
- X
- X{
- X /* Does nothing here */
- X}
- X
- X#if COLOR
- Xvt52fcol() /* set the forground color [NOT IMPLIMENTED] */
- X{
- X}
- X
- Xvt52bcol() /* set the background color [NOT IMPLIMENTED] */
- X{
- X}
- X#endif
- X
- Xvt52beep()
- X{
- X#ifdef BEL
- X ttputc(BEL);
- X ttflush();
- X#endif
- X}
- X
- Xvt52open()
- X{
- X#if V7 | BSD
- X register char *cp;
- X char *getenv();
- X
- X if ((cp = getenv("TERM")) == NULL) {
- X puts("Shell variable TERM not defined!");
- X exit(1);
- X }
- X if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
- X puts("Terminal type not 'vt52'or 'z19' !");
- X exit(1);
- X }
- X#endif
- X ttopen();
- X}
- X
- Xvt52kopen()
- X
- X{
- X}
- X
- Xvt52kclose()
- X
- X{
- X}
- X
- X
- X#if FLABEL
- Xfnclabel(f, n) /* label a function key */
- X
- Xint f,n; /* default flag, numeric argument [unused] */
- X
- X{
- X /* on machines with no function keys...don't bother */
- X return(TRUE);
- X}
- X#endif
- X#else
- X
- Xvt52hello()
- X
- X{
- X}
- X
- X#endif
- FRIDAY_NIGHT
- echo extracting - window.c
- sed 's/^X//' > window.c << 'FRIDAY_NIGHT'
- X/*
- X * Window management. Some of the functions are internal, and some are
- X * attached to keys that the user actually types.
- X */
- X
- X#include <stdio.h>
- X#include "estruct.h"
- X#include "edef.h"
- X
- X#if MEGAMAX & ST520
- Xoverlay "window"
- X#endif
- X
- X/*
- X * Reposition dot in the current window to line "n". If the argument is
- X * positive, it is that line. If it is negative it is that line from the
- X * bottom. If it is 0 the window is centered (this is what the standard
- X * redisplay code does). With no argument it defaults to 0. Bound to M-!.
- X */
- Xreposition(f, n)
- X {
- X if (f == FALSE) /* default to 0 to center screen */
- X n = 0;
- X curwp->w_force = n;
- X curwp->w_flag |= WFFORCE;
- X return (TRUE);
- X }
- X
- X/*
- X * Refresh the screen. With no argument, it just does the refresh. With an
- X * argument it recenters "." in the current window. Bound to "C-L".
- X */
- Xrefresh(f, n)
- X {
- X if (f == FALSE)
- X sgarbf = TRUE;
- X else
- X {
- X curwp->w_force = 0; /* Center dot. */
- X curwp->w_flag |= WFFORCE;
- X }
- X
- X return (TRUE);
- X }
- X
- X/*
- X * The command make the next window (next => down the screen) the current
- X * window. There are no real errors, although the command does nothing if
- X * there is only 1 window on the screen. Bound to "C-X C-N".
- X *
- X * with an argument this command finds the <n>th window from the top
- X *
- X */
- Xnextwind(f, n)
- X
- Xint f, n; /* default flag and numeric argument */
- X
- X{
- X register WINDOW *wp;
- X register int nwindows; /* total number of windows */
- X
- X if (f) {
- X
- X /* first count the # of windows */
- X wp = wheadp;
- X nwindows = 1;
- X while (wp->w_wndp != NULL) {
- X nwindows++;
- X wp = wp->w_wndp;
- X }
- X
- X /* if the argument is negative, it is the nth window
- X from the bottom of the screen */
- X if (n < 0)
- X n = nwindows + n + 1;
- X
- X /* if an argument, give them that window from the top */
- X if (n > 0 && n <= nwindows) {
- X wp = wheadp;
- X while (--n)
- X wp = wp->w_wndp;
- X } else {
- X mlwrite("Window number out of range");
- X return(FALSE);
- X }
- X } else
- X if ((wp = curwp->w_wndp) == NULL)
- X wp = wheadp;
- X curwp = wp;
- X curbp = wp->w_bufp;
- X upmode();
- X return (TRUE);
- X}
- X
- X/*
- X * This command makes the previous window (previous => up the screen) the
- X * current window. There arn't any errors, although the command does not do a
- X * lot if there is 1 window.
- X */
- Xprevwind(f, n)
- X{
- X register WINDOW *wp1;
- X register WINDOW *wp2;
- X
- X /* if we have an argument, we mean the nth window from the bottom */
- X if (f)
- X return(nextwind(f, -n));
- X
- X wp1 = wheadp;
- X wp2 = curwp;
- X
- X if (wp1 == wp2)
- X wp2 = NULL;
- X
- X while (wp1->w_wndp != wp2)
- X wp1 = wp1->w_wndp;
- X
- X curwp = wp1;
- X curbp = wp1->w_bufp;
- X upmode();
- X return (TRUE);
- X}
- X
- X/*
- X * This command moves the current window down by "arg" lines. Recompute the
- X * top line in the window. The move up and move down code is almost completely
- X * the same; most of the work has to do with reframing the window, and picking
- X * a new dot. We share the code by having "move down" just be an interface to
- X * "move up". Magic. Bound to "C-X C-N".
- X */
- Xmvdnwind(f, n)
- X
- Xint n;
- X
- X{
- X return (mvupwind(f, -n));
- X}
- X
- X/*
- X * Move the current window up by "arg" lines. Recompute the new top line of
- X * the window. Look to see if "." is still on the screen. If it is, you win.
- X * If it isn't, then move "." to center it in the new framing of the window
- X * (this command does not really move "."; it moves the frame). Bound to
- X * "C-X C-P".
- X */
- Xmvupwind(f, n)
- X int n;
- X
- X {
- X register LINE *lp;
- X register int i;
- X
- X lp = curwp->w_linep;
- X
- X if (n < 0)
- X {
- X while (n++ && lp!=curbp->b_linep)
- X lp = lforw(lp);
- X }
- X else
- X {
- X while (n-- && lback(lp)!=curbp->b_linep)
- X lp = lback(lp);
- X }
- X
- X curwp->w_linep = lp;
- X curwp->w_flag |= WFHARD; /* Mode line is OK. */
- X
- X for (i = 0; i < curwp->w_ntrows; ++i)
- X {
- X if (lp == curwp->w_dotp)
- X return (TRUE);
- X if (lp == curbp->b_linep)
- X break;
- X lp = lforw(lp);
- X }
- X
- X lp = curwp->w_linep;
- X i = curwp->w_ntrows/2;
- X
- X while (i-- && lp != curbp->b_linep)
- X lp = lforw(lp);
- X
- X curwp->w_dotp = lp;
- X curwp->w_doto = 0;
- X return (TRUE);
- X }
- X
- X/*
- X * This command makes the current window the only window on the screen. Bound
- X * to "C-X 1". Try to set the framing so that "." does not have to move on the
- X * display. Some care has to be taken to keep the values of dot and mark in
- X * the buffer structures right if the distruction of a window makes a buffer
- X * become undisplayed.
- X */
- Xonlywind(f, n)
- X{
- X register WINDOW *wp;
- X register LINE *lp;
- X register int i;
- X
- X while (wheadp != curwp) {
- X wp = wheadp;
- X wheadp = wp->w_wndp;
- X if (--wp->w_bufp->b_nwnd == 0) {
- X wp->w_bufp->b_dotp = wp->w_dotp;
- X wp->w_bufp->b_doto = wp->w_doto;
- X wp->w_bufp->b_markp = wp->w_markp;
- X wp->w_bufp->b_marko = wp->w_marko;
- X }
- X free((char *) wp);
- X }
- X while (curwp->w_wndp != NULL) {
- X wp = curwp->w_wndp;
- X curwp->w_wndp = wp->w_wndp;
- X if (--wp->w_bufp->b_nwnd == 0) {
- X wp->w_bufp->b_dotp = wp->w_dotp;
- X wp->w_bufp->b_doto = wp->w_doto;
- X wp->w_bufp->b_markp = wp->w_markp;
- X wp->w_bufp->b_marko = wp->w_marko;
- X }
- X free((char *) wp);
- X }
- X lp = curwp->w_linep;
- X i = curwp->w_toprow;
- X while (i!=0 && lback(lp)!=curbp->b_linep) {
- X --i;
- X lp = lback(lp);
- X }
- X curwp->w_toprow = 0;
- X curwp->w_ntrows = term.t_nrow-1;
- X curwp->w_linep = lp;
- X curwp->w_flag |= WFMODE|WFHARD;
- X return (TRUE);
- X}
- X
- X/*
- X * Delete the current window, placing its space in the window above,
- X * or, if it is the top window, the window below. Bound to C-X 0.
- X */
- X
- Xdelwind(f,n)
- X
- Xint f, n; /* arguments are ignored for this command */
- X
- X{
- X register WINDOW *wp; /* window to recieve deleted space */
- X register WINDOW *lwp; /* ptr window before curwp */
- X register int target; /* target line to search for */
- X
- X /* if there is only one window, don't delete it */
- X if (wheadp->w_wndp == NULL) {
- X mlwrite("Can not delete this window");
- X return(FALSE);
- X }
- X
- X /* find window before curwp in linked list */
- X wp = wheadp;
- X lwp = NULL;
- X while (wp != NULL) {
- X if (wp == curwp)
- X break;
- X lwp = wp;
- X wp = wp->w_wndp;
- X }
- X
- X /* find recieving window and give up our space */
- X wp = wheadp;
- X if (curwp->w_toprow == 0) {
- X /* find the next window down */
- X target = curwp->w_ntrows + 1;
- X while (wp != NULL) {
- X if (wp->w_toprow == target)
- X break;
- X wp = wp->w_wndp;
- X }
- X if (wp == NULL)
- X return(FALSE);
- X wp->w_toprow = 0;
- X wp->w_ntrows += target;
- X } else {
- X /* find the next window up */
- X target = curwp->w_toprow - 1;
- X while (wp != NULL) {
- X if ((wp->w_toprow + wp->w_ntrows) == target)
- X break;
- X wp = wp->w_wndp;
- X }
- X if (wp == NULL)
- X return(FALSE);
- X wp->w_ntrows += 1 + curwp->w_ntrows;
- X }
- X
- X /* get rid of the current window */
- X if (--curwp->w_bufp->b_nwnd == 0) {
- X curwp->w_bufp->b_dotp = curwp->w_dotp;
- X curwp->w_bufp->b_doto = curwp->w_doto;
- X curwp->w_bufp->b_markp = curwp->w_markp;
- X curwp->w_bufp->b_marko = curwp->w_marko;
- X }
- X if (lwp == NULL)
- X wheadp = curwp->w_wndp;
- X else
- X lwp->w_wndp = curwp->w_wndp;
- X free((char *)curwp);
- X curwp = wp;
- X wp->w_flag |= WFHARD;
- X curbp = wp->w_bufp;
- X upmode();
- X return(TRUE);
- X}
- X
- X/*
- X
- XSplit the current window. A window smaller than 3 lines cannot be
- Xsplit. An argument of 1 forces the cursor into the upper window, an
- Xargument of two forces the cursor to the lower window. The only other
- Xerror that is possible is a "malloc" failure allocating the structure
- Xfor the new window. Bound to "C-X 2".
- X
- X */
- Xsplitwind(f, n)
- X
- Xint f, n; /* default flag and numeric argument */
- X
- X{
- X register WINDOW *wp;
- X register LINE *lp;
- X register int ntru;
- X register int ntrl;
- X register int ntrd;
- X register WINDOW *wp1;
- X register WINDOW *wp2;
- X char *malloc();
- X
- X if (curwp->w_ntrows < 3) {
- X mlwrite("Cannot split a %d line window", curwp->w_ntrows);
- X return (FALSE);
- X }
- X if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
- X mlwrite("[OUT OF MEMORY]");
- X return (FALSE);
- X }
- X ++curbp->b_nwnd; /* Displayed twice. */
- X wp->w_bufp = curbp;
- X wp->w_dotp = curwp->w_dotp;
- X wp->w_doto = curwp->w_doto;
- X wp->w_markp = curwp->w_markp;
- X wp->w_marko = curwp->w_marko;
- X wp->w_flag = 0;
- X wp->w_force = 0;
- X#if COLOR
- X /* set the colors of the new window */
- X wp->w_fcolor = gfcolor;
- X wp->w_bcolor = gbcolor;
- X#endif
- X ntru = (curwp->w_ntrows-1) / 2; /* Upper size */
- X ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */
- X lp = curwp->w_linep;
- X ntrd = 0;
- X while (lp != curwp->w_dotp) {
- X ++ntrd;
- X lp = lforw(lp);
- X }
- X lp = curwp->w_linep;
- X if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
- X /* Old is upper window. */
- X if (ntrd == ntru) /* Hit mode line. */
- X lp = lforw(lp);
- X curwp->w_ntrows = ntru;
- X wp->w_wndp = curwp->w_wndp;
- X curwp->w_wndp = wp;
- X wp->w_toprow = curwp->w_toprow+ntru+1;
- X wp->w_ntrows = ntrl;
- X } else { /* Old is lower window */
- X wp1 = NULL;
- X wp2 = wheadp;
- X while (wp2 != curwp) {
- X wp1 = wp2;
- X wp2 = wp2->w_wndp;
- X }
- X if (wp1 == NULL)
- X wheadp = wp;
- X else
- X wp1->w_wndp = wp;
- X wp->w_wndp = curwp;
- X wp->w_toprow = curwp->w_toprow;
- X wp->w_ntrows = ntru;
- X ++ntru; /* Mode line. */
- X curwp->w_toprow += ntru;
- X curwp->w_ntrows = ntrl;
- X while (ntru--)
- X lp = lforw(lp);
- X }
- X curwp->w_linep = lp; /* Adjust the top lines */
- X wp->w_linep = lp; /* if necessary. */
- X curwp->w_flag |= WFMODE|WFHARD;
- X wp->w_flag |= WFMODE|WFHARD;
- X return (TRUE);
- X}
- X
- X/*
- X * Enlarge the current window. Find the window that loses space. Make sure it
- X * is big enough. If so, hack the window descriptions, and ask redisplay to do
- X * all the hard work. You don't just set "force reframe" because dot would
- X * move. Bound to "C-X Z".
- X */
- Xenlargewind(f, n)
- X{
- X register WINDOW *adjwp;
- X register LINE *lp;
- X register int i;
- X
- X if (n < 0)
- X return (shrinkwind(f, -n));
- X if (wheadp->w_wndp == NULL) {
- X mlwrite("Only one window");
- X return (FALSE);
- X }
- X if ((adjwp=curwp->w_wndp) == NULL) {
- X adjwp = wheadp;
- X while (adjwp->w_wndp != curwp)
- X adjwp = adjwp->w_wndp;
- X }
- X if (adjwp->w_ntrows <= n) {
- X mlwrite("Impossible change");
- X return (FALSE);
- X }
- X if (curwp->w_wndp == adjwp) { /* Shrink below. */
- X lp = adjwp->w_linep;
- X for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
- X lp = lforw(lp);
- X adjwp->w_linep = lp;
- X adjwp->w_toprow += n;
- X } else { /* Shrink above. */
- X lp = curwp->w_linep;
- X for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
- X lp = lback(lp);
- X curwp->w_linep = lp;
- X curwp->w_toprow -= n;
- X }
- X curwp->w_ntrows += n;
- X adjwp->w_ntrows -= n;
- X curwp->w_flag |= WFMODE|WFHARD;
- X adjwp->w_flag |= WFMODE|WFHARD;
- X return (TRUE);
- X}
- X
- X/*
- X * Shrink the current window. Find the window that gains space. Hack at the
- X * window descriptions. Ask the redisplay to do all the hard work. Bound to
- X * "C-X C-Z".
- X */
- Xshrinkwind(f, n)
- X{
- X register WINDOW *adjwp;
- X register LINE *lp;
- X register int i;
- X
- X if (n < 0)
- X return (enlargewind(f, -n));
- X if (wheadp->w_wndp == NULL) {
- X mlwrite("Only one window");
- X return (FALSE);
- X }
- X if ((adjwp=curwp->w_wndp) == NULL) {
- X adjwp = wheadp;
- X while (adjwp->w_wndp != curwp)
- X adjwp = adjwp->w_wndp;
- X }
- X if (curwp->w_ntrows <= n) {
- X mlwrite("Impossible change");
- X return (FALSE);
- X }
- X if (curwp->w_wndp == adjwp) { /* Grow below. */
- X lp = adjwp->w_linep;
- X for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
- X lp = lback(lp);
- X adjwp->w_linep = lp;
- X adjwp->w_toprow -= n;
- X } else { /* Grow above. */
- X lp = curwp->w_linep;
- X for (i=0; i<n && lp!=curbp->b_linep; ++i)
- X lp = lforw(lp);
- X curwp->w_linep = lp;
- X curwp->w_toprow += n;
- X }
- X curwp->w_ntrows -= n;
- X adjwp->w_ntrows += n;
- X curwp->w_flag |= WFMODE|WFHARD;
- X adjwp->w_flag |= WFMODE|WFHARD;
- X return (TRUE);
- X}
- X
- X/* Resize the current window to the requested size */
- X
- Xresize(f, n)
- X
- Xint f, n; /* default flag and numeric argument */
- X
- X{
- X int clines; /* current # of lines in window */
- X
- X /* must have a non-default argument, else ignore call */
- X if (f == FALSE)
- X return(TRUE);
- X
- X /* find out what to do */
- X clines = curwp->w_ntrows;
- X
- X /* already the right size? */
- X if (clines == n)
- X return(TRUE);
- X
- X return(enlargewind(TRUE, n - clines));
- X}
- X
- X/*
- X * Pick a window for a pop-up. Split the screen if there is only one window.
- X * Pick the uppermost window that isn't the current window. An LRU algorithm
- X * might be better. Return a pointer, or NULL on error.
- X */
- XWINDOW *
- Xwpopup()
- X{
- X register WINDOW *wp;
- X
- X if (wheadp->w_wndp == NULL /* Only 1 window */
- X && splitwind(FALSE, 0) == FALSE) /* and it won't split */
- X return (NULL);
- X wp = wheadp; /* Find window to use */
- X while (wp!=NULL && wp==curwp)
- X wp = wp->w_wndp;
- X return (wp);
- X}
- X
- Xscrnextup(f, n) /* scroll the next window up (back) a page */
- X
- X{
- X nextwind(FALSE, 1);
- X backpage(f, n);
- X prevwind(FALSE, 1);
- X}
- X
- Xscrnextdw(f, n) /* scroll the next window down (forward) a page */
- X
- X{
- X nextwind(FALSE, 1);
- X forwpage(f, n);
- X prevwind(FALSE, 1);
- X}
- X
- Xsavewnd(f, n) /* save ptr to current window */
- X
- X{
- X swindow = curwp;
- X return(TRUE);
- X}
- X
- Xrestwnd(f, n) /* restore the saved screen */
- X
- X{
- X register WINDOW *wp;
- X
- X /* find the window */
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp == swindow) {
- X curwp = wp;
- X curbp = wp->w_bufp;
- X upmode();
- X return (TRUE);
- X }
- X wp = wp->w_wndp;
- X }
- X
- X mlwrite("[No such window exists]");
- X return(FALSE);
- X}
- X
- Xnewsize(f, n) /* resize the screen, re-writing the screen */
- X
- Xint f; /* default flag */
- Xint n; /* numeric argument */
- X
- X{
- X WINDOW *wp; /* current window being examined */
- X WINDOW *nextwp; /* next window to scan */
- X WINDOW *lastwp; /* last window scanned */
- X int lastline; /* screen line of last line of current window */
- X
- X /* if the command defaults, assume the largest */
- X if (f == FALSE)
- X n = term.t_mrow + 1;
- X
- X /* make sure it's in range */
- X if (n < 3 || n > term.t_mrow + 1) {
- X mlwrite("%%Screen size out of range");
- X return(FALSE);
- X }
- X
- X if (term.t_nrow == n - 1)
- X return(TRUE);
- X else if (term.t_nrow < n - 1) {
- X
- X /* go to the last window */
- X wp = wheadp;
- X while (wp->w_wndp != NULL)
- X wp = wp->w_wndp;
- X
- X /* and enlarge it as needed */
- X wp->w_ntrows = n - wp->w_toprow - 2;
- X wp->w_flag |= WFHARD|WFMODE;
- X
- X } else {
- X
- X /* rebuild the window structure */
- X nextwp = wheadp;
- X wp = NULL;
- X lastwp = NULL;
- X while (nextwp != NULL) {
- X wp = nextwp;
- X nextwp = wp->w_wndp;
- X
- X /* get rid of it if it is too low */
- X if (wp->w_toprow > n - 2) {
- X
- X /* save the point/mark if needed */
- X if (--wp->w_bufp->b_nwnd == 0) {
- X wp->w_bufp->b_dotp = wp->w_dotp;
- X wp->w_bufp->b_doto = wp->w_doto;
- X wp->w_bufp->b_markp = wp->w_markp;
- X wp->w_bufp->b_marko = wp->w_marko;
- X }
- X
- X /* update curwp and lastwp if needed */
- X if (wp == curwp)
- X curwp = wheadp;
- X curbp = curwp->w_bufp;
- X if (lastwp != NULL)
- X lastwp->w_wndp = NULL;
- X
- X /* free the structure */
- X free((char *)wp);
- X wp = NULL;
- X
- X } else {
- X /* need to change this window size? */
- X lastline = wp->w_toprow + wp->w_ntrows - 1;
- X if (lastline >= n - 2) {
- X wp->w_ntrows = n - wp->w_toprow - 2;
- X wp->w_flag |= WFHARD|WFMODE;
- X }
- X }
- X
- X lastwp = wp;
- X }
- X }
- X
- X /* screen is garbage */
- X term.t_nrow = n - 1;
- X sgarbf = TRUE;
- X return(TRUE);
- X}
- X
- Xnewwidth(f, n) /* resize the screen, re-writing the screen */
- X
- Xint f; /* default flag */
- Xint n; /* numeric argument */
- X
- X{
- X register WINDOW *wp;
- X
- X /* if the command defaults, assume the largest */
- X if (f == FALSE)
- X n = term.t_mcol;
- X
- X /* make sure it's in range */
- X if (n < 10 || n > term.t_mcol) {
- X mlwrite("%%Screen width out of range");
- X return(FALSE);
- X }
- X
- X /* otherwise, just re-width it (no big deal) */
- X term.t_ncol = n;
- X term.t_margin = n / 10;
- X term.t_scrsiz = n - (term.t_margin * 2);
- X
- X /* florce all windows to redraw */
- X wp = wheadp;
- X while (wp) {
- X wp->w_flag |= WFHARD | WFMOVE | WFMODE;
- X wp = wp->w_wndp;
- X }
- X sgarbf = TRUE;
- X
- X return(TRUE);
- X}
- X
- Xint getwpos() /* get screen offset of current line in current window */
- X
- X{
- X register int sline; /* screen line from top of window */
- X register LINE *lp; /* scannile line pointer */
- X
- X /* search down the line we want */
- X lp = curwp->w_linep;
- X sline = 1;
- X while (lp != curwp->w_dotp) {
- X ++sline;
- X lp = lforw(lp);
- X }
- X
- X /* and return the value */
- X return(sline);
- X}
- FRIDAY_NIGHT
- echo extracting - word.c
- sed 's/^X//' > word.c << 'FRIDAY_NIGHT'
- X/*
- X * The routines in this file implement commands that work word or a
- X * paragraph at a time. There are all sorts of word mode commands. If I
- X * do any sentence mode commands, they are likely to be put in this file.
- X */
- X
- X#include <stdio.h>
- X#include "estruct.h"
- X#include "edef.h"
- X
- X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
- X * line and stop on the first word-break or the beginning of the line. If we
- X * reach the beginning of the line, jump back to the end of the word and start
- X * a new line. Otherwise, break the line at the word-break, eat it, and jump
- X * back to the end of the word.
- X * Returns TRUE on success, FALSE on errors.
- X */
- Xwrapword(f, n)
- X
- Xint f; /* default flag */
- Xint n; /* numeric argument */
- X
- X{
- X register int cnt; /* size of word wrapped to next line */
- X register int c; /* charector temporary */
- X
- X /* backup from the <NL> 1 char */
- X if (!backchar(0, 1))
- X return(FALSE);
- X
- X /* back up until we aren't in a word,
- X make sure there is a break in the line */
- X cnt = 0;
- X while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ')
- X && (c != '\t')) {
- X cnt++;
- X if (!backchar(0, 1))
- X return(FALSE);
- X /* if we make it to the beginning, start a new line */
- X if (curwp->w_doto == 0) {
- X gotoeol(FALSE, 0);
- X return(lnewline());
- X }
- X }
- X
- X /* delete the forward white space */
- X if (!forwdel(0, 1))
- X return(FALSE);
- X
- X /* put in a end of line */
- X if (!lnewline())
- X return(FALSE);
- X
- X /* and past the first word */
- X while (cnt-- > 0) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return(FALSE);
- X }
- X return(TRUE);
- X}
- X
- X/*
- X * Move the cursor backward by "n" words. All of the details of motion are
- X * performed by the "backchar" and "forwchar" routines. Error if you try to
- X * move beyond the buffers.
- X */
- Xbackword(f, n)
- X{
- X if (n < 0)
- X return (forwword(f, -n));
- X if (backchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X while (n--) {
- X while (inword() == FALSE) {
- X if (backchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X while (inword() != FALSE) {
- X if (backchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X }
- X return (forwchar(FALSE, 1));
- X}
- X
- X/*
- X * Move the cursor forward by the specified number of words. All of the motion
- X * is done by "forwchar". Error if you try and move beyond the buffer's end.
- X */
- Xforwword(f, n)
- X{
- X if (n < 0)
- X return (backword(f, -n));
- X while (n--) {
- X while (inword() == TRUE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X
- X while (inword() == FALSE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X }
- X return(TRUE);
- X}
- X
- X/*
- X * Move the cursor forward by the specified number of words. As you move,
- X * convert any characters to upper case. Error if you try and move beyond the
- X * end of the buffer. Bound to "M-U".
- X */
- Xupperword(f, n)
- X{
- X register int c;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if (n < 0)
- X return (FALSE);
- X while (n--) {
- X while (inword() == FALSE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X while (inword() != FALSE) {
- X c = lgetc(curwp->w_dotp, curwp->w_doto);
- X if (c>='a' && c<='z') {
- X c -= 'a'-'A';
- X lputc(curwp->w_dotp, curwp->w_doto, c);
- X lchange(WFHARD);
- X }
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X }
- X return (TRUE);
- X}
- X
- X/*
- X * Move the cursor forward by the specified number of words. As you move
- X * convert characters to lower case. Error if you try and move over the end of
- X * the buffer. Bound to "M-L".
- X */
- Xlowerword(f, n)
- X{
- X register int c;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if (n < 0)
- X return (FALSE);
- X while (n--) {
- X while (inword() == FALSE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X while (inword() != FALSE) {
- X c = lgetc(curwp->w_dotp, curwp->w_doto);
- X if (c>='A' && c<='Z') {
- X c += 'a'-'A';
- X lputc(curwp->w_dotp, curwp->w_doto, c);
- X lchange(WFHARD);
- X }
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X }
- X return (TRUE);
- X}
- X
- X/*
- X * Move the cursor forward by the specified number of words. As you move
- X * convert the first character of the word to upper case, and subsequent
- X * characters to lower case. Error if you try and move past the end of the
- X * buffer. Bound to "M-C".
- X */
- Xcapword(f, n)
- X{
- X register int c;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if (n < 0)
- X return (FALSE);
- X while (n--) {
- X while (inword() == FALSE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X if (inword() != FALSE) {
- X c = lgetc(curwp->w_dotp, curwp->w_doto);
- X if (c>='a' && c<='z') {
- X c -= 'a'-'A';
- X lputc(curwp->w_dotp, curwp->w_doto, c);
- X lchange(WFHARD);
- X }
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X while (inword() != FALSE) {
- X c = lgetc(curwp->w_dotp, curwp->w_doto);
- X if (c>='A' && c<='Z') {
- X c += 'a'-'A';
- X lputc(curwp->w_dotp, curwp->w_doto, c);
- X lchange(WFHARD);
- X }
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X }
- X }
- X }
- X return (TRUE);
- X}
- X
- X/*
- X * Kill forward by "n" words. Remember the location of dot. Move forward by
- X * the right number of words. Put dot back where it was and issue the kill
- X * command for the right number of characters. With a zero argument, just
- X * kill one word and no whitespace. Bound to "M-D".
- X */
- Xdelfword(f, n)
- X{
- X register LINE *dotp; /* original cursor line */
- X register int doto; /* and row */
- X register int c; /* temp char */
- X long size; /* # of chars to delete */
- X
- X /* don't allow this command if we are in read only mode */
- X if (curbp->b_mode&MDVIEW)
- X return(rdonly());
- X
- X /* ignore the command if there is a negative argument */
- X if (n < 0)
- X return (FALSE);
- X
- X /* Clear the kill buffer if last command wasn't a kill */
- X if ((lastflag&CFKILL) == 0)
- X kdelete();
- X thisflag |= CFKILL; /* this command is a kill */
- X
- X /* save the current cursor position */
- X dotp = curwp->w_dotp;
- X doto = curwp->w_doto;
- X
- X /* figure out how many characters to give the axe */
- X size = 0;
- X
- X /* get us into a word.... */
- X while (inword() == FALSE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return(FALSE);
- X ++size;
- X }
- X
- X if (n == 0) {
- X /* skip one word, no whitespace! */
- X while (inword() == TRUE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return(FALSE);
- X ++size;
- X }
- X } else {
- X /* skip n words.... */
- X while (n--) {
- X
- X /* if we are at EOL; skip to the beginning of the next */
- X while (curwp->w_doto == llength(curwp->w_dotp)) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return(FALSE);
- X ++size;
- X }
- X
- X /* move forward till we are at the end of the word */
- X while (inword() == TRUE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return(FALSE);
- X ++size;
- X }
- X
- X /* if there are more words, skip the interword stuff */
- X if (n != 0)
- X while (inword() == FALSE) {
- X if (forwchar(FALSE, 1) == FALSE)
- X return(FALSE);
- X ++size;
- X }
- X }
- X
- X /* skip whitespace and newlines */
- X while ((curwp->w_doto == llength(curwp->w_dotp)) ||
- X ((c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ') ||
- X (c == '\t')) {
- X if (forwchar(FALSE, 1) == FALSE)
- X break;
- X ++size;
- X }
- X }
- X
- X /* restore the original position and delete the words */
- X curwp->w_dotp = dotp;
- X curwp->w_doto = doto;
- X return (ldelete(size, TRUE));
- X}
- X
- X/*
- X * Kill backwards by "n" words. Move backwards by the desired number of words,
- X * counting the characters. When dot is finally moved to its resting place,
- X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
- X */
- Xdelbword(f, n)
- X{
- X long size;
- X
- X /* don't allow this command if we are in read only mode */
- X if (curbp->b_mode&MDVIEW)
- X return(rdonly());
- X
- X /* ignore the command if there is a nonpositive argument */
- X if (n <= 0)
- X return (FALSE);
- X
- X /* Clear the kill buffer if last command wasn't a kill */
- X if ((lastflag&CFKILL) == 0)
- X kdelete();
- X thisflag |= CFKILL; /* this command is a kill */
- X
- X if (backchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X size = 0;
- X while (n--) {
- X while (inword() == FALSE) {
- X if (backchar(FALSE, 1) == FALSE)
- X return (FALSE);
- X ++size;
- X }
- X while (inword() != FALSE) {
- X ++size;
- X if (backchar(FALSE, 1) == FALSE)
- X goto bckdel;
- X }
- X }
- X if (forwchar(FALSE, 1) == FALSE)
- X return (FALSE);
- Xbckdel: return (ldelete(size, TRUE));
- X}
- X
- X/*
- X * Return TRUE if the character at dot is a character that is considered to be
- X * part of a word. The word character list is hard coded. Should be setable.
- X */
- Xinword()
- X{
- X register int c;
- X
- X if (curwp->w_doto == llength(curwp->w_dotp))
- X return (FALSE);
- X c = lgetc(curwp->w_dotp, curwp->w_doto);
- X if (c>='a' && c<='z')
- X return (TRUE);
- X if (c>='A' && c<='Z')
- X return (TRUE);
- X if (c>='0' && c<='9')
- X return (TRUE);
- X return (FALSE);
- X}
- X
- X#if WORDPRO
- Xfillpara(f, n) /* Fill the current paragraph according to the current
- X fill column */
- X
- Xint f, n; /* deFault flag and Numeric argument */
- X
- X{
- X register int c; /* current char durring scan */
- X register int wordlen; /* length of current word */
- X register int clength; /* position on line during fill */
- X register int i; /* index during word copy */
- X register int newlength; /* tentative new line length */
- X register int eopflag; /* Are we at the End-Of-Paragraph? */
- X register int firstflag; /* first word? (needs no space) */
- X register LINE *eopline; /* pointer to line just past EOP */
- X register int dotflag; /* was the last char a period? */
- X char wbuf[NSTRING]; /* buffer for current word */
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if (fillcol == 0) { /* no fill column set */
- X mlwrite("No fill column set");
- X return(FALSE);
- X }
- X
- X /* record the pointer to the line just past the EOP */
- X gotoeop(FALSE, 1);
- X eopline = lforw(curwp->w_dotp);
- X
- X /* and back top the beginning of the paragraph */
- X gotobop(FALSE, 1);
- X
- X /* initialize various info */
- X clength = curwp->w_doto;
- X if (clength && curwp->w_dotp->l_text[0] == TAB)
- X clength = 8;
- X wordlen = 0;
- X dotflag = FALSE;
- X
- X /* scan through lines, filling words */
- X firstflag = TRUE;
- X eopflag = FALSE;
- X while (!eopflag) {
- X /* get the next character in the paragraph */
- X if (curwp->w_doto == llength(curwp->w_dotp)) {
- X c = ' ';
- X if (lforw(curwp->w_dotp) == eopline)
- X eopflag = TRUE;
- X } else
- X c = lgetc(curwp->w_dotp, curwp->w_doto);
- X
- X /* and then delete it */
- X ldelete(1L, FALSE);
- X
- X /* if not a separator, just add it in */
- X if (c != ' ' && c != '\t') {
- X dotflag = (c == '.'); /* was it a dot */
- X if (wordlen < NSTRING - 1)
- X wbuf[wordlen++] = c;
- X } else if (wordlen) {
- X /* at a word break with a word waiting */
- X /* calculate tentitive new length with word added */
- X newlength = clength + 1 + wordlen;
- X if (newlength <= fillcol) {
- X /* add word to current line */
- X if (!firstflag) {
- X linsert(1, ' '); /* the space */
- X ++clength;
- X }
- X firstflag = FALSE;
- X } else {
- X /* start a new line */
- X lnewline();
- X clength = 0;
- X }
- X
- X /* and add the word in in either case */
- X for (i=0; i<wordlen; i++) {
- X linsert(1, wbuf[i]);
- X ++clength;
- X }
- X if (dotflag) {
- X linsert(1, ' ');
- X ++clength;
- X }
- X wordlen = 0;
- X }
- X }
- X /* and add a last newline for the end of our new paragraph */
- X lnewline();
- X return(TRUE);
- X}
- X
- Xkillpara(f, n) /* delete n paragraphs starting with the current one */
- X
- Xint f; /* default flag */
- Xint n; /* # of paras to delete */
- X
- X{
- X register int status; /* returned status of functions */
- X
- X while (n--) { /* for each paragraph to delete */
- X
- X /* mark out the end and beginning of the para to delete */
- X gotoeop(FALSE, 1);
- X
- X /* set the mark here */
- X curwp->w_markp = curwp->w_dotp;
- X curwp->w_marko = curwp->w_doto;
- X
- X /* go to the beginning of the paragraph */
- X gotobop(FALSE, 1);
- X curwp->w_doto = 0; /* force us to the beginning of line */
- X
- X /* and delete it */
- X if ((status = killregion(FALSE, 1)) != TRUE)
- X return(status);
- X
- X /* and clean up the 2 extra lines */
- X ldelete(2L, TRUE);
- X }
- X return(TRUE);
- X}
- X
- X
- X/* wordcount: count the # of words in the marked region,
- X along with average word sizes, # of chars, etc,
- X and report on them. */
- X
- Xwordcount(f, n)
- X
- Xint f, n; /* ignored numeric arguments */
- X
- X{
- X register LINE *lp; /* current line to scan */
- X register int offset; /* current char to scan */
- X long size; /* size of region left to count */
- X register int ch; /* current character to scan */
- X register int wordflag; /* are we in a word now? */
- X register int lastword; /* were we just in a word? */
- X long nwords; /* total # of words */
- X long nchars; /* total number of chars */
- X int nlines; /* total number of lines in region */
- X int avgch; /* average number of chars/word */
- X int status; /* status return code */
- X REGION region; /* region to look at */
- X
- X /* make sure we have a region to count */
- X if ((status = getregion(®ion)) != TRUE)
- X return(status);
- X lp = region.r_linep;
- X offset = region.r_offset;
- X size = region.r_size;
- X
- X /* count up things */
- X lastword = FALSE;
- X nchars = 0L;
- X nwords = 0L;
- X nlines = 0;
- X while (size--) {
- X
- X /* get the current character */
- X if (offset == llength(lp)) { /* end of line */
- X ch = '\n';
- X lp = lforw(lp);
- X offset = 0;
- X ++nlines;
- X } else {
- X ch = lgetc(lp, offset);
- X ++offset;
- X }
- X
- X /* and tabulate it */
- X wordflag = ((ch >= 'a' && ch <= 'z') ||
- X (ch >= 'A' && ch <= 'Z') ||
- X (ch >= '0' && ch <= '9'));
- X if (wordflag == TRUE && lastword == FALSE)
- X ++nwords;
- X lastword = wordflag;
- X ++nchars;
- X }
- X
- X /* and report on the info */
- X if (nwords > 0L)
- X avgch = (int)((100L * nchars) / nwords);
- X else
- X avgch = 0;
- X
- X mlwrite("Words %D Chars %D Lines %d Avg chars/word %f",
- X nwords, nchars, nlines + 1, avgch);
- X return(TRUE);
- X}
- X#endif
- FRIDAY_NIGHT
- echo mes.13 completed!
- # That's all folks!
-
-
-