home *** CD-ROM | disk | FTP | other *** search
- /*
- * Library of display line routines.
- *
- * Robert W. Baldwin, December 1984.
- */
-
- #include <stdio.h>
- #include "window.h"
- #include "specs.h"
-
-
- /* After clrdline is called the routines assume that there is
- * a null character terminating the string at index w->wwidth.
- * That is, the length of the display string is always equal
- * the the (fixed) width of the line.
- * The dl_length field behaves like the apparent string length.
- * It is the column location of the last non-blank character.
- * That is, an all blank line has a length of zero.
- */
-
- /* INTERNAL PROCEDURES */
-
- /* Set the range of positions between firstcol and lastcol (inclusive) to
- * the given string. The string is padded on the right with spaces
- * or truncated to make it fill the interval.
- */
- setarange(line, str, firstcol, lastcol)
- displine *line;
- char *str;
- int firstcol, lastcol;
- {
- int i;
-
- line->dl_length = 0;
- for (i = firstcol-1 ; i < lastcol ; i++) {
- if (*str == 0) break;
- if (*str != ' ') line->dl_length = i+1;
- line->dl_chars[i] = *str++;
- }
-
- for ( ; i < lastcol ; i++) {
- line->dl_chars[i] = ' ';
- }
-
- line->dl_chars[i] = '\000';
- }
-
-
-
- /* PUBLIC PROCEDURES */
-
-
-
- /* Set the line from column, col, onward to the given string,
- * padding with blanks if needed. Note col = 1, set the whole line.
- * This cannot be used to initialize a display line. It does not
- * set the character preceeding col.
- */
- setnadline(line, str, col)
- displine *line;
- char *str;
- int col;
- {
- setarange(line, str, col, line->wwidth);
- }
-
-
- /* Blank out all the characters in a displine.
- */
- clrdline(line)
- displine *line;
- {
- line->dl_length = 0;
- setarange(line, "", 1, line->wwidth);
- }
-
-
- /* Set the entire displine to the given string, padding with blanks.
- * This fills in the null termination, so it can be used to initialize
- * a display line.
- */
- setadline(line, str)
- displine *line;
- char *str;
- {
- line->dl_length = 0;
- setarange(line, str, 1, line->wwidth);
- }
-
-
- /* Set characters in the given range to the string, truncating
- * if necessary. Do not pad with blanks, just avoid overflowing
- * the range.
- */
- setrange(line, str, firstcol, lastcol)
- displine *line;
- char *str;
- int firstcol, lastcol; /* Inclusive interval. */
- {
- int i;
- int newlength;
-
- newlength = 0;
- for (i = firstcol-1 ; i < lastcol ; i++) {
- if (*str == 0) return;
- if (*str != ' ') newlength = i+1;
- line->dl_chars[i] = *str++;
- }
-
- if (newlength > line->dl_length) line->dl_length = newlength;
- }
-
-
-
- /* Starting at column, col, set the characters in the display line, line,
- * to the given string, str.
- * This differs from setnadline because it does not pad the line with blanks.
- * Overflows are avoided by truncation.
- * Note that col is a one-based position, not zero-based as strings are.
- * This cannot be used to initialize a line, since it does not set the
- * characters before column col.
- */
- setndline(line, str, col)
- displine *line;
- char *str;
- int col;
- {
- setrange(line, str, col, line->wwidth);
- }
-
-
- /* Set the variable part of the line (between min and max_col) to
- * the given string. Pad with blanks.
- */
- dlsetvar(line, str)
- displine *line;
- char *str;
- {
- setarange(line, str, line->dl_min_col, line->dl_max_col);
- }
-
-
-
- /* Fill the given buffer from the given range of column positions.
- * Trailing blanks are not removed.
- */
- getrange(line, buf, firstcol, lastcol)
- displine *line;
- char *buf;
- int firstcol, lastcol;
- {
- int i;
-
- for (i = firstcol-1 ; i < lastcol ; i++) {
- *buf++ = line->dl_chars[i];
- }
- *buf = '\000';
- }
-
-
- /* Fill the given character buffer with a null terminated string
- * corresponding to the part of the dline between the min and max
- * column positions. Trailing blanks are not removed.
- */
- dlgetvar(line, buf)
- displine *line;
- char *buf;
- {
- getrange(line, buf, line->dl_min_col, line->dl_max_col);
- }
-
-
-
- /* EDITING PROCEDURES */
-
-
- /* Insert the given character at the current cursor position.
- * Do nothing if the line would become too long.
- * Do nothing if the character is not printable.
- * The cursor moves to the right one column, provided it doesn't
- * move past dl_max_col.
- */
- dlinsert(line, k)
- displine *line;
- key k;
- {
- char restbuf[MAXWIDTH+1]; /* Char from cursor to end. */
- char insbuf[2]; /* Char to insert. */
-
- if (line->dl_length >= line->wwidth) return;
- if (!printable(k)) return;
-
- getrange(line, restbuf, line->wcur_col, line->wwidth);
-
- insbuf[0] = k;
- insbuf[1] = '\000';
- setrange(line, insbuf, line->wcur_col, line->wcur_col);
-
- setrange(line, restbuf, line->wcur_col+1, line->wwidth);
-
- dlright(line);
- }
-
-
- /* Delete the character at the current cursor position and
- * shuffle down the rest of the line.
- * The cursor doesn't move.
- * The non-blank length is correctly maintained.
- */
- dldelete(line)
- displine *line;
- {
- char *p;
- char linebuf[MAXWIDTH+1]; /* Rebuild whole line here. */
-
- getrange(line, linebuf, 1, line->wcur_col-1);
-
- for (p = linebuf ; *p != '\000' ; p++); /* p pts to end of line. */
- getrange(line, p, line->wcur_col+1, line->wwidth);
-
- setadline(line, linebuf);
- }
-
-
- /* Move the cursor right within min and max column.
- */
- dlright(line)
- displine *line;
- {
- if (line->wcur_col+1 <= line->dl_max_col)
- line->wcur_col++;
- }
-
-
- /* Move the cursor left within min and max column.
- */
- dlleft(line)
- displine *line;
- {
- if (line->wcur_col-1 >= line->dl_min_col)
- line->wcur_col--;
- }
-
-
-
- /* DISPLAY UPDATING PROCEDURES */
-
-
- /* Redraw routine for a display line.
- */
- wl_dldraw(dline)
- displine *dline;
- {
- int oldcolumn;
-
- oldcolumn = dline->wcur_col;
-
- wl_setcur(dline, 1, 1);
- plstring(dline->dl_chars);
- wl_setcur(dline, 1, oldcolumn);
- }
-
-
- /* Insert a character an redisplay the line.
- */
- wl_dlinsert(line, k)
- displine *line;
- key k;
- {
- dlinsert(line, k);
- wl_dldraw(line);
- }
-
-
- /* Delete the current character an redisplay the line.
- */
- wl_dlfdel(line, k)
- displine *line;
- key k;
- {
- dldelete(line, k);
- wl_dldraw(line);
- }
-
-
- /* Delete the previous character an redisplay the line.
- * The cursor moves backwards one position.
- */
- wl_dlbdel(line, k)
- displine *line;
- key k;
- {
- if (line->wcur_col == line->dl_min_col) return;
-
- dlleft(line);
- dldelete(line, k);
- wl_dldraw(line);
- }
-
-
- /* Move cursor right and update display.
- */
- wl_dlright(line)
- displine *line;
- {
- dlright(line);
- wl_rcursor(line);
- }
-
-
- /* Move cursor left and update display.
- */
- wl_dlleft(line)
- displine *line;
- {
- dlleft(line);
- wl_rcursor(line);
- }
-
-
- /* Clear the variable part of the display line and update the display.
- */
- wl_dlclr(line)
- displine *line;
- {
- dlsetvar(line, "");
- line->wcur_col = line->dl_min_col;
- wl_dldraw(line);
- }
-
-
- /* Scan for the first argument place holder, '%',
- * position the cursor there, and delete it.
- * Do nothing if the line doesn't contain a '%'.
- */
- wl_nxtarg(line)
- displine *line;
- {
- int i;
-
- for (i = line->dl_min_col-1 ; i < line->dl_max_col ; i++) {
- if (line->dl_chars[i] != '%') continue;
- wl_setcur(line, 1, i+1);
- wl_dlfdel(line);
- break;
- }
- }
-