Annotation of coherent/g/usr/bin/me/basic.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The routines in this file move the cursor around on the screen.
                      3:  * They compute a new value for the cursor, then adjust ".".
                      4:  * The display code always updates the cursor location, so only moves
                      5:  * between lines, or functions that adjust the top line in the window
                      6:  * and invalidate the framing, are hard.
                      7:  */
                      8: #include       <stdio.h>
                      9: #include       "ed.h"
                     10: 
                     11: /*
                     12:  * Move the cursor to the beginning of the current line.
                     13:  * Trivial.
                     14:  */
                     15: gotobol(f, n)
                     16: {
                     17:        curwp->w_doto  = 0;
                     18:        return (TRUE);
                     19: }
                     20: 
                     21: /*
                     22:  * Move the cursor backwards by "n" characters. If "n" is less than
                     23:  * zero call "forwchar" to actually do the move. Otherwise compute
                     24:  * the new cursor location. Error if you try and move out of the buffer.
                     25:  * Set the flag if the line pointer for dot changes.
                     26:  */
                     27: backchar(f, n)
                     28: register int   n;
                     29: {
                     30:        register LINE   *lp;
                     31: 
                     32:        if (n < 0)
                     33:                return (forwchar(f, -n));
                     34:        while (n--) {
                     35:                if (curwp->w_doto == 0) {
                     36:                        if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
                     37:                                return (FALSE);
                     38:                        curwp->w_dotp  = lp;
                     39:                        curwp->w_doto  = llength(lp);
                     40:                        curwp->w_flag |= WFMOVE;
                     41:                } else
                     42:                        curwp->w_doto--;
                     43:        }
                     44:        return (TRUE);
                     45: }
                     46: 
                     47: /*
                     48:  * Move the cursor to the end of the current line. Trivial.
                     49:  * No errors.
                     50:  */
                     51: gotoeol(f, n)
                     52: {
                     53:        curwp->w_doto  = llength(curwp->w_dotp);
                     54:        return (TRUE);
                     55: }
                     56: 
                     57: /*
                     58:  * Move the cursor forwards by "n" characters. If "n" is less than
                     59:  * zero call "backchar" to actually do the move. Otherwise compute
                     60:  * the new cursor location, and move ".".  Error if you try and move
                     61:  * off the end of the buffer. Set the flag if the line pointer
                     62:  * for dot changes.
                     63:  */
                     64: forwchar(f, n)
                     65: register int   n;
                     66: {
                     67:        if (n < 0)
                     68:                return (backchar(f, -n));
                     69:        while (n--) {
                     70:                if (curwp->w_doto == llength(curwp->w_dotp)) {
                     71:                        if (curwp->w_dotp == curbp->b_linep)
                     72:                                return (FALSE);
                     73:                        curwp->w_dotp  = lforw(curwp->w_dotp);
                     74:                        curwp->w_doto  = 0;
                     75:                        curwp->w_flag |= WFMOVE;
                     76:                } else
                     77:                        curwp->w_doto++;
                     78:        }
                     79:        return (TRUE);
                     80: }
                     81: 
                     82: /*
                     83:  * Goto the beginning of the buffer.
                     84:  * Massive adjustment of dot. This is considered to be hard motion;
                     85:  * it really isn't if the original value of dot is the same as the
                     86:  * new value of dot.
                     87:  * Normally bound to "M-<".
                     88:  */
                     89: gotobob(f, n)
                     90: {
                     91:        curwp->w_dotp  = lforw(curbp->b_linep);
                     92:        curwp->w_doto  = 0;
                     93:        curwp->w_flag |= WFHARD;
                     94:        return (TRUE);
                     95: }
                     96: 
                     97: /*
                     98:  * Move to the end of the buffer.
                     99:  * Dot is always put at the end of the file (ZJ). The standard screen code does
                    100:  * most of the hard parts of update. Bound to "M->".
                    101:  */
                    102: gotoeob(f, n)
                    103: {
                    104:        curwp->w_dotp  = curbp->b_linep;
                    105:        curwp->w_doto  = 0;
                    106:        curwp->w_flag |= WFHARD;
                    107:        return (TRUE);
                    108: }
                    109: 
                    110: /*
                    111:  * Move forward by full lines.
                    112:  * If the number of lines to move is less than zero, call the backward line
                    113:  * function to actually do it. The last command controls how the goal column
                    114:  * is set. Bound to "C-N". No errors are possible.
                    115:  */
                    116: forwline(f, n)
                    117: {
                    118:        register LINE   *dlp;
                    119: 
                    120:        if (n < 0)
                    121:                return (backline(f, -n));
                    122:        if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
                    123:                curgoal = curcol;               /* not C-P or C-N       */
                    124:        thisflag |= CFCPCN;
                    125:        dlp = curwp->w_dotp;
                    126:        while (n-- && dlp!=curbp->b_linep)
                    127:                dlp = lforw(dlp);
                    128:        curwp->w_dotp  = dlp;
                    129:        curwp->w_doto  = getgoal(dlp);
                    130:        curwp->w_flag |= WFMOVE;
                    131:        return (TRUE);
                    132: }
                    133: 
                    134: /*
                    135:  * This function is like "forwline", but goes backwards.
                    136:  * The scheme is exactly the same.  Check for arguments that are
                    137:  * less than zero and call your alternate. Figure out the new line and
                    138:  * call "movedot" to perform the motion. No errors are possible.
                    139:  * Bound to "C-P".
                    140:  */
                    141: backline(f, n)
                    142: {
                    143:        register LINE   *dlp;
                    144: 
                    145:        if (n < 0)
                    146:                return (forwline(f, -n));
                    147:        if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
                    148:                curgoal = curcol;               /* last isn't C-P, C-N  */
                    149:        thisflag |= CFCPCN;
                    150:        dlp = curwp->w_dotp;
                    151:        while (n-- && lback(dlp)!=curbp->b_linep)
                    152:                dlp = lback(dlp);
                    153:        curwp->w_dotp  = dlp;
                    154:        curwp->w_doto  = getgoal(dlp);
                    155:        curwp->w_flag |= WFMOVE;
                    156:        return (TRUE);
                    157: }
                    158: 
                    159: /*
                    160:  * This routine, given a pointer to a LINE, and the current cursor goal
                    161:  * column, return the best choice for the offset. The offset is returned.
                    162:  * Used by "C-N" and "C-P".
                    163:  */
                    164: getgoal(dlp)
                    165: register LINE  *dlp;
                    166: {
                    167:        unsigned c;
                    168:        register int    col;
                    169:        register int    newcol;
                    170:        register int    dbo;
                    171: 
                    172:        col = 0;
                    173:        dbo = 0;
                    174:        while (dbo != llength(dlp)) {
                    175:                c = lgetc(dlp, dbo);
                    176:                newcol = col;
                    177:                switch (dblchr(c)) {
                    178:                case 2:
                    179:                        taber(newcol);
                    180:                        break;
                    181:                case 1:
                    182:                        ++newcol;
                    183:                }
                    184:                ++newcol;
                    185:                if (newcol > curgoal)
                    186:                        break;
                    187:                col = newcol;
                    188:                ++dbo;
                    189:        }
                    190:        return (dbo);
                    191: }
                    192: 
                    193: /*
                    194:  * Scroll forward by a specified number of lines, or by a full page if
                    195:  * no argument.
                    196:  * The "2" in the arithmetic on the window size is the overlap; this value is
                    197:  * the default overlap value in ITS EMACS. Because this zaps the top line in
                    198:  * the display window, we have to do a hard update.
                    199:  * Bound to "C-V".
                    200:  */
                    201: forwpage(f, n)
                    202: register int   n;
                    203: {
                    204:        register LINE   *lp;
                    205: 
                    206:        if (f == FALSE) {
                    207:                n = curwp->w_ntrows - 2;        /* Default scroll.      */
                    208:                if (n <= 0)                     /* Forget the overlap   */
                    209:                        n = 1;                  /* if tiny window.      */
                    210:        } else if (n < 0)
                    211:                return (backpage(f, -n));
                    212: #if    CVMVAS
                    213:        else                                    /* Convert from pages   */
                    214:                n *= curwp->w_ntrows;           /* to lines.            */
                    215: #endif
                    216:        lp = curwp->w_linep;
                    217:        while (n-- && lp!=curbp->b_linep)
                    218:                lp = lforw(lp);
                    219:        curwp->w_linep = lp;
                    220:        curwp->w_dotp  = lp;
                    221:        curwp->w_doto  = 0;
                    222:        curwp->w_flag |= WFHARD;
                    223:        return (TRUE);
                    224: }
                    225: 
                    226: /*
                    227:  * This command is like "forwpage", but it goes backwards.
                    228:  * The "2", like above, is the overlap between the two windows. The
                    229:  * value is from the ITS EMACS manual.  We do a hard update for exactly
                    230:  * the same reason.
                    231:  * Bound to "M-V".
                    232:  */
                    233: backpage(f, n)
                    234: register int   n;
                    235: {
                    236:        register LINE   *lp;
                    237: 
                    238:        if (f == FALSE) {
                    239:                n = curwp->w_ntrows - 2;        /* Default scroll.      */
                    240:                if (n <= 0)                     /* Don't blow up if the */
                    241:                        n = 1;                  /* window is tiny.      */
                    242:        } else if (n < 0)
                    243:                return (forwpage(f, -n));
                    244: #if    CVMVAS
                    245:        else                                    /* Convert from pages   */
                    246:                n *= curwp->w_ntrows;           /* to lines.            */
                    247: #endif
                    248:        lp = curwp->w_linep;
                    249:        while (n-- && lback(lp)!=curbp->b_linep)
                    250:                lp = lback(lp);
                    251:        curwp->w_linep = lp;
                    252:        curwp->w_dotp  = lp;
                    253:        curwp->w_doto  = 0;
                    254:        curwp->w_flag |= WFHARD;
                    255:        return (TRUE);
                    256: }
                    257: 
                    258: /*
                    259:  * Set the mark in the current window to the value of "." in the window.
                    260:  * No errors are possible.
                    261:  * Bound to "M-.".
                    262:  */
                    263: setmark(f, n)
                    264: {
                    265:        curwp->w_markp = curwp->w_dotp;
                    266:        curwp->w_marko = curwp->w_doto;
                    267:        mlwrite("[Mark set]");
                    268:        return (TRUE);
                    269: }
                    270: 
                    271: /*
                    272:  * Swap the values of "." and "mark" in the current window.
                    273:  * This is pretty easy, because all of the hard work gets done by the
                    274:  * standard routine that moves the mark about. The only possible error is
                    275:  * "no mark".
                    276:  * Bound to "C-X C-X".
                    277:  */
                    278: swapmark(f, n)
                    279: {
                    280:        register LINE   *odotp;
                    281:        register int    odoto;
                    282: 
                    283:        if (curwp->w_markp == NULL) {
                    284:                mlwrite("No mark in this window");
                    285:                return (FALSE);
                    286:        }
                    287:        odotp = curwp->w_dotp;
                    288:        odoto = curwp->w_doto;
                    289:        curwp->w_dotp  = curwp->w_markp;
                    290:        curwp->w_doto  = curwp->w_marko;
                    291:        curwp->w_markp = odotp;
                    292:        curwp->w_marko = odoto;
                    293:        curwp->w_flag |= WFMOVE;
                    294:        return (TRUE);
                    295: }
                    296: 
                    297: /*
                    298:  * Go to a specific line in the buffer, mostly for
                    299:  * looking up errors in C programs, which give the
                    300:  * error a line number. If an argument is present, then
                    301:  * it is the line number, else prompt for a line number
                    302:  * to use.
                    303:  */
                    304: gotoline(f, n)
                    305: register int   n;
                    306: {
                    307:        register LINE   *clp;
                    308:        register int    s;
                    309:        uchar           buf[32];
                    310: 
                    311:        if (f == FALSE) {
                    312:                if ((s=mlreply("Goto line: ", buf, sizeof(buf))) != TRUE)
                    313:                        return (s);
                    314:                n = atoi(buf);
                    315:        }
                    316:        if (n <= 0) {
                    317:                mlwrite("Bad line");
                    318:                return (FALSE);
                    319:        }
                    320:        clp = lforw(curbp->b_linep);            /* "clp" is first line  */
                    321:        while (n != 1) {
                    322:                if (clp == curbp->b_linep) {
                    323:                        mlwrite("Line too large");
                    324:                        return (FALSE);
                    325:                }
                    326:                clp = lforw(clp);
                    327:                --n;
                    328:        }
                    329:        curwp->w_dotp = clp;
                    330:        curwp->w_doto = 0;
                    331:        curwp->w_flag |= WFMOVE;
                    332:        return (TRUE);
                    333: }
                    334: 
                    335: /*
                    336:  * Go to a specific line from the original file, mostly for
                    337:  * looking up errors in C programs, which give the
                    338:  * error a line number. If an argument is present, then
                    339:  * it is the line number, else prompt for a line number
                    340:  * to use.
                    341:  */
                    342: gotofline(f, n)
                    343: register int   n;
                    344: {
                    345:        register LINE   *clp;
                    346:        register int    s;
                    347:        uchar           buf[32];
                    348: 
                    349:        if (f == FALSE) {
                    350:                if ((s=mlreply("Goto line: ", buf, sizeof(buf))) != TRUE)
                    351:                        return (s);
                    352:                n = atoi(buf);
                    353:        }
                    354:        if (n <= 0) {
                    355:                mlwrite("Bad line");
                    356:                return (FALSE);
                    357:        }
                    358:        clp = lforw(curbp->b_linep);            /* "clp" is first line  */
                    359:        while (n != l_number(clp)) {
                    360:                if (clp == curbp->b_linep) {
                    361:                        mlwrite("Line not in buffer");
                    362:                        return (FALSE);
                    363:                }
                    364:                clp = lforw(clp);
                    365:        }
                    366:        curwp->w_dotp = clp;
                    367:        curwp->w_doto = 0;
                    368:        curwp->w_flag |= WFMOVE;
                    369:        return (TRUE);
                    370: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.