[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.2

1.1       deraadt     1: /*
                      2:  *             Basic cursor motion commands.
                      3:  *
                      4:  * The routines in this file are the basic
                      5:  * command functions for moving the cursor around on
                      6:  * the screen, setting mark, and swapping dot with
                      7:  * mark. Only moves between lines, which might make the
                      8:  * current buffer framing bad, are hard.
                      9:  */
                     10: #include       "def.h"
                     11:
                     12: VOID   setgoal();
                     13:
                     14: /*
                     15:  * Go to beginning of line.
                     16:  */
                     17: /*ARGSUSED*/
                     18: gotobol(f, n)
                     19: {
                     20:        curwp->w_doto  = 0;
                     21:        return (TRUE);
                     22: }
                     23:
                     24: /*
                     25:  * Move cursor backwards. Do the
                     26:  * right thing if the count is less than
                     27:  * 0. Error if you try to move back from
                     28:  * the beginning of the buffer.
                     29:  */
                     30: /*ARGSUSED*/
                     31: backchar(f, n)
                     32: register int n;
                     33: {
                     34:        register LINE   *lp;
                     35:
                     36:        if (n < 0) return forwchar(f, -n);
                     37:        while (n--) {
                     38:                if (curwp->w_doto == 0) {
                     39:                        if ((lp=lback(curwp->w_dotp)) == curbp->b_linep) {
                     40:                                if (!(f & FFRAND))
                     41:                                        ewprintf("Beginning of buffer");
                     42:                                return (FALSE);
                     43:                        }
                     44:                        curwp->w_dotp  = lp;
                     45:                        curwp->w_doto  = llength(lp);
                     46:                        curwp->w_flag |= WFMOVE;
                     47:                } else
                     48:                        curwp->w_doto--;
                     49:        }
                     50:        return TRUE;
                     51: }
                     52:
                     53: /*
                     54:  * Go to end of line.
                     55:  */
                     56: /*ARGSUSED*/
                     57: gotoeol(f, n)
                     58: {
                     59:        curwp->w_doto  = llength(curwp->w_dotp);
                     60:        return (TRUE);
                     61: }
                     62:
                     63: /*
                     64:  * Move cursor forwards. Do the
                     65:  * right thing if the count is less than
                     66:  * 0. Error if you try to move forward
                     67:  * from the end of the buffer.
                     68:  */
                     69: /*ARGSUSED*/
                     70: forwchar(f, n)
                     71: register int n;
                     72: {
                     73:        if (n < 0) return backchar(f, -n);
                     74:        while (n--) {
                     75:                if (curwp->w_doto == llength(curwp->w_dotp)) {
                     76:                        curwp->w_dotp  = lforw(curwp->w_dotp);
                     77:                        if (curwp->w_dotp == curbp->b_linep) {
                     78:                                curwp->w_dotp = lback(curwp->w_dotp);
                     79:                                if (!(f & FFRAND))
                     80:                                        ewprintf("End of buffer");
                     81:                                return FALSE;
                     82:                        }
                     83:                        curwp->w_doto  = 0;
                     84:                        curwp->w_flag |= WFMOVE;
                     85:                } else
                     86:                        curwp->w_doto++;
                     87:        }
                     88:        return TRUE;
                     89: }
                     90:
                     91: /*
                     92:  * Go to the beginning of the
                     93:  * buffer. Setting WFHARD is conservative,
                     94:  * but almost always the case.
                     95:  */
                     96: gotobob(f, n)
                     97: {
                     98:        (VOID) setmark(f, n) ;
                     99:        curwp->w_dotp  = lforw(curbp->b_linep);
                    100:        curwp->w_doto  = 0;
                    101:        curwp->w_flag |= WFHARD;
                    102:        return TRUE;
                    103: }
                    104:
                    105: /*
                    106:  * Go to the end of the buffer.
                    107:  * Setting WFHARD is conservative, but
                    108:  * almost always the case.
                    109:  */
                    110: gotoeob(f, n)
                    111: {
                    112:        (VOID) setmark(f, n) ;
                    113:        curwp->w_dotp  = lback(curbp->b_linep);
                    114:        curwp->w_doto  = llength(curwp->w_dotp);
                    115:        curwp->w_flag |= WFHARD;
                    116:        return TRUE;
                    117: }
                    118:
                    119: /*
                    120:  * Move forward by full lines.
                    121:  * If the number of lines to move is less
                    122:  * than zero, call the backward line function to
                    123:  * actually do it. The last command controls how
                    124:  * the goal column is set.
                    125:  */
                    126: /*ARGSUSED*/
                    127: forwline(f, n)
                    128: {
                    129:        register LINE   *dlp;
                    130:
                    131:        if (n < 0)
                    132:                return backline(f|FFRAND, -n);
                    133:        if ((lastflag&CFCPCN) == 0)             /* Fix goal.            */
                    134:                setgoal();
                    135:        thisflag |= CFCPCN;
                    136:        if (n == 0) return TRUE;
                    137:        dlp = curwp->w_dotp;
                    138:        while (dlp!=curbp->b_linep && n--)
                    139:                dlp = lforw(dlp);
                    140:        curwp->w_flag |= WFMOVE;
                    141:        if(dlp==curbp->b_linep) {       /* ^N at end of buffer creates lines (like gnu) */
                    142:                if(!(curbp->b_flag&BFCHG)) {    /* first change */
                    143:                        curbp->b_flag |= BFCHG;
                    144:                        curwp->w_flag |= WFMODE;
                    145:                }
                    146:                curwp->w_doto = 0;
                    147:                while(n-- >= 0) {
                    148:                        if((dlp = lallocx(0)) == NULL) return FALSE;
                    149:                        dlp->l_fp = curbp->b_linep;
                    150:                        dlp->l_bp = lback(dlp->l_fp);
                    151:                        dlp->l_bp->l_fp = dlp->l_fp->l_bp = dlp;
                    152:                }
                    153:                curwp->w_dotp = lback(curbp->b_linep);
                    154:        } else {
                    155:                curwp->w_dotp  = dlp;
                    156:                curwp->w_doto  = getgoal(dlp);
                    157:        }
                    158:        return TRUE;
                    159: }
                    160:
                    161: /*
                    162:  * This function is like "forwline", but
                    163:  * goes backwards. The scheme is exactly the same.
                    164:  * Check for arguments that are less than zero and
                    165:  * call your alternate. Figure out the new line and
                    166:  * call "movedot" to perform the motion.
                    167:  */
                    168: /*ARGSUSED*/
                    169: backline(f, n)
                    170: {
                    171:        register LINE   *dlp;
                    172:
                    173:        if (n < 0) return forwline(f|FFRAND, -n);
                    174:        if ((lastflag&CFCPCN) == 0)             /* Fix goal.            */
                    175:                setgoal();
                    176:        thisflag |= CFCPCN;
                    177:        dlp = curwp->w_dotp;
                    178:        while (n-- && lback(dlp)!=curbp->b_linep)
                    179:                dlp = lback(dlp);
                    180:        curwp->w_dotp  = dlp;
                    181:        curwp->w_doto  = getgoal(dlp);
                    182:        curwp->w_flag |= WFMOVE;
                    183:        return TRUE;
                    184: }
                    185:
                    186: /*
                    187:  * Set the current goal column,
                    188:  * which is saved in the external variable "curgoal",
                    189:  * to the current cursor column. The column is never off
                    190:  * the edge of the screen; it's more like display then
                    191:  * show position.
                    192:  */
                    193: VOID
                    194: setgoal() {
                    195:
                    196:        curgoal = getcolpos() - 1;              /* Get the position.    */
                    197: /* we can now display past end of display, don't chop! */
                    198: }
                    199:
                    200: /*
                    201:  * This routine looks at a line (pointed
                    202:  * to by the LINE pointer "dlp") and the current
                    203:  * vertical motion goal column (set by the "setgoal"
                    204:  * routine above) and returns the best offset to use
                    205:  * when a vertical motion is made into the line.
                    206:  */
                    207: getgoal(dlp) register LINE *dlp; {
                    208:        register int    c;
                    209:        register int    col;
                    210:        register int    newcol;
                    211:        register int    dbo;
                    212:
                    213:        col = 0;
                    214:        dbo = 0;
                    215:        while (dbo != llength(dlp)) {
                    216:                c = lgetc(dlp, dbo);
                    217:                newcol = col;
                    218:                if (c == '\t'
                    219: #ifdef NOTAB
                    220:                                && !(curbp->b_flag & BFNOTAB)
                    221: #endif
                    222:                        )
                    223:                    newcol |= 0x07;
                    224:                else if (ISCTRL(c) != FALSE)
                    225:                        ++newcol;
                    226:                ++newcol;
                    227:                if (newcol > curgoal)
                    228:                        break;
                    229:                col = newcol;
                    230:                ++dbo;
                    231:        }
                    232:        return (dbo);
                    233: }
                    234:
                    235: /*
                    236:  * Scroll forward by a specified number
                    237:  * of lines, or by a full page if no argument.
                    238:  * The "2" is the window overlap (this is the default
                    239:  * value from ITS EMACS). Because the top line in
                    240:  * the window is zapped, we have to do a hard
                    241:  * update and get it back.
                    242:  */
                    243: /*ARGSUSED*/
                    244: forwpage(f, n)
                    245: register int n;
                    246: {
                    247:        register LINE   *lp;
                    248:
                    249:        if (!(f & FFARG)) {
                    250:                n = curwp->w_ntrows - 2;        /* Default scroll.      */
                    251:                if (n <= 0)                     /* Forget the overlap   */
                    252:                        n = 1;                  /* if tiny window.      */
                    253:        } else if (n < 0)
                    254:                return backpage(f|FFRAND, -n);
                    255: #ifdef CVMVAS
                    256:        else                                    /* Convert from pages   */
                    257:                n *= curwp->w_ntrows;           /* to lines.            */
                    258: #endif
                    259:        lp = curwp->w_linep;
                    260:        while (n-- && lforw(lp)!=curbp->b_linep)
                    261:                lp = lforw(lp);
                    262:        curwp->w_linep = lp;
                    263:        curwp->w_flag |= WFHARD;
                    264:        /* if in current window, don't move dot */
                    265:        for(n = curwp->w_ntrows; n-- && lp!=curbp->b_linep; lp = lforw(lp))
                    266:                if(lp==curwp->w_dotp) return TRUE;
                    267:        curwp->w_dotp  = curwp->w_linep;
                    268:        curwp->w_doto  = 0;
                    269:        return TRUE;
                    270: }
                    271:
                    272: /*
                    273:  * This command is like "forwpage",
                    274:  * but it goes backwards. The "2", like above,
                    275:  * is the overlap between the two windows. The
                    276:  * value is from the ITS EMACS manual. The
                    277:  * hard update is done because the top line in
                    278:  * the window is zapped.
                    279:  */
                    280: /*ARGSUSED*/
                    281: backpage(f, n)
                    282: register int n;
                    283: {
                    284:        register LINE   *lp;
                    285:
                    286:        if (!(f & FFARG)) {
                    287:                n = curwp->w_ntrows - 2;        /* Default scroll.      */
                    288:                if (n <= 0)                     /* Don't blow up if the */
                    289:                        n = 1;                  /* window is tiny.      */
                    290:        } else if (n < 0)
                    291:                return forwpage(f|FFRAND, -n);
                    292: #ifdef CVMVAS
                    293:        else                                    /* Convert from pages   */
                    294:                n *= curwp->w_ntrows;           /* to lines.            */
                    295: #endif
                    296:        lp = curwp->w_linep;
                    297:        while (n-- && lback(lp)!=curbp->b_linep)
                    298:                lp = lback(lp);
                    299:        curwp->w_linep = lp;
                    300:        curwp->w_flag |= WFHARD;
                    301:        /* if in current window, don't move dot */
                    302:        for(n = curwp->w_ntrows; n-- && lp!=curbp->b_linep; lp = lforw(lp))
                    303:                if(lp==curwp->w_dotp) return TRUE;
                    304:        curwp->w_dotp = curwp->w_linep;
                    305:        curwp->w_doto = 0;
                    306:        return TRUE;
                    307: }
                    308:
                    309: /* These functions are provided for compatibility with Gosling's Emacs.
                    310:  *    They are used to scroll the display up (or down) one line at a time.
                    311:  */
                    312:
                    313: #ifdef GOSMACS
                    314: forw1page(f, n)
                    315: int f, n;
                    316: {
                    317:        if (!(f & FFARG))  {
                    318:                n = 1;
                    319:                f = FFUNIV;
                    320:        }
                    321:        forwpage(f|FFRAND, n);
                    322: }
                    323:
                    324: back1page(f, n)
                    325: int f, n;
                    326: {
                    327:        if (!(f & FFARG)) {
                    328:                n = 1;
                    329:                f = FFUNIV;
                    330:        }
                    331:        backpage(f|FFRAND, n);
                    332: }
                    333: #endif
                    334:
                    335: /*
                    336:  * Page the other window. Check to make sure it exists, then
                    337:  * nextwind, forwpage and restore window pointers.
                    338:  */
                    339: pagenext(f, n)
                    340: {
1.2     ! millert   341:        register MGWIN *wp;
1.1       deraadt   342:
                    343:        if (wheadp->w_wndp == NULL) {
                    344:                ewprintf("No other window");
                    345:                return FALSE;
                    346:        }
                    347:        wp = curwp;
                    348:        (VOID) nextwind(f, n);
                    349:        (VOID) forwpage(f, n);
                    350:        curwp = wp;
                    351:        curbp = wp->w_bufp;
                    352:        return TRUE;
                    353: }
                    354:
                    355: /*
                    356:  * Internal set mark routine, used by other functions (daveb).
                    357:  */
                    358: VOID
                    359: isetmark()
                    360: {
                    361:        curwp->w_markp = curwp->w_dotp;
                    362:        curwp->w_marko = curwp->w_doto;
                    363: }
                    364:
                    365: /*
                    366:  * Set the mark in the current window
                    367:  * to the value of dot. A message is written to
                    368:  * the echo line.  (ewprintf knows about macros)
                    369:  */
                    370: /*ARGSUSED*/
                    371: setmark(f, n)
                    372: {
                    373:        isetmark();
                    374:        ewprintf("Mark set");
                    375:        return TRUE;
                    376: }
                    377:
                    378: /*
                    379:  * Swap the values of "dot" and "mark" in
                    380:  * the current window. This is pretty easy, because
                    381:  * all of the hard work gets done by the standard routine
                    382:  * that moves the mark about. The only possible
                    383:  * error is "no mark".
                    384:  */
                    385: /*ARGSUSED*/
                    386: swapmark(f, n)
                    387: {
                    388:        register LINE   *odotp;
                    389:        register int    odoto;
                    390:
                    391:        if (curwp->w_markp == NULL) {
                    392:                ewprintf("No mark in this window");
                    393:                return FALSE;
                    394:        }
                    395:        odotp = curwp->w_dotp;
                    396:        odoto = curwp->w_doto;
                    397:        curwp->w_dotp  = curwp->w_markp;
                    398:        curwp->w_doto  = curwp->w_marko;
                    399:        curwp->w_markp = odotp;
                    400:        curwp->w_marko = odoto;
                    401:        curwp->w_flag |= WFMOVE;
                    402:        return TRUE;
                    403: }
                    404:
                    405: /*
                    406:  * Go to a specific line, mostly for
                    407:  * looking up errors in C programs, which give the
                    408:  * error a line number. If an argument is present, then
                    409:  * it is the line number, else prompt for a line number
                    410:  * to use.
                    411:  */
                    412: /*ARGSUSED*/
                    413: gotoline(f, n)
                    414: register int n;
                    415: {
                    416:        register LINE   *clp;
                    417:        register int    s;
                    418:        char            buf[32];
                    419:
                    420:        if (!(f & FFARG)) {
                    421:                if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
                    422:                        return s;
                    423:                n = atoi(buf);
                    424:        }
                    425:
                    426:        if (n > 0) {
                    427:                clp = lforw(curbp->b_linep);    /* "clp" is first line  */
                    428:                while (--n > 0) {
                    429:                        if (lforw(clp) == curbp->b_linep) break;
                    430:                        clp = lforw(clp);
                    431:                }
                    432:        } else {
                    433:                clp = lback(curbp->b_linep);    /* clp is last line */
                    434:                while (n < 0) {
                    435:                        if (lback(clp) == curbp->b_linep) break;
                    436:                        clp = lback(clp);
                    437:                        n++;
                    438:                }
                    439:        }
                    440:        curwp->w_dotp = clp;
                    441:        curwp->w_doto = 0;
                    442:        curwp->w_flag |= WFMOVE;
                    443:        return TRUE;
                    444: }