Example #1
0
/*
 * Implements the vi "k" command.
 *
 * This function is like "forwline", but goes backwards.
 */
int
backline(int f, int n)
{
    int rc;
    LINE *dlp;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = forwline(f, -n);
    } else if (is_first_line(DOT, curbp)) {
	/* cannot move up */
	rc = FALSE;
    } else {
	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	/* loop upwards */
	dlp = DOT.l;
	while (n-- && lback(dlp) != buf_head(curbp))
	    dlp = lback(dlp);

	/* set dot */
	DOT.l = dlp;
	DOT.o = getgoal(dlp);
	curwp->w_flag |= WFMOVE;
	rc = TRUE;
    }
    return rc;
}
Example #2
0
/*
 * Move forward n rows on the screen, staying in the same column.  It's ok to
 * scroll, too.
 */
int
forw_row(int f, int n)
{
    int code = TRUE;
    int col, next;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	code = back_row(f, -n);
    } else if (n > 0) {

	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	col = curgoal;
	next = col;

	while ((n-- > 0) && (code == TRUE)) {
	    int save = next;
	    next += term.cols;
	    if (gotocol(TRUE, next + 1) == FALSE) {
		curgoal %= term.cols;
		gotocol(TRUE, save);
		code = forwline(TRUE, 1);
	    } else {
		curgoal = next;
	    }
	}
    }
    return code;
}
Example #3
0
/*
 * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
 * tab into file.  If given argument, n, of zero, change to true tabs.
 * If n > 1, simulate tab stop every n-characters using spaces. This has to be
 * done in this slightly funny way because the tab (in ASCII) has been turned
 * into "C-I" (in 10 bit code) already. Bound to "C-I".
 */
int
tab(int f, int n)
{
    if (n < 0)
      return (FALSE);

    if (n == 0 || n > 1) {
	tabsize = n;
	return(TRUE);
    }

    if (! tabsize)
      return(linsert(1, '\t'));

    return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
}
Example #4
0
File: basic.c Project: aksr/esnc
/*
 * This function is like "forwline", but goes backwards. The scheme is exactly
 * the same. Check for arguments that are less than zero and call your
 * alternate. Figure out the new line and call "movedot" to perform the
 * motion. No errors are possible. Bound to "C-P".
 */
int backline (int f, int n)
{
  LINE *dlp;

  if (n < 0)
    return (forwline (f, -n));
  if ((lastflag & CFCPCN) == 0)/* Reset goal if the */
    curgoal = getccol (FALSE); /* last isn't C-P, C-N */
  thisflag |= CFCPCN;
  dlp = curwp->w_dotp;
  while (n-- && lback (dlp) != curbp->b_linep)
    dlp = lback (dlp);
  curwp->w_dotp = dlp;
  curwp->w_doto = getgoal (dlp);
  curwp->w_flag |= WFMOVE;
  return (TRUE);
}
Example #5
0
File: basic.c Project: aksr/esnc
/*
 * Move forward by full lines. If the number of lines to move is less than
 * zero, call the backward line function to actually do it. The last command
 * controls how the goal column is set. Bound to "C-N". No errors are possible.
 */
int forwline (int f, int n)
{
  LINE *dlp;

  if (n < 0)
    return (backline (f, -n));
  if ((lastflag & CFCPCN) == 0)/* Reset goal if last */
    curgoal = getccol (FALSE); /* not C-P or C-N */
  thisflag |= CFCPCN;
  dlp = curwp->w_dotp;
  while (n-- && dlp != curbp->b_linep)
    dlp = lforw (dlp);
  curwp->w_dotp = dlp;
  curwp->w_doto = getgoal (dlp);
  curwp->w_flag |= WFMOVE;
  return (TRUE);
}
Example #6
0
/*
 * This function is like "forwline", but goes backwards. The scheme is exactly
 * the same. Check for arguments that are less than zero and call your
 * alternate. Figure out the new line and call "movedot" to perform the
 * motion. No errors are possible. Bound to "C-P".
 * If raw is TRUE then enter folds, else skip them. MJB: 13-Oct-89
 */
PASCAL NEAR backline(
  int f,
  int n,
  int raw )	/* argument falg and num */

{
        register LINE   *dlp;

        if (n < 0)
                return(forwline(f, -n, raw));


	/* if we are on the last line as we start....fail the command */
	if (lback(curwp->w_dotp) == curbp->b_linep)
		return(FALSE);

	/* if the last command was not note a line move,
	   reset the goal column */
        if ((lastflag&CFCPCN) == 0)
                curgoal = getccol(FALSE);

	/* flag this command as a line move */
        thisflag |= CFCPCN;

	/* and move the point up */
        dlp = curwp->w_dotp;
        while (n-- && lback(dlp)!=curbp->b_linep)
		if (raw) /* raw mode */
			dlp = dlp->l_bp;
		else   /* it's cooked */
	                dlp = lback(dlp);

	/* reseting the current position */
        curwp->w_dotp  = dlp;
        curwp->w_doto  = getgoal(dlp);
        curwp->w_flag |= WFMOVE;

	if (raw) /* may have entered folds */
		openoutfolds();

#if	DBCS
	return(stopback());
#else
        return(TRUE);
#endif
}
Example #7
0
/*
 * 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.
 */
globle int execute(
  void *theEnv,
  int c,
  int f,
  int 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)(theEnv,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(theEnv);

        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(theEnv,n, c);
                lastflag = thisflag;
                return (status);
        }
        lastflag = 0;                           /* Fake last flags.     */
        return (FALSE);
}
Example #8
0
/*
 * Display the current position of the cursor, in origin 1 X-Y coordinates,
 * the character that is under the cursor (in hex), and the fraction of the
 * text that is before the cursor. The displayed column is not the current
 * column, but the column that would be used on an infinite width display.
 * Normally this is bound to "C-X ="
 */
int showcpos (int f, int n)
{
  LINE *clp;
  long nch, nbc;
  int cbo, cac, ratio, col;

  clp = lforw (curbp->b_linep);	/* Grovel the data */
  cbo = 0;
  nch = 0;
  nbc = 0;
  cac = 0;
  for (;;)
    {
      if (clp == curwp->w_dotp && cbo == curwp->w_doto)
	{
	  nbc = nch;
	  if (cbo == llength (clp))
	    cac = '\n';
	  else
	    cac = lgetc (clp, cbo);
	}
      if (cbo == llength (clp))
	{
	  if (clp == curbp->b_linep)
	    break;
	  clp = lforw (clp);
	  cbo = 0;
	}
      else
	++cbo;
      ++nch;
    }
  col = getccol (FALSE);       /* Get real column */
  ratio = 0;		       /* Ratio before dot */
  if (nch != 0)
    ratio = (100L * nbc) / nch;
  mlwrite ("Char: %c (0%o, %d, 0x%x)  point=%D of %D(%d%%) column %d",
	   ((cac > 31) && (cac < 128) ? cac : 32),
	   cac, cac, cac, nbc + 1, nch, ratio, col);
  return (TRUE);
}
Example #9
0
/*
 * Implements the vi "j" command.
 *
 * Move forward by full lines. If the number of lines to move is less than
 * zero, call the backward line function to actually do it. The last command
 * controls how the goal column is set.
 */
int
forwline(int f, int n)
{
    int rc;
    LINE *dlp;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = backline(f, -n);
    } else if (n == 0) {
	rc = TRUE;
    } else {

	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	/* loop downwards */
	dlp = DOT.l;
	rc = TRUE;
	do {
	    LINE *nlp = lforw(dlp);
	    if (nlp == buf_head(curbp)) {
		rc = FALSE;
		break;
	    }
	    dlp = nlp;
	} while (--n != 0);

	if (rc) {
	    /* set dot */
	    DOT.l = dlp;
	    DOT.o = getgoal(dlp);
	    curwp->w_flag |= WFMOVE;
	}
    }
    return rc;
}
Example #10
0
/*
 * Move back n rows on the screen, staying in the same column.  It's ok to
 * scroll, too.
 */
int
back_row(int f, int n)
{
    int code = TRUE;
    int col, next;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	code = forw_row(f, -n);
    } else if (n > 0) {

	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	col = curgoal;
	next = col;

	while ((n-- > 0) && (code == TRUE)) {
	    next -= term.cols;
	    if (next < 0) {
		if ((code = backline(TRUE, 1)) == TRUE
		    && llength(DOT.l) >= curgoal) {
		    next = llength(DOT.l) / term.cols;
		    next = (next * term.cols) + curgoal;
		    curgoal = next;
		}
	    } else {
		if ((code = gotocol(TRUE, next + 1)) == TRUE)
		    curgoal = next;
	    }
	}
    }
    return code;
}
Example #11
0
// If default n, display the current line, column, and character position of the cursor in the current buffer, the fraction of
// the text that is before the cursor, and the character that is under the cursor (in printable form and hex).  If n is not the
// default, display the cursor column and the character under the cursor only.  The displayed column is not the current column,
// but the column on an infinite-width display.  (Interactive only)
int whence(Value *rp,int n) {
	Line *lnp;			// Current line.
	ulong numchars;			// # of chars in file.
	ulong numlines;			// # of lines in file.
	ulong predchars;		// # chars preceding point.
	ulong predlines;		// # lines preceding point.
	int curchar;			// Character under cursor.
	double ratio;
	int col;
	int savepos;			// Temp save for current offset.
	int ecol;			// Column pos/end of current line.
	Dot *dotp = &curwp->w_face.wf_dot;
	char *strp,wkbuf1[32],wkbuf2[32];

	// Skip this if not displaying messages.
	if(!(modetab[MDR_GLOBAL].flags & MDMSG))
		return rc.status;

	if(n == INT_MIN) {

		// Starting at the beginning of the buffer.
		lnp = lforw(curbp->b_hdrlnp);
		curchar = '\n';

		// Start counting chars and lines.
		numchars = numlines = 0;
		while(lnp != curbp->b_hdrlnp) {

			// If we are on the current line, record it.
			if(lnp == dotp->lnp) {
				predlines = numlines;
				predchars = numchars + dotp->off;
				curchar = (dotp->off == lused(lnp)) ? '\n' : lgetc(lnp,dotp->off);
				}

			// On to the next line.
			++numlines;
			numchars += lused(lnp) + 1;
			lnp = lforw(lnp);
			}

		// If dot is at end of buffer, record it.
		if(dotp->lnp == curbp->b_hdrlnp) {
			predlines = numlines;
			predchars = numchars;
			}

		ratio = 0.0;				// Ratio before dot.
		if(numchars > 0)
			ratio = (double) predchars / numchars * 100.0;
		sprintf(strp = wkbuf2,"%.1f",ratio);
		if(numchars > 0) {

			// Fix rounding errors at buffer boundaries.
			if(predchars > 0 && strcmp(strp,"0.0") == 0)
				strp = "0.1";
			else if(predchars < numchars && strcmp(strp,"100.0") == 0)
				strp = "99.9";
			}
		}
	else
		curchar = (dotp->off == lused(dotp->lnp)) ? '\n' : lgetc(dotp->lnp,dotp->off);

	// Get real column and end-of-line column.
	col = getccol();
	savepos = dotp->off;
	dotp->off = lused(dotp->lnp);
	ecol = getccol();
	dotp->off = savepos;

	// Summarize and report the info.
	if(curchar >= ' ' && curchar < 0x7f)
		sprintf(wkbuf1,"'%c' 0x%.2X",curchar,curchar);
	else
		sprintf(wkbuf1,"0x%.2X",curchar);
	return (n == INT_MIN) ? rcset(SUCCESS,0,text60,predlines + 1,numlines,col,ecol,predchars,numchars,strp,wkbuf1) :
					// "Line %lu/%lu, Col %d/%d, Char %lu/%lu (%s%%), char = %s"
	 rcset(SUCCESS,0,text340,col,ecol,wkbuf1);
		// "Col %d/%d, char = %s"
	}
Example #12
0
/*
 * 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.
 */
int execute(int c, int f, int n)
{
	int status;
	fn_t execfunc;

	/* if the keystroke is a bound function...do it */
	execfunc = getbind(c);
	if (execfunc != NULL) {
		thisflag = 0;
		status = (*execfunc) (f, n);
		lastflag = thisflag;
		return status;
	}

	/*
	 * If a space was typed, fill column is defined, the argument is non-
	 * negative, wrap mode is enabled, and we are now past fill column,
	 * and we are not read-only, perform word wrap.
	 */
	if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 &&
	    n >= 0 && getccol(FALSE) > fillcol &&
	    (curwp->w_bufp->b_mode & MDVIEW) == FALSE)
		execute(META | SPEC | 'W', FALSE, 1);

#if	PKCODE
	if ((c >= 0x20 && c <= 0x7E)	/* Self inserting.      */
#if	IBMPC
	    || (c >= 0x80 && c <= 0xFE)) {
#else
#if	VMS || BSD || USG	/* 8BIT P.K. */
	    || (c >= 0xA0 && c <= 0xFFFF)) {
#else
	    ) {
#endif
#endif
#else
	if ((c >= 0x20 && c <= 0xFF)) {	/* Self inserting.      */
#endif
		if (n <= 0) {	/* Fenceposts.          */
			lastflag = 0;
			return n < 0 ? FALSE : TRUE;
		}
		thisflag = 0;	/* For the future.      */

		/* if we are in overwrite mode, not at eol,
		   and next char is not a tab or we are at a tab stop,
		   delete a char forword                        */
		if (curwp->w_bufp->b_mode & MDOVER &&
		    curwp->w_doto < curwp->w_dotp->l_used &&
		    (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
		     (curwp->w_doto) % 8 == 7))
			ldelchar(1, FALSE);

		/* do the appropriate insertion */
		if (c == '}' && (curbp->b_mode & MDCMOD) != 0)
			status = insbrace(n, c);
		else if (c == '#' && (curbp->b_mode & MDCMOD) != 0)
			status = inspound();
		else
			status = linsert(n, c);

#if	CFENCE
		/* check for CMODE fence matching */
		if ((c == '}' || c == ')' || c == ']') &&
		    (curbp->b_mode & MDCMOD) != 0)
			fmatch(c);
#endif

		/* check auto-save mode */
		if (curbp->b_mode & MDASAVE)
			if (--gacount == 0) {
				/* and save the file if needed */
				upscreen(FALSE, 0);
				filesave(FALSE, 0);
				gacount = gasave;
			}

		lastflag = thisflag;
		return status;
	}
	TTbeep();
	mlwrite("(Key not bound)");	/* complain             */
	lastflag = 0;		/* Fake last flags.     */
	return FALSE;
}

/*
 * Fancy quit command, as implemented by Norm. If the any buffer has
 * changed do a write on that buffer and exit emacs, otherwise simply exit.
 */
int quickexit(int f, int n)
{
	struct buffer *bp;	/* scanning pointer to buffers */
	struct buffer *oldcb;	/* original current buffer */
	int status;

	oldcb = curbp;		/* save in case we fail */

	bp = bheadp;
	while (bp != NULL) {
		if ((bp->b_flag & BFCHG) != 0	/* Changed.             */
		    && (bp->b_flag & BFTRUNC) == 0	/* Not truncated P.K.   */
		    && (bp->b_flag & BFINVS) == 0) {	/* Real.                */
			curbp = bp;	/* make that buffer cur */
			mlwrite("(Saving %s)", bp->b_fname);
#if	PKCODE
#else
			mlwrite("\n");
#endif
			if ((status = filesave(f, n)) != TRUE) {
				curbp = oldcb;	/* restore curbp */
				return status;
			}
		}
		bp = bp->b_bufp;	/* on to the next buffer */
	}
	quit(f, n);		/* conditionally quit   */
	return TRUE;
}

static void emergencyexit(int signr)
{
	quickexit(FALSE, 0);
	quit(TRUE, 0);
}

/*
 * 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".
 */
int quit(int f, int n)
{
	int s;

	if (f != FALSE		/* Argument forces it.  */
	    || anycb() == FALSE	/* All buffers clean.   */
	    /* User says it's OK.   */
	    || (s =
		mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
#if	(FILOCK && BSD) || SVR4
		if (lockrel() != TRUE) {
			TTputc('\n');
			TTputc('\r');
			TTclose();
			TTkclose();
			exit(1);
		}
#endif
		vttidy();
		if (f)
			exit(n);
		else
			exit(GOOD);
	}
	mlwrite("");
	return s;
}

/*
 * Begin a keyboard macro.
 * Error if not at the top level in keyboard processing. Set up variables and
 * return.
 */
int ctlxlp(int f, int n)
{
	if (kbdmode != STOP) {
		mlwrite("%%Macro already active");
		return FALSE;
	}
	mlwrite("(Start macro)");
	kbdptr = &kbdm[0];
	kbdend = kbdptr;
	kbdmode = RECORD;
	return TRUE;
}

/*
 * End keyboard macro. Check for the same limit conditions as the above
 * routine. Set up the variables and return to the caller.
 */
int ctlxrp(int f, int n)
{
	if (kbdmode == STOP) {
		mlwrite("%%Macro not active");
		return FALSE;
	}
	if (kbdmode == RECORD) {
		mlwrite("(End macro)");
		kbdmode = STOP;
	}
	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.
 */
int ctlxe(int f, int n)
{
	if (kbdmode != STOP) {
		mlwrite("%%Macro already active");
		return FALSE;
	}
	if (n <= 0)
		return TRUE;
	kbdrep = n;		/* remember how many times to execute */
	kbdmode = PLAY;		/* start us in play mode */
	kbdptr = &kbdm[0];	/*    at the beginning */
	return TRUE;
}

/*
 * 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.
 */
int ctrlg(int f, int n)
{
	TTbeep();
	kbdmode = STOP;
	mlwrite("(Aborted)");
	return ABORT;
}
Example #13
0
/*
 * gtenv()
 *
 * char *vname;			name of environment variable to retrieve
 */
char *gtenv(char *vname)
{
	int vnum;	/* ordinal number of var refrenced */

	/* scan the list, looking for the referenced name */
	for (vnum = 0; vnum < ARRAY_SIZE(envars); vnum++)
		if (strcmp(vname, envars[vnum]) == 0)
			break;

	/* return errorm on a bad reference */
	if (vnum == ARRAY_SIZE(envars))
#if	ENVFUNC
	{
		char *ename = getenv(vname);

		if (ename != NULL)
			return ename;
		else
			return errorm;
	}
#else
		return errorm;
#endif

	/* otherwise, fetch the appropriate value */
	switch (vnum) {
	case EVFILLCOL:
		return itoa(fillcol);
	case EVPAGELEN:
		return itoa(term.t_nrow + 1);
	case EVCURCOL:
		return itoa(getccol(FALSE));
	case EVCURLINE:
		return itoa(getcline());
	case EVRAM:
		return itoa((int) (envram / 1024l));
	case EVFLICKER:
		return ltos(flickcode);
	case EVCURWIDTH:
		return itoa(term.t_ncol);
	case EVCBUFNAME:
		return curbp->b_bname;
	case EVCFNAME:
		return curbp->b_fname;
	case EVSRES:
		return sres;
	case EVDEBUG:
		return ltos(macbug);
	case EVSTATUS:
		return ltos(cmdstatus);
	case EVPALETTE:
		return palstr;
	case EVASAVE:
		return itoa(gasave);
	case EVACOUNT:
		return itoa(gacount);
	case EVLASTKEY:
		return itoa(lastkey);
	case EVCURCHAR:
		return (curwp->w_dotp->l_used ==
			curwp->w_doto ? itoa('\n') :
			itoa(lgetc(curwp->w_dotp, curwp->w_doto)));
	case EVDISCMD:
		return ltos(discmd);
	case EVVERSION:
		return VERSION;
	case EVPROGNAME:
		return PROGRAM_NAME_LONG;
	case EVSEED:
		return itoa(seed);
	case EVDISINP:
		return ltos(disinp);
	case EVWLINE:
		return itoa(curwp->w_ntrows);
	case EVCWLINE:
		return itoa(getwpos());
	case EVTARGET:
		saveflag = lastflag;
		return itoa(curgoal);
	case EVSEARCH:
		return pat;
	case EVREPLACE:
		return rpat;
	case EVMATCH:
		return (patmatch == NULL) ? "" : patmatch;
	case EVKILL:
		return getkill();
	case EVCMODE:
		return itoa(curbp->b_mode);
	case EVGMODE:
		return itoa(gmode);
	case EVTPAUSE:
		return itoa(term.t_pause);
	case EVPENDING:
#if	TYPEAH
		return ltos(typahead());
#else
		return falsem;
#endif
	case EVLWIDTH:
		return itoa(llength(curwp->w_dotp));
	case EVLINE:
		return getctext();
	case EVGFLAGS:
		return itoa(gflags);
	case EVRVAL:
		return itoa(rval);
	case EVTAB:
		return itoa(tabmask + 1);
	case EVOVERLAP:
		return itoa(overlap);
	case EVSCROLLCOUNT:
		return itoa(scrollcount);
#if SCROLLCODE
	case EVSCROLL:
		return ltos(term.t_scroll != NULL);
#else
	case EVSCROLL:
		return ltos(0);
#endif
	}
	exit(-12);		/* again, we should never get here */
}
Example #14
0
// Redisplay the mode line for the window pointed to by winp.  If popbuf is NULL, display a fully-formatted mode line containing
// the current buffer's name and filename (but in condensed form if the current terminal width is less than 96 columns);
// otherwise, display only the buffer name and filename of buffer "popbuf".  This is the only routine that has any idea of how
// the mode line is formatted.  You can change the mode line format by hacking at this routine.  Called by "update" any time
// there is a dirty window.
void wupd_modeline(EWindow *winp,Buffer *popbuf) {
	int c;
	int n;				// Cursor position.
	Buffer *bufp;
	ModeSpec *msp;
	int lchar;
	int condensed = term.t_ncol < 80 ? -1 : term.t_ncol < 96 ? 1 : 0;
	char wkbuf[32];			// Work buffer.
	static struct {			// Mode display parameters.
		int leadch,trailch;
		uint flags;
		} *mdp,md[] = {
			{'(',')',0},
			{'[',']',0},
			{-1,-1,0}};

	n = winp->w_toprow + winp->w_nrows;		// Row location.

	// Note that we assume that setting REVERSE will cause the terminal driver to draw with the inverted relationship of
	// fcolor and bcolor, so that when we say to set the foreground color to "white" and background color to "black", the
	// fact that "reverse" is enabled means that the terminal driver actually draws "black" on a background of "white".
	// Makes sense, no?  This way, devices for which the color controls are optional will still get the "reverse" signals.
	vscreen[n]->v_left = 0;
	vscreen[n]->v_right = term.t_ncol;
#if COLOR
	vscreen[n]->v_flags |= VFCHGD | VFCOLOR;	// Redraw next time.
	vscreen[n]->v_rfcolor = 7;			// Black on.
	vscreen[n]->v_rbcolor = 0;			// White...
#else
	vscreen[n]->v_flags |= VFCHGD;			// Redraw next time.
#endif
	vtmove(n,0);					// Seek to right line.
	if(winp == curwp)				// Make the current buffer stand out.
		lchar = '=';
#if REVSTA
	else if(opflags & OPHAVEREV)
		lchar = ' ';
#endif
	else
		lchar = '-';

	// Full display?
	if(popbuf == NULL) {
		bufp = winp->w_bufp;
		vtputc((bufp->b_flags & BFTRUNC) ? '#' : lchar);	// "#" if truncated.
		vtputc((bufp->b_flags & BFCHGD) ? '*' : lchar);		// "*" if changed.
		vtputc((bufp->b_flags & BFNARROW) ? '<' : lchar);	// "<" if narrowed.
		vtputc(' ');
		n = 4;

		// Display program name and version.
		if(!condensed) {
			sprintf(wkbuf,"%s %s ",Myself,Version);
			n += vtputs(wkbuf);
			}

		// Are we horizontally scrolled?
		if(winp->w_face.wf_fcol > 0) {
			sprintf(wkbuf,"[<%d] ",winp->w_face.wf_fcol);
			n += vtputs(wkbuf);
			}

		// Display the screen number if bottom window and there's more than one screen.
		if(winp->w_nextp == NULL && scrcount() > 1) {
			sprintf(wkbuf,"S%hu ",cursp->s_num);
			n += vtputs(wkbuf);
			}

		// Display keyboard macro recording state.
		if(kmacro.km_state == KMRECORD)
			n += vtputs("*R* ");

		// Display the line and/or column point position if enabled and winp is current window.
		if(winp == curwp) {
			if(curbp->b_modes & MDLINE) {
				sprintf(wkbuf,"L:%ld ",getlinenum(bufp,winp->w_face.wf_dot.lnp));
				n += vtputs(wkbuf);
				}
			if(curbp->b_modes & MDCOL) {
				sprintf(wkbuf,"C:%d ",getccol());
				n += vtputs(wkbuf);
				}
			}

		// Display the modes, in short form if condensed display.
		md[0].flags = modetab[MDR_GLOBAL].flags & modetab[MDR_SHOW].flags;
		md[1].flags = winp->w_bufp->b_modes;
		mdp = md;
		do {
			msp = ((c = mdp->leadch) == '[') ? bmodeinfo : gmodeinfo;
			do {
				if(mdp->flags & msp->mask) {
					n += vtputc(c);
					c = ' ';
					if(condensed >= 0)
						n += vtputs(msp->mlname);
					else {
						n += vtputc(msp->mlname[0]);
						if(msp->mlname[1] != '\0')
							n += vtputc(msp->mlname[1]);
						}
					}
				} while((++msp)->name != NULL);
			if(c != mdp->leadch) {
				n += vtputc(mdp->trailch);
				n += vtputc(' ');
				}
			} while((++mdp)->leadch > 0);
#if 0
		// Display internal modes on modeline.
		vtputc(lchar);
		vtputc((winp->w_flags & WFCOLOR) ? 'C' : lchar);
		vtputc((winp->w_flags & WFMODE) ? 'M' : lchar);
		vtputc((winp->w_flags & WFHARD) ? 'H' : lchar);
		vtputc((winp->w_flags & WFEDIT) ? 'E' : lchar);
		vtputc((winp->w_flags & WFMOVE) ? 'V' : lchar);
		vtputc((winp->w_flags & WFFORCE) ? 'F' : lchar);
		vtputc(lchar);
		n += 8;
#endif
		n += wupd_tab(lchar);
		}
	else {
		n = 0;
		bufp = popbuf;
		vtputc(lchar);
		n += wupd_tab(lchar) + 1;
		}

	// Display the buffer name.
	n += vtputs(bufp->b_bname) + 1;
	vtputc(' ');

	// Display the filename in the remaining space using strfit().
	if(bufp->b_fname != NULL) {
		char wkbuf[TT_MAXCOLS];

		n += wupd_tab(lchar);
		if(condensed < 0) {
			vtputc(*text34);
				// "File: "
			vtputc(':');
			vtputc(' ');
			n += 3;
			}
		else
			n += vtputs(text34);
				// "File: "
		n += vtputs(strfit(wkbuf,term.t_ncol - n - 1,bufp->b_fname,0)) + 1;
		vtputc(' ');
		}

	// If it's the current window, not a pop-up, "pwd" mode, and room still available, display the working directory as
	// well.
	if(winp == curwp && popbuf == NULL && (modetab[MDR_GLOBAL].flags & MDWKDIR) && ((int) term.t_ncol - n) > 12) {
		char *wdp;
		char wkbuf[TT_MAXCOLS];

		n += wupd_tab(lchar);
		n += vtputs(text274);
			// "WD: "
		(void) getwkdir(&wdp,false);
		n += vtputs(strfit(wkbuf,term.t_ncol - n - 1,wdp,0)) + 1;
		vtputc(' ');
		}

	// Pad to full width.
	while(n < (int) term.t_ncol) {
		vtputc(lchar);
		++n;
		}
	}