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

unix.superglobalmegacorp.com

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