Annotation of 43BSDReno/contrib/jove/insert.c, revision 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.