/* * 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; }
/* * 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; }
/* * 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), ' ')); }
/* * 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); }
/* * 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); }
/* * 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 }
/* * 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); }
/* * 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); }
/* * 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; }
/* * 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; }
// 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" }
/* * 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; }
/* * 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 */ }
// 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; } }