[BACK]Return to basic.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/basic.c, Revision 1.50

1.50    ! lum         1: /*     $OpenBSD: basic.c,v 1.49 2019/06/17 11:39:26 lum Exp $  */
1.19      kjell       2:
                      3: /* This file is in the public domain */
1.4       niklas      4:
1.1       deraadt     5: /*
                      6:  *             Basic cursor motion commands.
                      7:  *
                      8:  * The routines in this file are the basic
                      9:  * command functions for moving the cursor around on
                     10:  * the screen, setting mark, and swapping dot with
                     11:  * mark. Only moves between lines, which might make the
                     12:  * current buffer framing bad, are hard.
                     13:  */
                     14:
1.44      bcallah    15: #include <sys/queue.h>
1.14      vincent    16: #include <ctype.h>
1.43      guenther   17: #include <limits.h>
1.44      bcallah    18: #include <signal.h>
                     19: #include <stdio.h>
                     20: #include <stdlib.h>
                     21:
                     22: #include "def.h"
1.1       deraadt    23:
1.48      lum        24: #define percint(n1, n2)                ((n1 * (int) n2) * 0.1)
                     25:
1.1       deraadt    26: /*
                     27:  * Go to beginning of line.
                     28:  */
1.3       millert    29: /* ARGSUSED */
                     30: int
1.12      vincent    31: gotobol(int f, int n)
1.1       deraadt    32: {
1.47      lum        33:        if (n == 0)
                     34:                return (TRUE);
                     35:
1.3       millert    36:        curwp->w_doto = 0;
1.1       deraadt    37:        return (TRUE);
                     38: }
                     39:
                     40: /*
                     41:  * Move cursor backwards. Do the
                     42:  * right thing if the count is less than
                     43:  * 0. Error if you try to move back from
                     44:  * the beginning of the buffer.
                     45:  */
1.3       millert    46: /* ARGSUSED */
                     47: int
1.12      vincent    48: backchar(int f, int n)
1.1       deraadt    49: {
1.21      deraadt    50:        struct line   *lp;
1.1       deraadt    51:
1.3       millert    52:        if (n < 0)
1.18      db         53:                return (forwchar(f, -n));
1.1       deraadt    54:        while (n--) {
                     55:                if (curwp->w_doto == 0) {
1.25      kjell      56:                        if ((lp = lback(curwp->w_dotp)) == curbp->b_headp) {
1.50    ! lum        57:                                if (!(f & FFRAND))
        !            58:                                        (void)dobeep_msg("Beginning "
        !            59:                                            "of buffer");
1.1       deraadt    60:                                return (FALSE);
                     61:                        }
1.3       millert    62:                        curwp->w_dotp = lp;
                     63:                        curwp->w_doto = llength(lp);
1.30      kjell      64:                        curwp->w_rflag |= WFMOVE;
1.23      kjell      65:                        curwp->w_dotline--;
1.1       deraadt    66:                } else
                     67:                        curwp->w_doto--;
                     68:        }
1.18      db         69:        return (TRUE);
1.1       deraadt    70: }
                     71:
                     72: /*
                     73:  * Go to end of line.
                     74:  */
1.3       millert    75: /* ARGSUSED */
                     76: int
1.12      vincent    77: gotoeol(int f, int n)
1.1       deraadt    78: {
1.47      lum        79:        if (n == 0)
                     80:                return (TRUE);
                     81:
1.3       millert    82:        curwp->w_doto = llength(curwp->w_dotp);
1.1       deraadt    83:        return (TRUE);
                     84: }
                     85:
                     86: /*
                     87:  * Move cursor forwards. Do the
                     88:  * right thing if the count is less than
                     89:  * 0. Error if you try to move forward
                     90:  * from the end of the buffer.
                     91:  */
1.3       millert    92: /* ARGSUSED */
                     93: int
1.12      vincent    94: forwchar(int f, int n)
1.1       deraadt    95: {
1.3       millert    96:        if (n < 0)
1.18      db         97:                return (backchar(f, -n));
1.1       deraadt    98:        while (n--) {
                     99:                if (curwp->w_doto == llength(curwp->w_dotp)) {
1.3       millert   100:                        curwp->w_dotp = lforw(curwp->w_dotp);
1.25      kjell     101:                        if (curwp->w_dotp == curbp->b_headp) {
1.1       deraadt   102:                                curwp->w_dotp = lback(curwp->w_dotp);
1.50    ! lum       103:                                if (!(f & FFRAND))
        !           104:                                        (void)dobeep_msg("End of buffer");
1.18      db        105:                                return (FALSE);
1.1       deraadt   106:                        }
1.3       millert   107:                        curwp->w_doto = 0;
1.23      kjell     108:                        curwp->w_dotline++;
1.30      kjell     109:                        curwp->w_rflag |= WFMOVE;
1.1       deraadt   110:                } else
                    111:                        curwp->w_doto++;
                    112:        }
1.18      db        113:        return (TRUE);
1.1       deraadt   114: }
                    115:
                    116: /*
1.48      lum       117:  * Go to the beginning of the buffer. Setting WFFULL is conservative,
                    118:  * but almost always the case. A universal argument of higher than 9
                    119:  * puts the cursor back to the end of buffer.
1.1       deraadt   120:  */
1.3       millert   121: int
1.12      vincent   122: gotobob(int f, int n)
1.1       deraadt   123: {
1.49      lum       124:        if (!curwp->w_markp)
                    125:                (void) setmark(f, n);
1.26      kjell     126:        curwp->w_dotp = bfirstlp(curbp);
1.3       millert   127:        curwp->w_doto = 0;
1.30      kjell     128:        curwp->w_rflag |= WFFULL;
1.23      kjell     129:        curwp->w_dotline = 1;
1.48      lum       130:        if (f & FFOTHARG && n > 0) {
                    131:                if (n > 9)
                    132:                        gotoeob(0, 0);
                    133:                else
                    134:                        forwline(f, percint(curwp->w_bufp->b_lines, n) - 1);
                    135:        }
1.18      db        136:        return (TRUE);
1.1       deraadt   137: }
                    138:
                    139: /*
1.37      lum       140:  * Go to the end of the buffer. Leave dot 3 lines from the bottom of the
                    141:  * window if buffer length is longer than window length; same as emacs.
1.48      lum       142:  * Setting WFFULL is conservative, but almost always the case. A universal
                    143:  * argument of higher than 9 puts the cursor back to the start of buffer.
1.1       deraadt   144:  */
1.3       millert   145: int
1.12      vincent   146: gotoeob(int f, int n)
1.1       deraadt   147: {
1.48      lum       148:        int              ln;
1.37      lum       149:        struct line     *lp;
1.46      jasper    150:
1.49      lum       151:        if (!curwp->w_markp)
                    152:                (void) setmark(f, n);
1.26      kjell     153:        curwp->w_dotp = blastlp(curbp);
1.3       millert   154:        curwp->w_doto = llength(curwp->w_dotp);
1.23      kjell     155:        curwp->w_dotline = curwp->w_bufp->b_lines;
1.37      lum       156:
                    157:        lp = curwp->w_dotp;
1.48      lum       158:        ln = curwp->w_ntrows - 3;
1.37      lum       159:
1.48      lum       160:        if (ln < curwp->w_bufp->b_lines && ln >= 3) {
                    161:                while (ln--)
1.37      lum       162:                        curwp->w_dotp = lback(curwp->w_dotp);
                    163:
                    164:                curwp->w_linep = curwp->w_dotp;
                    165:                curwp->w_dotp = lp;
                    166:        }
1.48      lum       167:        if (f & FFOTHARG && n > 0) {
                    168:                if (n > 9)
                    169:                        gotobob(0, 0);
                    170:                else
                    171:                        backline(f, percint(curwp->w_bufp->b_lines, n));
                    172:        }
                    173:
1.30      kjell     174:        curwp->w_rflag |= WFFULL;
1.18      db        175:        return (TRUE);
1.1       deraadt   176: }
                    177:
                    178: /*
                    179:  * Move forward by full lines.
                    180:  * If the number of lines to move is less
                    181:  * than zero, call the backward line function to
                    182:  * actually do it. The last command controls how
                    183:  * the goal column is set.
                    184:  */
1.3       millert   185: /* ARGSUSED */
                    186: int
1.12      vincent   187: forwline(int f, int n)
1.1       deraadt   188: {
1.21      deraadt   189:        struct line  *dlp;
1.1       deraadt   190:
                    191:        if (n < 0)
1.18      db        192:                return (backline(f | FFRAND, -n));
1.41      florian   193:        if ((dlp = curwp->w_dotp) == curbp->b_headp) {
1.50    ! lum       194:                if (!(f & FFRAND))
        !           195:                        (void)dobeep_msg("End of buffer");
1.23      kjell     196:                return(TRUE);
1.41      florian   197:        }
1.14      vincent   198:        if ((lastflag & CFCPCN) == 0)   /* Fix goal. */
1.1       deraadt   199:                setgoal();
                    200:        thisflag |= CFCPCN;
1.3       millert   201:        if (n == 0)
1.18      db        202:                return (TRUE);
1.23      kjell     203:        while (n--) {
1.1       deraadt   204:                dlp = lforw(dlp);
1.25      kjell     205:                if (dlp == curbp->b_headp) {
1.23      kjell     206:                        curwp->w_dotp = lback(dlp);
                    207:                        curwp->w_doto = llength(curwp->w_dotp);
1.30      kjell     208:                        curwp->w_rflag |= WFMOVE;
1.50    ! lum       209:                        if (!(f & FFRAND))
        !           210:                                (void)dobeep_msg("End of buffer");
1.23      kjell     211:                        return (TRUE);
1.1       deraadt   212:                }
1.23      kjell     213:                curwp->w_dotline++;
1.1       deraadt   214:        }
1.30      kjell     215:        curwp->w_rflag |= WFMOVE;
1.23      kjell     216:        curwp->w_dotp = dlp;
                    217:        curwp->w_doto = getgoal(dlp);
                    218:
1.18      db        219:        return (TRUE);
1.1       deraadt   220: }
                    221:
                    222: /*
                    223:  * This function is like "forwline", but
                    224:  * goes backwards. The scheme is exactly the same.
                    225:  * Check for arguments that are less than zero and
                    226:  * call your alternate. Figure out the new line and
                    227:  * call "movedot" to perform the motion.
                    228:  */
1.3       millert   229: /* ARGSUSED */
                    230: int
1.12      vincent   231: backline(int f, int n)
1.1       deraadt   232: {
1.21      deraadt   233:        struct line   *dlp;
1.1       deraadt   234:
1.3       millert   235:        if (n < 0)
1.18      db        236:                return (forwline(f | FFRAND, -n));
1.14      vincent   237:        if ((lastflag & CFCPCN) == 0)   /* Fix goal. */
1.1       deraadt   238:                setgoal();
                    239:        thisflag |= CFCPCN;
                    240:        dlp = curwp->w_dotp;
1.41      florian   241:        if (lback(dlp) == curbp->b_headp)  {
1.50    ! lum       242:                if (!(f & FFRAND))
        !           243:                        (void)dobeep_msg("Beginning of buffer");
1.41      florian   244:                return(TRUE);
                    245:        }
1.25      kjell     246:        while (n-- && lback(dlp) != curbp->b_headp) {
1.1       deraadt   247:                dlp = lback(dlp);
1.23      kjell     248:                curwp->w_dotline--;
1.41      florian   249:        }
1.50    ! lum       250:        if (n > 0 && !(f & FFRAND))
        !           251:                (void)dobeep_msg("Beginning of buffer");
1.3       millert   252:        curwp->w_dotp = dlp;
                    253:        curwp->w_doto = getgoal(dlp);
1.30      kjell     254:        curwp->w_rflag |= WFMOVE;
1.18      db        255:        return (TRUE);
1.1       deraadt   256: }
                    257:
                    258: /*
1.3       millert   259:  * Set the current goal column, which is saved in the external variable
                    260:  * "curgoal", to the current cursor column. The column is never off
                    261:  * the edge of the screen; it's more like display then show position.
1.1       deraadt   262:  */
1.6       art       263: void
1.12      vincent   264: setgoal(void)
1.3       millert   265: {
1.39      florian   266:        curgoal = getcolpos(curwp);     /* Get the position. */
1.3       millert   267:        /* we can now display past end of display, don't chop! */
1.1       deraadt   268: }
                    269:
                    270: /*
                    271:  * This routine looks at a line (pointed
                    272:  * to by the LINE pointer "dlp") and the current
                    273:  * vertical motion goal column (set by the "setgoal"
                    274:  * routine above) and returns the best offset to use
                    275:  * when a vertical motion is made into the line.
                    276:  */
1.3       millert   277: int
1.21      deraadt   278: getgoal(struct line *dlp)
1.3       millert   279: {
1.14      vincent   280:        int c, i, col = 0;
1.24      kjell     281:        char tmp[5];
                    282:
1.14      vincent   283:
                    284:        for (i = 0; i < llength(dlp); i++) {
                    285:                c = lgetc(dlp, i);
1.1       deraadt   286:                if (c == '\t'
                    287: #ifdef NOTAB
1.3       millert   288:                    && !(curbp->b_flag & BFNOTAB)
1.1       deraadt   289: #endif
1.14      vincent   290:                        ) {
                    291:                        col |= 0x07;
                    292:                        col++;
                    293:                } else if (ISCTRL(c) != FALSE) {
                    294:                        col += 2;
                    295:                } else if (isprint(c))
                    296:                        col++;
                    297:                else {
1.24      kjell     298:                        col += snprintf(tmp, sizeof(tmp), "\\%o", c);
1.14      vincent   299:                }
                    300:                if (col > curgoal)
1.1       deraadt   301:                        break;
                    302:        }
1.14      vincent   303:        return (i);
1.1       deraadt   304: }
                    305:
                    306: /*
                    307:  * Scroll forward by a specified number
                    308:  * of lines, or by a full page if no argument.
                    309:  * The "2" is the window overlap (this is the default
                    310:  * value from ITS EMACS). Because the top line in
                    311:  * the window is zapped, we have to do a hard
                    312:  * update and get it back.
                    313:  */
1.3       millert   314: /* ARGSUSED */
                    315: int
1.12      vincent   316: forwpage(int f, int n)
1.1       deraadt   317: {
1.21      deraadt   318:        struct line  *lp;
1.1       deraadt   319:
                    320:        if (!(f & FFARG)) {
1.3       millert   321:                n = curwp->w_ntrows - 2;        /* Default scroll.       */
                    322:                if (n <= 0)                     /* Forget the overlap    */
                    323:                        n = 1;                  /* if tiny window.       */
1.1       deraadt   324:        } else if (n < 0)
1.18      db        325:                return (backpage(f | FFRAND, -n));
1.31      lum       326:
1.1       deraadt   327:        lp = curwp->w_linep;
1.31      lum       328:        while (n--)
1.34      lum       329:                if ((lp = lforw(lp)) == curbp->b_headp) {
1.50    ! lum       330:                        (void)dobeep_msg("End of buffer");
1.31      lum       331:                        return(TRUE);
1.34      lum       332:                }
1.1       deraadt   333:        curwp->w_linep = lp;
1.30      kjell     334:        curwp->w_rflag |= WFFULL;
1.31      lum       335:
1.1       deraadt   336:        /* if in current window, don't move dot */
1.32      lum       337:        for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp))
1.3       millert   338:                if (lp == curwp->w_dotp)
1.18      db        339:                        return (TRUE);
1.31      lum       340:
1.27      kjell     341:        /* Advance the dot the slow way, for line nos */
                    342:        while (curwp->w_dotp != curwp->w_linep) {
                    343:                curwp->w_dotp = lforw(curwp->w_dotp);
                    344:                curwp->w_dotline++;
                    345:        }
1.3       millert   346:        curwp->w_doto = 0;
1.18      db        347:        return (TRUE);
1.1       deraadt   348: }
                    349:
                    350: /*
                    351:  * This command is like "forwpage",
                    352:  * but it goes backwards. The "2", like above,
                    353:  * is the overlap between the two windows. The
                    354:  * value is from the ITS EMACS manual. The
                    355:  * hard update is done because the top line in
                    356:  * the window is zapped.
                    357:  */
1.3       millert   358: /* ARGSUSED */
                    359: int
1.12      vincent   360: backpage(int f, int n)
1.1       deraadt   361: {
1.33      lum       362:        struct line  *lp, *lp2;
1.1       deraadt   363:
                    364:        if (!(f & FFARG)) {
1.3       millert   365:                n = curwp->w_ntrows - 2;        /* Default scroll.       */
                    366:                if (n <= 0)                     /* Don't blow up if the  */
1.35      lum       367:                        return (backline(f, 1));/* window is tiny.       */
1.1       deraadt   368:        } else if (n < 0)
1.18      db        369:                return (forwpage(f | FFRAND, -n));
1.33      lum       370:
                    371:        lp = lp2 = curwp->w_linep;
                    372:
1.25      kjell     373:        while (n-- && lback(lp) != curbp->b_headp) {
1.1       deraadt   374:                lp = lback(lp);
1.34      lum       375:        }
1.50    ! lum       376:        if (lp == curwp->w_linep)
        !           377:                (void)dobeep_msg("Beginning of buffer");
        !           378:
1.1       deraadt   379:        curwp->w_linep = lp;
1.30      kjell     380:        curwp->w_rflag |= WFFULL;
1.33      lum       381:
1.1       deraadt   382:        /* if in current window, don't move dot */
1.25      kjell     383:        for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp))
1.3       millert   384:                if (lp == curwp->w_dotp)
1.18      db        385:                        return (TRUE);
1.33      lum       386:
                    387:         lp2 = lforw(lp2);
                    388:
1.27      kjell     389:        /* Move the dot the slow way, for line nos */
1.33      lum       390:        while (curwp->w_dotp != lp2) {
1.36      lum       391:                 if (curwp->w_dotline <= curwp->w_ntrows)
1.45      florian   392:                        goto out;
1.27      kjell     393:                curwp->w_dotp = lback(curwp->w_dotp);
                    394:                curwp->w_dotline--;
                    395:        }
1.45      florian   396: out:
1.1       deraadt   397:        curwp->w_doto = 0;
1.18      db        398:        return (TRUE);
1.1       deraadt   399: }
                    400:
1.3       millert   401: /*
                    402:  * These functions are provided for compatibility with Gosling's Emacs. They
                    403:  * are used to scroll the display up (or down) one line at a time.
1.1       deraadt   404:  */
1.7       deraadt   405: int
1.12      vincent   406: forw1page(int f, int n)
1.1       deraadt   407: {
1.3       millert   408:        if (!(f & FFARG)) {
                    409:                n = 1;
1.1       deraadt   410:                f = FFUNIV;
                    411:        }
1.3       millert   412:        forwpage(f | FFRAND, n);
1.18      db        413:        return (TRUE);
1.1       deraadt   414: }
                    415:
1.7       deraadt   416: int
1.12      vincent   417: back1page(int f, int n)
1.1       deraadt   418: {
                    419:        if (!(f & FFARG)) {
1.3       millert   420:                n = 1;
1.1       deraadt   421:                f = FFUNIV;
                    422:        }
1.3       millert   423:        backpage(f | FFRAND, n);
1.18      db        424:        return (TRUE);
1.1       deraadt   425: }
                    426:
                    427: /*
                    428:  * Page the other window. Check to make sure it exists, then
                    429:  * nextwind, forwpage and restore window pointers.
                    430:  */
1.3       millert   431: int
1.12      vincent   432: pagenext(int f, int n)
1.1       deraadt   433: {
1.21      deraadt   434:        struct mgwin *wp;
1.1       deraadt   435:
1.50    ! lum       436:        if (wheadp->w_wndp == NULL)
        !           437:                return(dobeep_msg("No other window"));
        !           438:
1.1       deraadt   439:        wp = curwp;
1.6       art       440:        (void) nextwind(f, n);
                    441:        (void) forwpage(f, n);
1.1       deraadt   442:        curwp = wp;
                    443:        curbp = wp->w_bufp;
1.18      db        444:        return (TRUE);
1.1       deraadt   445: }
                    446:
                    447: /*
                    448:  * Internal set mark routine, used by other functions (daveb).
                    449:  */
1.6       art       450: void
1.12      vincent   451: isetmark(void)
1.1       deraadt   452: {
                    453:        curwp->w_markp = curwp->w_dotp;
                    454:        curwp->w_marko = curwp->w_doto;
1.23      kjell     455:        curwp->w_markline = curwp->w_dotline;
1.1       deraadt   456: }
                    457:
                    458: /*
                    459:  * Set the mark in the current window
                    460:  * to the value of dot. A message is written to
                    461:  * the echo line.  (ewprintf knows about macros)
                    462:  */
1.3       millert   463: /* ARGSUSED */
                    464: int
1.12      vincent   465: setmark(int f, int n)
1.1       deraadt   466: {
                    467:        isetmark();
                    468:        ewprintf("Mark set");
1.29      kjell     469:        return (TRUE);
                    470: }
                    471:
                    472: /* Clear the mark, if set. */
                    473: /* ARGSUSED */
                    474: int
                    475: clearmark(int f, int n)
                    476: {
                    477:        if (!curwp->w_markp)
                    478:                return (FALSE);
                    479:
                    480:        curwp->w_markp = NULL;
                    481:        curwp->w_marko = 0;
                    482:        curwp->w_markline = 0;
                    483:
1.18      db        484:        return (TRUE);
1.1       deraadt   485: }
                    486:
                    487: /*
                    488:  * Swap the values of "dot" and "mark" in
                    489:  * the current window. This is pretty easy, because
                    490:  * all of the hard work gets done by the standard routine
                    491:  * that moves the mark about. The only possible
                    492:  * error is "no mark".
                    493:  */
1.3       millert   494: /* ARGSUSED */
                    495: int
1.12      vincent   496: swapmark(int f, int n)
1.1       deraadt   497: {
1.21      deraadt   498:        struct line  *odotp;
1.23      kjell     499:        int odoto, odotline;
1.1       deraadt   500:
1.50    ! lum       501:        if (curwp->w_markp == NULL)
        !           502:                return(dobeep_msg("No mark in this window"));
        !           503:
1.1       deraadt   504:        odotp = curwp->w_dotp;
                    505:        odoto = curwp->w_doto;
1.23      kjell     506:        odotline = curwp->w_dotline;
1.3       millert   507:        curwp->w_dotp = curwp->w_markp;
                    508:        curwp->w_doto = curwp->w_marko;
1.23      kjell     509:        curwp->w_dotline = curwp->w_markline;
1.1       deraadt   510:        curwp->w_markp = odotp;
                    511:        curwp->w_marko = odoto;
1.23      kjell     512:        curwp->w_markline = odotline;
1.30      kjell     513:        curwp->w_rflag |= WFMOVE;
1.18      db        514:        return (TRUE);
1.1       deraadt   515: }
                    516:
                    517: /*
                    518:  * Go to a specific line, mostly for
                    519:  * looking up errors in C programs, which give the
                    520:  * error a line number. If an argument is present, then
                    521:  * it is the line number, else prompt for a line number
                    522:  * to use.
                    523:  */
1.3       millert   524: /* ARGSUSED */
                    525: int
1.12      vincent   526: gotoline(int f, int n)
1.1       deraadt   527: {
1.23      kjell     528:        char   buf[32], *bufp;
                    529:        const char *err;
1.1       deraadt   530:
                    531:        if (!(f & FFARG)) {
1.20      kjell     532:                if ((bufp = eread("Goto line: ", buf, sizeof(buf),
                    533:                    EFNUL | EFNEW | EFCR)) == NULL)
1.24      kjell     534:                        return (ABORT);
                    535:                if (bufp[0] == '\0')
1.18      db        536:                        return (ABORT);
1.23      kjell     537:                n = (int)strtonum(buf, INT_MIN, INT_MAX, &err);
1.50    ! lum       538:                if (err)
        !           539:                        return(dobeep_msgs("Line number %s", err));
1.1       deraadt   540:        }
1.38      jasper    541:        return(setlineno(n));
                    542: }
                    543:
                    544: /*
                    545:  * Set the line number and switch to it.
                    546:  */
                    547: int
                    548: setlineno(int n)
                    549: {
                    550:        struct line  *clp;
                    551:
1.5       millert   552:        if (n >= 0) {
1.23      kjell     553:                if (n == 0)
                    554:                        n++;
                    555:                curwp->w_dotline = n;
1.25      kjell     556:                clp = lforw(curbp->b_headp);    /* "clp" is first line */
1.1       deraadt   557:                while (--n > 0) {
1.25      kjell     558:                        if (lforw(clp) == curbp->b_headp) {
1.23      kjell     559:                                curwp->w_dotline = curwp->w_bufp->b_lines;
1.3       millert   560:                                break;
1.23      kjell     561:                        }
1.1       deraadt   562:                        clp = lforw(clp);
                    563:                }
                    564:        } else {
1.23      kjell     565:                curwp->w_dotline = curwp->w_bufp->b_lines + n;
1.25      kjell     566:                clp = lback(curbp->b_headp);    /* "clp" is last line */
1.1       deraadt   567:                while (n < 0) {
1.25      kjell     568:                        if (lback(clp) == curbp->b_headp) {
1.23      kjell     569:                                curwp->w_dotline = 1;
1.3       millert   570:                                break;
1.23      kjell     571:                        }
1.1       deraadt   572:                        clp = lback(clp);
                    573:                        n++;
                    574:                }
                    575:        }
                    576:        curwp->w_dotp = clp;
                    577:        curwp->w_doto = 0;
1.30      kjell     578:        curwp->w_rflag |= WFMOVE;
1.18      db        579:        return (TRUE);
1.1       deraadt   580: }