Annotation of 43BSDReno/contrib/jove/insert.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
                      3:  * is provided to you without charge, and with no warranty.  You may give  *
                      4:  * away copies of JOVE, including sources, provided that this notice is    *
                      5:  * included in all the files.                                              *
                      6:  ***************************************************************************/
                      7: 
                      8: #include "jove.h"
                      9: #include "ctype.h"
                     10: #include "list.h"
                     11: #include "chars.h"
                     12: #include "disp.h"
                     13: 
                     14: private int
                     15:        newchunk proto((void));
                     16: private void
                     17:        DoNewline proto((int indentp)),
                     18:        init_specials proto((void));
                     19: 
                     20: /* Make a newline after AFTER in buffer BUF, UNLESS after is 0,
                     21:    in which case we insert the newline before after. */
                     22: 
                     23: Line *
                     24: listput(buf, after)
                     25: register Buffer        *buf;
                     26: register Line  *after;
                     27: {
                     28:        register Line   *newline = nbufline();
                     29: 
                     30:        if (after == 0) {       /* Before the first line */
                     31:                newline->l_next = buf->b_first;
                     32:                newline->l_prev = 0;
                     33:                buf->b_first = newline;
                     34:        } else {
                     35:                newline->l_prev = after;
                     36:                newline->l_next = after->l_next;
                     37:                after->l_next = newline;
                     38:        }
                     39:        if (newline->l_next)
                     40:                newline->l_next->l_prev = newline;
                     41:        else
                     42:                if (buf)
                     43:                        buf->b_last = newline;
                     44:        if (buf && buf->b_dot == 0)
                     45:                buf->b_dot = newline;
                     46:        return newline;
                     47: }
                     48: 
                     49: /* Divide the current line and move the current line to the next one */
                     50: 
                     51: void
                     52: LineInsert(num)
                     53: register int   num;
                     54: {
                     55:        char    newline[LBSIZE];
                     56:        register Line   *newdot,
                     57:                        *olddot;
                     58:        int     oldchar;
                     59: 
                     60:        olddot = curline;
                     61:        oldchar = curchar;
                     62: 
                     63:        newdot = curline;
                     64:        while (--num >= 0) {
                     65:                newdot = listput(curbuf, newdot);
                     66:                SavLine(newdot, NullStr);
                     67:        }
                     68: 
                     69:        modify();
                     70:        if (curchar != 0) {
                     71:                strcpy(newline, &linebuf[curchar]);
                     72:                linebuf[curchar] = '\0';        /* Shorten this line */
                     73:                SavLine(curline, linebuf);
                     74:                strcpy(linebuf, newline);
                     75:        } else {        /* Redisplay optimization */
                     76:                newdot->l_dline = curline->l_dline;
                     77:                SavLine(curline, NullStr);
                     78:        }
                     79: 
                     80:        makedirty(curline);
                     81:        curline = newdot;
                     82:        curchar = 0;
                     83:        makedirty(curline);
                     84:        IFixMarks(olddot, oldchar, curline, curchar);
                     85: }
                     86: 
                     87: /* Inserts tabs and spaces to move the cursor to column GOAL.  It
                     88:    Uses the most optimal number of tabs and spaces no matter what
                     89:    was there before hand. */
                     90: 
                     91: void
                     92: n_indent(goal)
                     93: register int   goal;
                     94: {
                     95:        int     dotcol,
                     96:                incrmt;
                     97: 
                     98:        DelWtSpace();
                     99:        dotcol = calc_pos(linebuf, curchar);
                    100: 
                    101:        for (;;) {
                    102:                incrmt = (tabstop - (dotcol % tabstop));
                    103:                if (dotcol + incrmt > goal)
                    104:                        break;
                    105:                insert_c('\t', 1);
                    106:                dotcol += incrmt;
                    107:        }
                    108:        if (dotcol != goal)
                    109:                insert_c(' ', (goal - dotcol));
                    110: }
                    111: 
                    112: #ifdef ABBREV
                    113: void
                    114: MaybeAbbrevExpand()
                    115: {
                    116:        if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
                    117:            !bolp() && ismword(linebuf[curchar - 1]))
                    118:                AbbrevExpand();
                    119: }
                    120: #endif
                    121: 
                    122: void
                    123: SelfInsert()
                    124: {
                    125: #ifdef ABBREV
                    126:        MaybeAbbrevExpand();
                    127: #endif
                    128:        if (LastKeyStruck != CTL('J') && MinorMode(OverWrite)) {
                    129:                register int    num,
                    130:                                i;
                    131: 
                    132:                for (i = 0, num = arg_value(); i < num; i++) {
                    133:                        int     pos = calc_pos(linebuf, curchar);
                    134: 
                    135:                        if (!eolp()) {
                    136:                                if (linebuf[curchar] == '\t') {
                    137:                                        if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
                    138:                                                del_char(FORWARD, 1, NO);
                    139:                                } else
                    140:                                        del_char(FORWARD, 1, NO);
                    141:                        }
                    142:                        insert_c(LastKeyStruck, 1);
                    143:                }
                    144:        } else
                    145:                Insert(LastKeyStruck);
                    146: 
                    147:        if (MinorMode(Fill) && (curchar >= RMargin ||
                    148:                               (calc_pos(linebuf, curchar) >= RMargin))) {
                    149:                int margin;
                    150:                Bufpos save;
                    151: 
                    152:                if (MinorMode(Indent)) {
                    153:                        DOTsave(&save);
                    154:                        ToIndent();
                    155:                        margin = calc_pos(linebuf, curchar);
                    156:                        SetDot(&save);
                    157:                } else
                    158:                        margin = LMargin;
                    159:                DoJustify(curline, 0, curline,
                    160:                          curchar + (int)strlen(&linebuf[curchar]), 1, margin);
                    161:        }
                    162: }
                    163: 
                    164: void
                    165: Insert(c)
                    166: int    c;
                    167: {
                    168:        if (c == CTL('J'))
                    169:                LineInsert(arg_value());
                    170:        else
                    171:                insert_c(c, arg_value());
                    172: }
                    173: 
                    174: /* insert character C N times at point */
                    175: void
                    176: insert_c(c, n)
                    177: int    c,
                    178:        n;
                    179: {
                    180:        if (n <= 0)
                    181:                return;
                    182:        modify();
                    183:        makedirty(curline);
                    184:        ins_c(c, linebuf, curchar, n, LBSIZE);
                    185:        IFixMarks(curline, curchar, curline, curchar + n);
                    186:        curchar += n;
                    187: }
                    188: 
                    189: /* Tab in to the right place for C mode */
                    190: 
                    191: void
                    192: Tab()
                    193: {
                    194: #ifdef LISP
                    195:        if (MajorMode(LISPMODE) && (bolp() || !eolp())) {
                    196:                int     dotchar = curchar;
                    197:                Mark    *m = 0;
                    198: 
                    199:                ToIndent();
                    200:                if (dotchar > curchar)
                    201:                        m = MakeMark(curline, dotchar, M_FLOATER);
                    202:                (void) lisp_indent();
                    203:                if (m) {
                    204:                        ToMark(m);
                    205:                        DelMark(m);
                    206:                } else
                    207:                        ToIndent();
                    208:                return;
                    209:        }
                    210: #endif
                    211:        if (MajorMode(CMODE)) {
                    212:                if (within_indent())
                    213:                        (void) c_indent(NO);
                    214:                else {
                    215:                        int     curpos,
                    216:                                tabbed_pos;
                    217: 
                    218:                        skip_wht_space();
                    219:                        curpos = calc_pos(linebuf, curchar);
                    220:                        tabbed_pos = curpos + (CIndIncrmt - (curpos % CIndIncrmt));
                    221:                        n_indent(tabbed_pos);
                    222:                }
                    223:        } else
                    224:                SelfInsert();
                    225: }
                    226: 
                    227: void
                    228: QuotChar()
                    229: {
                    230:        int     c,
                    231:                slow = NO;
                    232: 
                    233:        c = waitchar(&slow);
                    234:        if (c != CTL('@'))
                    235:                Insert(c);
                    236: }
                    237: 
                    238: /* Insert the paren.  If in C mode and c is a '}' then insert the
                    239:    '}' in the "right" place for C indentation; that is indented
                    240:    the same amount as the matching '{' is indented. */
                    241: 
                    242: int    PDelay = 5,     /* 1/2 a second */
                    243:        CIndIncrmt = 8;
                    244: 
                    245: void
                    246: DoParen()
                    247: {
                    248:        Bufpos  *bp;
                    249:        int     tried = NO,
                    250:                nx,
                    251:                c = LastKeyStruck;
                    252: 
                    253:        if (!isclosep(c)) {
                    254:                SelfInsert();
                    255:                return;
                    256:        }
                    257: 
                    258:        if (MajorMode(CMODE) && c == '}' && within_indent()) {
                    259:                bp = c_indent(YES);
                    260:                tried = TRUE;
                    261:        }
                    262: #ifdef LISP
                    263:        if (MajorMode(LISPMODE) && c == ')' && blnkp(linebuf)) {
                    264:                bp = lisp_indent();
                    265:                tried = TRUE;
                    266:        }
                    267: #endif
                    268:        SelfInsert();
                    269: #ifdef MAC
                    270:        if (MinorMode(ShowMatch) && !in_macro()) {
                    271: #else
                    272:        if (MinorMode(ShowMatch) && !charp() && !in_macro()) {
                    273: #endif
                    274:                b_char(1);      /* Back onto the ')' */
                    275:                if (!tried)
                    276:                        bp = m_paren(c, BACKWARD, NO, YES);
                    277:                f_char(1);
                    278:                if (bp != 0) {
                    279:                        nx = in_window(curwind, bp->p_line);
                    280:                        if (nx != -1) {         /* is visible */
                    281:                                Bufpos  b;
                    282: 
                    283:                                DOTsave(&b);
                    284:                                SetDot(bp);
                    285:                                SitFor(PDelay);
                    286:                                SetDot(&b);
                    287:                        } else
                    288:                                s_mess("%s", lcontents(bp->p_line));
                    289:                }
                    290:                mp_error();     /* display error message */
                    291:        }
                    292: }
                    293: 
                    294: void
                    295: LineAI()
                    296: {
                    297:        DoNewline(TRUE);
                    298: }
                    299: 
                    300: void
                    301: Newline()
                    302: {
                    303:        DoNewline(MinorMode(Indent));
                    304: }
                    305: 
                    306: private void
                    307: DoNewline(indentp)
                    308: int    indentp;
                    309: {
                    310:        Bufpos  save;
                    311:        int     indent;
                    312: 
                    313:        /* first we calculate the indent of the current line */
                    314:        DOTsave(&save);
                    315:        ToIndent();
                    316:        indent = calc_pos(linebuf, curchar);
                    317:        SetDot(&save);
                    318: 
                    319: #ifdef ABBREV
                    320:        MaybeAbbrevExpand();
                    321: #endif
                    322: #ifdef LISP
                    323:        if (MajorMode(LISPMODE))
                    324:                DelWtSpace();
                    325:        else
                    326: #endif
                    327:            if (indentp || blnkp(linebuf))
                    328:                DelWtSpace();
                    329: 
                    330:        /* If there is more than 2 blank lines in a row then don't make
                    331:           a newline, just move down one. */
                    332:        if (arg_value() == 1 && eolp() && TwoBlank())
                    333:                SetLine(curline->l_next);
                    334:        else
                    335:                LineInsert(arg_value());
                    336: 
                    337:        if (indentp)
                    338: #ifdef LISP
                    339:            if (MajorMode(LISPMODE))
                    340:                (void) lisp_indent();
                    341:            else
                    342: #endif
                    343:            {
                    344:                Bol();
                    345:                n_indent((LMargin == 0) ? indent : LMargin);
                    346:            }
                    347: }
                    348: 
                    349: void
                    350: ins_str(str, ok_nl)
                    351: register char  *str;
                    352: int    ok_nl;
                    353: {
                    354:        register char   c;
                    355:        Bufpos  save;
                    356:        int     llen;
                    357: 
                    358:        if (*str == 0)
                    359:                return;         /* ain't nothing to insert! */
                    360:        DOTsave(&save);
                    361:        llen = strlen(linebuf);
                    362:        while ((c = *str++) != '\0') {
                    363:                if (c == '\n' || (ok_nl && llen >= LBSIZE - 2)) {
                    364:                        IFixMarks(save.p_line, save.p_char, curline, curchar);
                    365:                        modify();
                    366:                        makedirty(curline);
                    367:                        LineInsert(1);
                    368:                        DOTsave(&save);
                    369:                        llen = strlen(linebuf);
                    370:                }
                    371:                if (c != '\n') {
                    372:                        ins_c(c, linebuf, curchar++, 1, LBSIZE);
                    373:                        llen += 1;
                    374:                }
                    375:        }
                    376:        IFixMarks(save.p_line, save.p_char, curline, curchar);
                    377:        modify();
                    378:        makedirty(curline);
                    379: }
                    380: 
                    381: void
                    382: open_lines(n)
                    383: int    n;
                    384: {
                    385:        Bufpos  dot;
                    386: 
                    387:        DOTsave(&dot);
                    388:        LineInsert(n);  /* Open the lines... */
                    389:        SetDot(&dot);
                    390: }
                    391: 
                    392: void
                    393: OpenLine()
                    394: {
                    395:        open_lines(arg_value());
                    396: }
                    397: 
                    398: /* Take the region FLINE/FCHAR to TLINE/TCHAR and insert it at
                    399:    ATLINE/ATCHAR in WHATBUF. */
                    400: 
                    401: Bufpos *
                    402: DoYank(fline, fchar, tline, tchar, atline, atchar, whatbuf)
                    403: Line   *fline,
                    404:        *tline,
                    405:        *atline;
                    406: int    fchar,
                    407:        tchar,
                    408:        atchar;
                    409: Buffer *whatbuf;
                    410: {
                    411:        register Line   *newline;
                    412:        static Bufpos   bp;
                    413:        char    save[LBSIZE],
                    414:                buf[LBSIZE];
                    415:        Line    *startline = atline;
                    416:        int     startchar = atchar;
                    417: 
                    418:        lsave();
                    419:        if (whatbuf)
                    420:                modify();
                    421:        (void) ltobuf(atline, genbuf);
                    422:        strcpy(save, &genbuf[atchar]);
                    423: 
                    424:        (void) ltobuf(fline, buf);
                    425:        if (fline == tline)
                    426:                buf[tchar] = '\0';
                    427: 
                    428:        linecopy(genbuf, atchar, &buf[fchar]);
                    429:        atline->l_dline = putline(genbuf);
                    430:        makedirty(atline);
                    431: 
                    432:        fline = fline->l_next;
                    433:        while (fline != tline->l_next) {
                    434:                newline = listput(whatbuf, atline);
                    435:                newline->l_dline = fline->l_dline;
                    436:                makedirty(newline);
                    437:                fline = fline->l_next;
                    438:                atline = newline;
                    439:                atchar = 0;
                    440:        }
                    441: 
                    442:        getline(atline->l_dline, genbuf);
                    443:        atchar += tchar;
                    444:        linecopy(genbuf, atchar, save);
                    445:        atline->l_dline = putline(genbuf);
                    446:        makedirty(atline);
                    447:        IFixMarks(startline, startchar, atline, atchar);
                    448:        bp.p_line = atline;
                    449:        bp.p_char = atchar;
                    450:        this_cmd = YANKCMD;
                    451:        getDOT();                       /* Whatever used to be in linebuf */
                    452:        return &bp;
                    453: }
                    454: 
                    455: void
                    456: YankPop()
                    457: {
                    458:        Line    *line,
                    459:                *last;
                    460:        Mark    *mp = CurMark();
                    461:        Bufpos  *dot;
                    462:        int     dir = -1;       /* Direction to rotate the ring */
                    463: 
                    464:        if (last_cmd != YANKCMD)
                    465:                complain("Yank something first!");
                    466: 
                    467:        lfreelist(reg_delete(mp->m_line, mp->m_char, curline, curchar));
                    468: 
                    469:        /* Now must find a recently killed region. */
                    470: 
                    471:        if (arg_value() < 0)
                    472:                dir = 1;
                    473: 
                    474:        killptr += dir;
                    475:        for (;;) {
                    476:                if (killptr < 0)
                    477:                        killptr = NUMKILLS - 1;
                    478:                else if (killptr >= NUMKILLS)
                    479:                        killptr = 0;
                    480:                if (killbuf[killptr])
                    481:                        break;
                    482:                killptr += dir;
                    483:        }
                    484: 
                    485:        this_cmd = YANKCMD;
                    486: 
                    487:        line = killbuf[killptr];
                    488:        last = lastline(line);
                    489:        dot = DoYank(line, 0, last, length(last), curline, curchar, curbuf);
                    490:        MarkSet(CurMark(), curline, curchar);
                    491:        SetDot(dot);
                    492: }
                    493: 
                    494: /* This is an attempt to reduce the amount of memory taken up by each line.
                    495:    Without this each malloc of a line uses sizeof (line) + sizeof(HEADER)
                    496:    where line is 3 words and HEADER is 1 word.
                    497:    This is going to allocate memory in chucks of CHUNKSIZE * sizeof (line)
                    498:    and divide each chuck into lineS.  A line is free in a chunk when its
                    499:    line->l_dline == 0, so freeline sets dline to 0. */
                    500: 
                    501: #define CHUNKSIZE      300
                    502: 
                    503: struct chunk {
                    504:        int     c_nlines;       /* Number of lines in this chunk (so they
                    505:                                   don't all have to be CHUNKSIZE long). */
                    506:        Line    *c_block;       /* Chunk of memory */
                    507:        struct chunk    *c_nextfree;    /* Next chunk of lines */
                    508: };
                    509: 
                    510: private struct chunk   *fchunk = 0;
                    511: private Line   *ffline = 0;    /* First free line */
                    512: 
                    513: void
                    514: freeline(line)
                    515: register Line  *line;
                    516: {
                    517:        line->l_dline = 0;
                    518:        line->l_next = ffline;
                    519:        if (ffline)
                    520:                ffline->l_prev = line;
                    521:        line->l_prev = 0;
                    522:        ffline = line;
                    523: }
                    524: 
                    525: void
                    526: lfreelist(first)
                    527: register Line  *first;
                    528: {
                    529:        if (first)
                    530:                lfreereg(first, lastline(first));
                    531: }
                    532: 
                    533: /* Append region from line1 to line2 onto the free list of lines */
                    534: 
                    535: void
                    536: lfreereg(line1, line2)
                    537: register Line  *line1,
                    538:                *line2;
                    539: {
                    540:        register Line   *next,
                    541:                        *last = line2->l_next;
                    542: 
                    543:        while (line1 != last) {
                    544:                next = line1->l_next;
                    545:                freeline(line1);
                    546:                line1 = next;
                    547:        }
                    548: }
                    549: 
                    550: private int
                    551: newchunk()
                    552: {
                    553:        register Line   *newline;
                    554:        register int    i;
                    555:        struct chunk    *f;
                    556:        int     nlines = CHUNKSIZE;
                    557: 
                    558:        f = (struct chunk *) emalloc(sizeof (struct chunk));
                    559:        if (f == 0)
                    560:                return 0;
                    561: 
                    562:        if ((f->c_block = (Line *) malloc((unsigned) (sizeof (Line) * nlines))) == 0) {
                    563:                while (nlines > 0) {
                    564:                        f->c_block = (Line *) malloc((unsigned) (sizeof (Line) * nlines));
                    565:                        if (f->c_block != 0)
                    566:                                break;
                    567:                        nlines /= 2;
                    568:                }
                    569:        }
                    570: 
                    571:        if (nlines <= 0)
                    572:                return 0;
                    573: 
                    574:        f->c_nlines = nlines;
                    575:        for (i = 0, newline = f->c_block; i < nlines; newline++, i++)
                    576:                freeline(newline);
                    577:        f->c_nextfree = fchunk;
                    578:        fchunk = f;
                    579:        return 1;
                    580: }
                    581: 
                    582: /* New BUFfer LINE */
                    583: 
                    584: Line *
                    585: nbufline()
                    586: {
                    587:        register Line   *newline;
                    588: 
                    589:        if (ffline == 0)        /* No free list */
                    590:                if (newchunk() == 0)
                    591:                        complain("[Out of lines] ");
                    592:        newline = ffline;
                    593:        ffline = ffline->l_next;
                    594:        if (ffline)
                    595:                ffline->l_prev = 0;
                    596:        return newline;
                    597: }
                    598: 
                    599: /* Remove the free lines, in chunk c, from the free list because they are
                    600:    no longer free. */
                    601: 
                    602: private void
                    603: remfreelines(c)
                    604: register struct chunk  *c;
                    605: {
                    606:        register Line   *lp;
                    607:        register int    i;
                    608: 
                    609:        for (lp = c->c_block, i = 0; i < c->c_nlines; i++, lp++) {
                    610:                if (lp->l_prev)
                    611:                        lp->l_prev->l_next = lp->l_next;
                    612:                else
                    613:                        ffline = lp->l_next;
                    614:                if (lp->l_next)
                    615:                        lp->l_next->l_prev = lp->l_prev;
                    616:        }
                    617: }
                    618: 
                    619: /* This is used to garbage collect the chunks of lines when malloc fails
                    620:    and we are NOT looking for a new buffer line.  This goes through each
                    621:    chunk, and if every line in a given chunk is not allocated, the entire
                    622:    chunk is `free'd by "free()". */
                    623: 
                    624: void
                    625: GCchunks()
                    626: {
                    627:        register struct chunk   *cp;
                    628:        struct chunk    *prev = 0,
                    629:                        *next = 0;
                    630:        register int    i;
                    631:        register Line   *newline;
                    632: 
                    633:        for (cp = fchunk; cp != 0; cp = next) {
                    634:                for (i = 0, newline = cp->c_block; i < cp->c_nlines; newline++, i++)
                    635:                        if (newline->l_dline != 0)
                    636:                                break;
                    637: 
                    638:                next = cp->c_nextfree;
                    639: 
                    640:                if (i == cp->c_nlines) {                /* Unlink it!!! */
                    641:                        if (prev)
                    642:                                prev->c_nextfree = cp->c_nextfree;
                    643:                        else
                    644:                                fchunk = cp->c_nextfree;
                    645:                        remfreelines(cp);
                    646:                        free((char *) cp->c_block);
                    647:                        free((char *) cp);
                    648:                } else
                    649:                        prev = cp;
                    650:        }
                    651: }
                    652: 
                    653: #ifdef LISP
                    654: 
                    655: #include "re.h"
                    656: 
                    657: /* Grind S-Expr */
                    658: 
                    659: void
                    660: GSexpr()
                    661: {
                    662:        Bufpos  dot,
                    663:                end;
                    664: 
                    665:        if (linebuf[curchar] != '(')
                    666:                complain((char *) 0);
                    667:        DOTsave(&dot);
                    668:        FSexpr();
                    669:        DOTsave(&end);
                    670:        SetDot(&dot);
                    671:        for (;;) {
                    672:                if (curline == end.p_line)
                    673:                        break;
                    674:                line_move(FORWARD, 1, NO);
                    675:                if (!blnkp(linebuf))
                    676:                        (void) lisp_indent();
                    677:        }
                    678:        SetDot(&dot);
                    679: }
                    680: 
                    681: /* lisp_indent() indents a new line in Lisp Mode, according to where
                    682:    the matching close-paren would go if we typed that (sort of). */
                    683: 
                    684: private List   *specials = NIL;
                    685: 
                    686: private void
                    687: init_specials()
                    688: {
                    689:        static char *const words[] = {
                    690:                "case",
                    691:                "def",
                    692:                "dolist",
                    693:                "fluid-let",
                    694:                "lambda",
                    695:                "let",
                    696:                "lexpr",
                    697:                "macro",
                    698:                "named-l",      /* named-let and named-lambda */
                    699:                "nlambda",
                    700:                "prog",
                    701:                "selectq",
                    702:                0
                    703:        };
                    704:        char    *const *wordp = words;
                    705: 
                    706:        while (*wordp)
                    707:                list_push(&specials, (Element *) *wordp++);
                    708: }
                    709: 
                    710: void
                    711: AddSpecial()
                    712: {
                    713:        char    *word;
                    714:        register List   *lp;
                    715: 
                    716:        if (specials == NIL)
                    717:                init_specials();
                    718:        word = ask((char *) 0, ProcFmt);
                    719:        for (lp = specials; lp != NIL; lp = list_next(lp))
                    720:                if (strcmp((char *) list_data(lp), word) == 0)
                    721:                        return;         /* already in list */
                    722:        (void) list_push(&specials, (Element *) copystr(word));
                    723: }
                    724: 
                    725: Bufpos *
                    726: lisp_indent()
                    727: {
                    728:        Bufpos  *bp,
                    729:                savedot;
                    730:        int     goal;
                    731: 
                    732:        bp = m_paren(')', BACKWARD, NO, YES);
                    733: 
                    734:        if (bp == NULL)
                    735:                return NULL;
                    736: 
                    737:        /* We want to end up
                    738: 
                    739:                (atom atom atom ...
                    740:                      ^ here.
                    741:         */
                    742: 
                    743:        DOTsave(&savedot);
                    744:        SetDot(bp);
                    745:        f_char(1);
                    746:        if (linebuf[curchar] != '(') {
                    747:                register List   *lp;
                    748: 
                    749:                if (specials == NIL)
                    750:                        init_specials();
                    751:                for (lp = specials; lp != NIL; lp = list_next(lp))
                    752:                        if (casencmp((char *) list_data(lp),
                    753:                                     &linebuf[curchar],
                    754:                                     strlen((char *) list_data(lp))) == 0)
                    755:                                break;
                    756:                if (lp == NIL) {        /* not special */
                    757:                        int     c_char = curchar;
                    758: 
                    759:                        WITH_TABLE(curbuf->b_major)
                    760:                                f_word(1);
                    761:                        END_TABLE();
                    762:                        if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar))
                    763:                                curchar = c_char;
                    764:                        else while (linebuf[curchar] == ' ')
                    765:                                curchar += 1;
                    766:                } else
                    767:                        curchar += 1;
                    768:        }
                    769:        goal = calc_pos(linebuf, curchar);
                    770:        SetDot(&savedot);
                    771:        Bol();
                    772:        n_indent(goal);
                    773: 
                    774:        return bp;
                    775: }
                    776: #endif /* LISP */

unix.superglobalmegacorp.com

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