Annotation of coherent/g/usr/bin/vi/input.c, revision 1.1

1.1     ! root        1: /* input.c */
        !             2: 
        !             3: /* Author:
        !             4:  *     Steve Kirkendall
        !             5:  *     14407 SW Teal Blvd. #C
        !             6:  *     Beaverton, OR 97005
        !             7:  *     [email protected]
        !             8:  */
        !             9: 
        !            10: 
        !            11: /* This file contains the input() function, which implements vi's INPUT mode.
        !            12:  * It also contains the code that supports digraphs.
        !            13:  */
        !            14: 
        !            15: #include "config.h"
        !            16: #include "ctype.h"
        !            17: #include "vi.h"
        !            18: 
        !            19: 
        !            20: #ifndef NO_DIGRAPH
        !            21: static struct _DIG
        !            22: {
        !            23:        struct _DIG     *next;
        !            24:        char            key1;
        !            25:        char            key2;
        !            26:        char            dig;
        !            27:        char            save;
        !            28: } *digs;
        !            29: 
        !            30: char digraph(key1, key2)
        !            31:        int     key1;   /* the underlying character */
        !            32:        int     key2;   /* the second character */
        !            33: {
        !            34:        int             newkey;
        !            35:        REG struct _DIG *dp;
        !            36: 
        !            37:        /* if digraphs are disabled, then just return the new char */
        !            38:        if (!*o_digraph)
        !            39:        {
        !            40:                return key2;
        !            41:        }
        !            42: 
        !            43:        /* remember the new key, so we can return it if this isn't a digraph */
        !            44:        newkey = key2;
        !            45: 
        !            46:        /* sort key1 and key2, so that their original order won't matter */
        !            47:        if (key1 > key2)
        !            48:        {
        !            49:                key2 = key1;
        !            50:                key1 = newkey;
        !            51:        }
        !            52: 
        !            53:        /* scan through the digraph chart */
        !            54:        for (dp = digs;
        !            55:             dp && (dp->key1 != key1 || dp->key2 != key2);
        !            56:             dp = dp->next)
        !            57:        {
        !            58:        }
        !            59: 
        !            60:        /* if this combination isn't in there, just use the new key */
        !            61:        if (!dp)
        !            62:        {
        !            63:                return newkey;
        !            64:        }
        !            65: 
        !            66:        /* else use the digraph key */
        !            67:        return dp->dig;
        !            68: }
        !            69: 
        !            70: /* this function lists or defines digraphs */
        !            71: void do_digraph(bang, extra)
        !            72:        int     bang;
        !            73:        char    extra[];
        !            74: {
        !            75:        int             dig;
        !            76:        REG struct _DIG *dp;
        !            77:        struct _DIG     *prev;
        !            78:        static int      user_defined = FALSE; /* boolean: are all later digraphs user-defined? */
        !            79:        char            listbuf[8];
        !            80: 
        !            81:        /* if "extra" is NULL, then we've reached the end of the built-ins */
        !            82:        if (!extra)
        !            83:        {
        !            84:                user_defined = TRUE;
        !            85:                return;
        !            86:        }
        !            87: 
        !            88:        /* if no args, then display the existing digraphs */
        !            89:        if (*extra < ' ')
        !            90:        {
        !            91:                listbuf[0] = listbuf[1] = listbuf[2] = listbuf[5] = ' ';
        !            92:                listbuf[7] = '\0';
        !            93:                for (dig = 0, dp = digs; dp; dp = dp->next)
        !            94:                {
        !            95:                        if (dp->save || bang)
        !            96:                        {
        !            97:                                dig += 7;
        !            98:                                if (dig >= COLS)
        !            99:                                {
        !           100:                                        addch('\n');
        !           101:                                        exrefresh();
        !           102:                                        dig = 7;
        !           103:                                }
        !           104:                                listbuf[3] = dp->key1;
        !           105:                                listbuf[4] = dp->key2;
        !           106:                                listbuf[6] = dp->dig;
        !           107:                                qaddstr(listbuf);
        !           108:                        }
        !           109:                }
        !           110:                addch('\n');
        !           111:                exrefresh();
        !           112:                return;
        !           113:        }
        !           114: 
        !           115:        /* make sure we have at least two characters */
        !           116:        if (!extra[1])
        !           117:        {
        !           118:                msg("Digraphs must be composed of two characters");
        !           119:                return;
        !           120:        }
        !           121: 
        !           122:        /* sort key1 and key2, so that their original order won't matter */
        !           123:        if (extra[0] > extra[1])
        !           124:        {
        !           125:                dig = extra[0];
        !           126:                extra[0] = extra[1];
        !           127:                extra[1] = dig;
        !           128:        }
        !           129: 
        !           130:        /* locate the new digraph character */
        !           131:        for (dig = 2; extra[dig] == ' ' || extra[dig] == '\t'; dig++)
        !           132:        {
        !           133:        }
        !           134:        dig = extra[dig];
        !           135:        if (!bang && dig)
        !           136:        {
        !           137:                dig |= 0x80;
        !           138:        }
        !           139: 
        !           140:        /* search for the digraph */
        !           141:        for (prev = (struct _DIG *)0, dp = digs;
        !           142:             dp && (dp->key1 != extra[0] || dp->key2 != extra[1]);
        !           143:             prev = dp, dp = dp->next)
        !           144:        {
        !           145:        }
        !           146: 
        !           147:        /* deleting the digraph? */
        !           148:        if (!dig)
        !           149:        {
        !           150:                if (!dp)
        !           151:                {
        !           152: #ifndef CRUNCH
        !           153:                        msg("%c%c not a digraph", extra[0], extra[1]);
        !           154: #endif
        !           155:                        return;
        !           156:                }
        !           157:                if (prev)
        !           158:                        prev->next = dp->next;
        !           159:                else
        !           160:                        digs = dp->next;
        !           161:                _free_(dp);
        !           162:                return;
        !           163:        }
        !           164: 
        !           165:        /* if necessary, create a new digraph struct for the new digraph */
        !           166:        if (dig && !dp)
        !           167:        {
        !           168:                dp = (struct _DIG *)malloc(sizeof *dp);
        !           169:                if (!dp)
        !           170:                {
        !           171:                        msg("Out of space in the digraph table");
        !           172:                        return;
        !           173:                }
        !           174:                if (prev)
        !           175:                        prev->next = dp;
        !           176:                else
        !           177:                        digs = dp;
        !           178:                dp->next = (struct _DIG *)0;
        !           179:        }
        !           180: 
        !           181:        /* assign it the new digraph value */
        !           182:        dp->key1 = extra[0];
        !           183:        dp->key2 = extra[1];
        !           184:        dp->dig = dig;
        !           185:        dp->save = user_defined;
        !           186: }
        !           187: 
        !           188: # ifndef NO_MKEXRC
        !           189: void savedigs(fd)
        !           190:        int             fd;
        !           191: {
        !           192:        static char     buf[] = "digraph! XX Y\n";
        !           193:        REG struct _DIG *dp;
        !           194: 
        !           195:        for (dp = digs; dp; dp = dp->next)
        !           196:        {
        !           197:                if (dp->save)
        !           198:                {
        !           199:                        buf[9] = dp->key1;
        !           200:                        buf[10] = dp->key2;
        !           201:                        buf[12] = dp->dig;
        !           202:                        write(fd, buf, (unsigned)14);
        !           203:                }
        !           204:        }
        !           205: }
        !           206: # endif
        !           207: #endif
        !           208: 
        !           209: 
        !           210: /* This function allows the user to replace an existing (possibly zero-length)
        !           211:  * chunk of text with typed-in text.  It returns the MARK of the last character
        !           212:  * that the user typed in.
        !           213:  */
        !           214: MARK input(from, to, when, delta)
        !           215:        MARK    from;   /* where to start inserting text */
        !           216:        MARK    to;     /* extent of text to delete */
        !           217:        int     when;   /* either WHEN_VIINP or WHEN_VIREP */
        !           218:        int     delta;  /* 1 to take indent from lower line, -1 for upper, 0 for none */
        !           219: {
        !           220:        char    key[2]; /* key char followed by '\0' char */
        !           221:        char    *build; /* used in building a newline+indent string */
        !           222:        char    *scan;  /* used while looking at the indent chars of a line */
        !           223:        MARK    m;      /* some place in the text */
        !           224: #ifndef NO_EXTENSIONS
        !           225:        int     quit = FALSE;   /* boolean: are we exiting after this? */
        !           226:        int     inchg;  /* boolean: have we done a "beforedo()" yet? */
        !           227: #endif
        !           228: 
        !           229: #ifdef DEBUG
        !           230:        /* if "from" and "to" are reversed, complain */
        !           231:        if (from > to)
        !           232:        {
        !           233:                msg("ERROR: input(%ld:%d, %ld:%d)",
        !           234:                        markline(from), markidx(from),
        !           235:                        markline(to), markidx(to));
        !           236:                return MARK_UNSET;
        !           237:        }
        !           238: #endif
        !           239: 
        !           240:        key[1] = 0;
        !           241: 
        !           242:        /* if we're replacing text with new text, save the old stuff */
        !           243:        /* (Alas, there is no easy way to save text for replace mode) */
        !           244:        if (from != to)
        !           245:        {
        !           246:                cut(from, to);
        !           247:        }
        !           248: 
        !           249:        /* if doing a dot command, then reuse the previous text */
        !           250:        if (doingdot)
        !           251:        {
        !           252:                ChangeText
        !           253:                {
        !           254:                        /* delete the text that's there now */
        !           255:                        if (from != to)
        !           256:                        {
        !           257:                                delete(from, to);
        !           258:                        }
        !           259: 
        !           260:                        /* insert the previous text */
        !           261:                        cutname('.');
        !           262:                        cursor = paste(from, FALSE, TRUE) + 1L;
        !           263:                }
        !           264:        }
        !           265:        else /* interactive version */
        !           266:        {
        !           267:                /* assume that whoever called this already did a beforedo() */
        !           268: #ifndef NO_EXTENSIONS
        !           269:                inchg = TRUE;
        !           270: #endif
        !           271: 
        !           272:                /* if doing a change within the line... */
        !           273:                if (from != to && markline(from) == markline(to))
        !           274:                {
        !           275:                        /* mark the end of the text with a "$" */
        !           276:                        change(to - 1, to, "$");
        !           277:                }
        !           278:                else
        !           279:                {
        !           280:                        /* delete the old text right off */
        !           281:                        if (from != to)
        !           282:                        {
        !           283:                                delete(from, to);
        !           284:                        }
        !           285:                        to = from;
        !           286:                }
        !           287: 
        !           288:                /* handle autoindent of the first line, maybe */
        !           289:                cursor = from;
        !           290:                m = cursor + MARK_AT_LINE(delta);
        !           291:                if (delta != 0 && *o_autoindent && markidx(m) == 0
        !           292:                 && markline(m) >= 1L && markline(m) <= nlines)
        !           293:                {
        !           294:                        /* Only autoindent blank lines. */
        !           295:                        pfetch(markline(cursor));
        !           296:                        if (plen == 0)
        !           297:                        {
        !           298:                                /* Okay, we really want to autoindent */
        !           299:                                pfetch(markline(m));
        !           300:                                for (scan = ptext, build = tmpblk.c;
        !           301:                                     *scan == ' ' || *scan == '\t';
        !           302:                                     )
        !           303:                                {
        !           304:                                        *build++ = *scan++;
        !           305:                                }
        !           306:                                if (build > tmpblk.c)
        !           307:                                {
        !           308:                                        *build = '\0';
        !           309:                                        add(cursor, tmpblk.c);
        !           310:                                        cursor += (int)(build - tmpblk.c);
        !           311:                                        if (cursor > to)
        !           312:                                                to = cursor;
        !           313:                                }
        !           314:                        }
        !           315:                }
        !           316: 
        !           317:                /* repeatedly add characters from the user */
        !           318:                for (;;)
        !           319:                {
        !           320:                        /* Get a character */
        !           321:                        redraw(cursor, TRUE);
        !           322: #ifdef DEBUG2
        !           323:                        msg("cursor=%ld.%d, to=%ld.%d",
        !           324:                                markline(cursor), markidx(cursor),
        !           325:                                markline(to), markidx(to));
        !           326: #endif
        !           327: #ifndef NO_ABBR
        !           328:                        pfetch(markline(cursor));
        !           329:                        build = ptext;
        !           330:                        if (pline == markline(from))
        !           331:                                build += markidx(from);
        !           332:                        for (scan = ptext + markidx(cursor); --scan >= build && isalnum(*scan); )
        !           333:                        {
        !           334:                        }
        !           335:                        scan++;
        !           336:                        key[0] = getabkey(when, scan, (int)(ptext + markidx(cursor) - scan));
        !           337: #else
        !           338:                        key[0] = getkey(when);
        !           339: #endif
        !           340: #ifndef NO_VISIBLE
        !           341:                        if (key[0] != '\0' && V_from != MARK_UNSET)
        !           342:                        {
        !           343:                                msg("Can't modify text during a selection");
        !           344:                                beep();
        !           345:                                continue;
        !           346:                        }
        !           347: #endif
        !           348: 
        !           349: #ifndef NO_EXTENSIONS
        !           350:                        if (key[0] == ctrl('O'))
        !           351:                        {
        !           352:                                if (inchg)
        !           353:                                {
        !           354:                                        if (cursor < to)
        !           355:                                        {
        !           356:                                                delete(cursor, to);
        !           357:                                                redraw(cursor, TRUE);
        !           358:                                        }
        !           359:                                        afterdo();
        !           360:                                        inchg = FALSE;
        !           361:                                }
        !           362:                        }
        !           363:                        else if (key[0] != ctrl('['))
        !           364:                        {
        !           365:                                if (!inchg)
        !           366:                                {
        !           367:                                        beforedo(FALSE);
        !           368:                                        inchg = TRUE;
        !           369:                                }
        !           370:                        }
        !           371: #endif
        !           372: 
        !           373: #ifndef CRUNCH
        !           374:                        /* if wrapmargin is set & we're past the
        !           375:                         * warpmargin, then change the last whitespace
        !           376:                         * characters on line into a newline
        !           377:                         */
        !           378:                        if (*o_wrapmargin != 0)
        !           379:                        {
        !           380:                                pfetch(markline(cursor));
        !           381:                                if (plen == idx2col(cursor, ptext, TRUE)
        !           382:                                 && plen > COLS - (*o_wrapmargin & 0xff))
        !           383:                                {
        !           384:                                        build = tmpblk.c;
        !           385:                                        *build++ = '\n';
        !           386:                                        if (*o_autoindent)
        !           387:                                        {
        !           388:                                                /* figure out indent for next line */
        !           389:                                                for (scan = ptext; *scan == ' ' || *scan == '\t'; )
        !           390:                                                {
        !           391:                                                        *build++ = *scan++;
        !           392:                                                }
        !           393:                                        }
        !           394:                                        *build = '\0';
        !           395: 
        !           396:                                        scan = ptext + plen;
        !           397:                                        m = cursor & ~(BLKSIZE - 1);
        !           398:                                        while (ptext < scan)
        !           399:                                        {
        !           400:                                                scan--;
        !           401:                                                if (*scan != ' ' && *scan != '\t')
        !           402:                                                        continue;
        !           403: 
        !           404:                                                /*break up line, and we do autoindent if needed*/
        !           405:                                                change(m + (int)(scan - ptext), m + (int)(scan - ptext) + 1, tmpblk.c);
        !           406: 
        !           407:                                                /* NOTE: for some reason, MSC 5.10 doesn't
        !           408:                                                 * like for these lines to be combined!!!
        !           409:                                                 */
        !           410:                                                cursor = (cursor & ~(BLKSIZE - 1));
        !           411:                                                cursor += BLKSIZE;
        !           412:                                                cursor += strlen(tmpblk.c) - 1;
        !           413:                                                cursor += plen - (int)(scan - ptext) - 1;
        !           414: 
        !           415:                                                /*remove trailing spaces on previous line*/
        !           416:                                                pfetch(markline(m));
        !           417:                                                scan = ptext + plen;
        !           418:                                                while (ptext < scan)
        !           419:                                                {
        !           420:                                                        scan--;
        !           421:                                                        if (*scan != ' ' && *scan != '\t')
        !           422:                                                                break;
        !           423:                                                }
        !           424:                                                delete(m + (int)(scan - ptext) + 1, m + plen);
        !           425: 
        !           426:                                                break;
        !           427:                                        }
        !           428:                                }
        !           429:                        }
        !           430: #endif /* !CRUNCH */
        !           431: 
        !           432:                        /* process it */
        !           433:                        switch (*key)
        !           434:                        {
        !           435: #ifndef NO_EXTENSIONS
        !           436:                          case ctrl('O'): /* special movement mapped keys */
        !           437:                                *key = getkey(0);
        !           438:                                switch (*key)
        !           439:                                {
        !           440:                                  case 'h':     m = m_left(cursor, 0L);         break;
        !           441:                                  case 'j':
        !           442:                                  case 'k':     m = m_updnto(cursor, 0L, *key); break;
        !           443:                                  case 'l':     m = cursor + 1;                 break;
        !           444:                                  case 'B':
        !           445:                                  case 'b':     m = m_bword(cursor, 0L, *key);  break;
        !           446:                                  case 'W':
        !           447:                                  case 'w':     m = m_fword(cursor, 0L, *key, '\0');    break;
        !           448:                                  case '^':     m = m_front(cursor, 0L);        break;
        !           449:                                  case '$':     m = m_rear(cursor, 0L);         break;
        !           450:                                  case ctrl('B'):
        !           451:                                  case ctrl('F'):
        !           452:                                                m = m_scroll(cursor, 0L, *key); break;
        !           453:                                  case 'x':
        !           454: #ifndef NO_VISIBLE
        !           455:                                                if (V_from)
        !           456:                                                        beep();
        !           457:                                                else
        !           458: #endif
        !           459:                                                ChangeText
        !           460:                                                {
        !           461:                                                        m = v_xchar(cursor, 0L, 'x');
        !           462:                                                }
        !           463:                                                break;
        !           464:                                  case 'i':     m = to = from = cursor;
        !           465:                                                when = WHEN_VIINP + WHEN_VIREP - when;
        !           466:                                                                                break;
        !           467:                                  case 'K':
        !           468:                                        pfetch(markline(cursor));
        !           469:                                        changes++; /* <- after this, we can alter ptext */
        !           470:                                        ptext[markidx(cursor)] = 0;
        !           471:                                        for (scan = ptext + markidx(cursor) - 1;
        !           472:                                             scan >= ptext && isalnum(*scan);
        !           473:                                             scan--)
        !           474:                                        {
        !           475:                                        }
        !           476:                                        scan++;
        !           477:                                        m = (*scan ? v_keyword(scan, cursor, 0L) : cursor);
        !           478:                                        break;
        !           479: 
        !           480: # ifndef NO_VISIBLE
        !           481:                                  case 'v':
        !           482:                                  case 'V':
        !           483:                                        if (V_from)
        !           484:                                                V_from = MARK_UNSET;
        !           485:                                        else
        !           486:                                                V_from = cursor;
        !           487:                                        m = from = to = cursor;
        !           488:                                        V_linemd = (*key == 'V');
        !           489:                                        break;
        !           490: 
        !           491:                                  case 'd':
        !           492:                                  case 'y':
        !           493:                                  case '\\':
        !           494:                                        /* do nothing if unmarked */
        !           495:                                        if (!V_from)
        !           496:                                        {
        !           497:                                                msg("You must mark the text first");
        !           498:                                                beep();
        !           499:                                                break;
        !           500:                                        }
        !           501: 
        !           502:                                        /* "from" must come before "to" */
        !           503:                                        if (V_from < cursor)
        !           504:                                        {
        !           505:                                                from = V_from;
        !           506:                                                to = cursor;
        !           507:                                        }
        !           508:                                        else
        !           509:                                        {
        !           510:                                                from = cursor;
        !           511:                                                to = V_from;
        !           512:                                        }
        !           513: 
        !           514:                                        /* we don't need V_from anymore */
        !           515:                                        V_from = MARK_UNSET;
        !           516: 
        !           517:                                        if (V_linemd)
        !           518:                                        {
        !           519:                                                /* adjust for line mode */
        !           520:                                                from &= ~(BLKSIZE - 1);
        !           521:                                                to |= (BLKSIZE - 1);
        !           522:                                        }
        !           523:                                        else
        !           524:                                        {
        !           525:                                                /* in character mode, we must
        !           526:                                                 * worry about deleting the newline
        !           527:                                                 * at the end of the last line
        !           528:                                                 */
        !           529:                                                pfetch(markline(to));
        !           530:                                                if (markidx(to) == plen)
        !           531:                                                        to |= (BLKSIZE - 1);
        !           532:                                        }
        !           533:                                        to++;
        !           534: 
        !           535:                                        switch (*key)
        !           536:                                        {
        !           537:                                          case 'y':
        !           538:                                                cut(from, to);
        !           539:                                                break;
        !           540: 
        !           541:                                          case 'd':
        !           542:                                                ChangeText
        !           543:                                                {
        !           544:                                                        cut(from, to);
        !           545:                                                        delete(from, to);
        !           546:                                                }
        !           547:                                                cursor = from;
        !           548:                                                break;
        !           549: 
        !           550: #ifndef NO_POPUP
        !           551:                                          case '\\':
        !           552:                                                ChangeText
        !           553:                                                {
        !           554:                                                        cursor = v_popup(from, to);
        !           555:                                                }
        !           556:                                                break;
        !           557: #endif
        !           558:                                        }
        !           559:                                        m = from = to = cursor;
        !           560:                                        break;
        !           561: 
        !           562:                                  case 'p':
        !           563:                                  case 'P':
        !           564:                                        V_from = MARK_UNSET;
        !           565:                                        ChangeText
        !           566:                                        {
        !           567:                                                m = from = to = cursor = paste(cursor, (*key == 'p'), FALSE);
        !           568:                                        }
        !           569:                                        break;
        !           570: # endif /* !NO_VISIBLE */
        !           571:                                  default:      m = MARK_UNSET;
        !           572:                                }
        !           573: 
        !           574:                                /* adjust the moved cursor */
        !           575:                                if (m != cursor)
        !           576:                                {
        !           577:                                        m = adjmove(cursor, m, (*key == 'j' || *key == 'k' ? NCOL|FINL : FINL));
        !           578:                                        if (*key == '$' || (*key == 'l' && m <= cursor))
        !           579:                                        {
        !           580:                                                m++;
        !           581:                                        }
        !           582:                                }
        !           583: 
        !           584:                                /* if the cursor is reasonable, use it */
        !           585:                                if (m == MARK_UNSET)
        !           586:                                {
        !           587:                                        beep();
        !           588:                                }
        !           589:                                else
        !           590:                                {
        !           591:                                        from = to = cursor = m;
        !           592:                                }
        !           593:                                break;
        !           594: 
        !           595:                          case ctrl('Z'):
        !           596:                                if (getkey(0) == ctrl('Z'))
        !           597:                                {
        !           598:                                        quit = TRUE;
        !           599:                                        goto BreakBreak;
        !           600:                                }
        !           601:                                break;
        !           602: #endif
        !           603: 
        !           604:                          case ctrl('['):
        !           605:                                /* if last line contains only whitespace, then remove whitespace */
        !           606:                                if (*o_autoindent)
        !           607:                                {
        !           608:                                        pfetch(markline(cursor));
        !           609:                                        for (scan = ptext; isspace(*scan); scan++)
        !           610:                                        {
        !           611:                                        }
        !           612:                                        if (scan > ptext && !*scan)
        !           613:                                        {
        !           614:                                                cursor &= ~(BLKSIZE - 1L);
        !           615:                                                if (to < cursor + plen)
        !           616:                                                {
        !           617:                                                        to = cursor + plen;
        !           618:                                                }
        !           619:                                        }
        !           620:                                }
        !           621:                                goto BreakBreak;
        !           622: 
        !           623:                          case ctrl('U'):
        !           624:                                if (markline(cursor) == markline(from))
        !           625:                                {
        !           626:                                        cursor = from;
        !           627:                                }
        !           628:                                else
        !           629:                                {
        !           630:                                        cursor &= ~(BLKSIZE - 1);
        !           631:                                }
        !           632:                                break;
        !           633: 
        !           634:                          case ctrl('D'):
        !           635:                          case ctrl('T'):
        !           636:                                if (to > cursor)
        !           637:                                {
        !           638:                                        delete(cursor, to);
        !           639:                                }
        !           640:                                mark[27] = cursor;
        !           641:                                cmd_shift(cursor, cursor, *key == ctrl('D') ? CMD_SHIFTL : CMD_SHIFTR, TRUE, "");
        !           642:                                if (mark[27])
        !           643:                                {
        !           644:                                        cursor = mark[27];
        !           645:                                }
        !           646:                                else
        !           647:                                {
        !           648:                                        cursor = m_front(cursor, 0L);
        !           649:                                }
        !           650:                                to = cursor;
        !           651:                                break;
        !           652: 
        !           653:                          case '\b':
        !           654:                                if (cursor <= from)
        !           655:                                {
        !           656:                                        beep();
        !           657:                                }
        !           658:                                else if (markidx(cursor) == 0)
        !           659:                                {
        !           660:                                        cursor -= BLKSIZE;
        !           661:                                        pfetch(markline(cursor));
        !           662:                                        cursor += plen;
        !           663:                                }
        !           664:                                else
        !           665:                                {
        !           666:                                        cursor--;
        !           667:                                }
        !           668:                                break;
        !           669: 
        !           670:                          case ctrl('W'):
        !           671:                                m = m_bword(cursor, 1L, 'b');
        !           672:                                if (markline(m) == markline(cursor) && m >= from)
        !           673:                                {
        !           674:                                        cursor = m;
        !           675:                                        if (from > cursor)
        !           676:                                        {
        !           677:                                                from = cursor;
        !           678:                                        }
        !           679:                                }
        !           680:                                else
        !           681:                                {
        !           682:                                        beep();
        !           683:                                }
        !           684:                                break;
        !           685: 
        !           686:                          case '\n':
        !           687: #if OSK
        !           688:                          case '\l':
        !           689: #else                            
        !           690:                          case '\r':
        !           691: #endif
        !           692:                                build = tmpblk.c;
        !           693:                                *build++ = '\n';
        !           694:                                if (*o_autoindent)
        !           695:                                {
        !           696:                                        /* figure out indent for next line */
        !           697:                                        pfetch(markline(cursor));
        !           698:                                        for (scan = ptext; *scan == ' ' || *scan == '\t'; )
        !           699:                                        {
        !           700:                                                *build++ = *scan++;
        !           701:                                        }
        !           702: 
        !           703:                                        /* remove indent from this line, if blank */
        !           704:                                        if ((int)(scan - ptext) >= markidx(cursor) && plen > 0)
        !           705:                                        {
        !           706:                                                to = cursor &= ~(BLKSIZE - 1);
        !           707:                                                delete(cursor, cursor + (int)(scan - ptext));
        !           708:                                        }
        !           709:                                }
        !           710:                                *build = 0;
        !           711:                                if (cursor >= to && when != WHEN_VIREP)
        !           712:                                {
        !           713:                                        add(cursor, tmpblk.c);
        !           714:                                }
        !           715:                                else
        !           716:                                {
        !           717:                                        change(cursor, to, tmpblk.c);
        !           718:                                }
        !           719:                                redraw(cursor, TRUE);
        !           720:                                to = cursor = (cursor & ~(BLKSIZE - 1))
        !           721:                                                + BLKSIZE
        !           722:                                                + (int)(build - tmpblk.c) - 1;
        !           723:                                break;
        !           724: 
        !           725:                          case ctrl('A'):
        !           726:                          case ctrl('P'):
        !           727:                                if (cursor < to)
        !           728:                                {
        !           729:                                        delete(cursor, to);
        !           730:                                }
        !           731:                                if (*key == ctrl('A'))
        !           732:                                {
        !           733:                                        cutname('.');
        !           734:                                }
        !           735:                                to = cursor = paste(cursor, FALSE, TRUE) + 1L;
        !           736:                                break;
        !           737: 
        !           738:                          case ctrl('V'):
        !           739:                                if (cursor >= to && when != WHEN_VIREP)
        !           740:                                {
        !           741:                                        add(cursor, "^");
        !           742:                                }
        !           743:                                else
        !           744:                                {
        !           745:                                        change(cursor, to, "^");
        !           746:                                        to = cursor + 1;
        !           747:                                }
        !           748:                                redraw(cursor, TRUE);
        !           749:                                *key = getkey(0);
        !           750:                                if (*key == '\n')
        !           751:                                {
        !           752:                                        /* '\n' too hard to handle */
        !           753: #if OSK
        !           754:                                        *key = '\l';
        !           755: #else
        !           756:                                        *key = '\r';
        !           757: #endif
        !           758:                                }
        !           759:                                change(cursor, cursor + 1, key);
        !           760:                                cursor++;
        !           761:                                if (cursor > to)
        !           762:                                {
        !           763:                                        to = cursor;
        !           764:                                }
        !           765:                                break;
        !           766: 
        !           767:                          case ctrl('L'):
        !           768:                          case ctrl('R'):
        !           769:                                redraw(MARK_UNSET, FALSE);
        !           770:                                break;
        !           771: 
        !           772:                          default:
        !           773:                                if (cursor >= to && when != WHEN_VIREP)
        !           774:                                {
        !           775:                                        add(cursor, key);
        !           776:                                        cursor++;
        !           777:                                        to = cursor;
        !           778:                                }
        !           779:                                else
        !           780:                                {
        !           781:                                        pfetch(markline(cursor));
        !           782:                                        if (markidx(cursor) == plen)
        !           783:                                        {
        !           784:                                                add(cursor, key);
        !           785:                                        }
        !           786:                                        else
        !           787:                                        {
        !           788: #ifndef NO_DIGRAPH
        !           789:                                                *key = digraph(ptext[markidx(cursor)], *key);
        !           790: #endif
        !           791:                                                change(cursor, cursor + 1, key);
        !           792:                                        }
        !           793:                                        cursor++;
        !           794:                                }
        !           795: #ifndef NO_SHOWMATCH
        !           796:                                /* show matching "({[" if necessary */
        !           797:                                if (*o_showmatch && strchr(")}]", *key))
        !           798:                                {
        !           799:                                        redraw(cursor, TRUE);
        !           800:                                        m = m_match(cursor - 1, 0L);
        !           801:                                        if (markline(m) >= topline
        !           802:                                         && markline(m) <= botline)
        !           803:                                        {
        !           804:                                                redraw(m, TRUE);
        !           805:                                                refresh();
        !           806:                                                sleep(1);
        !           807:                                        }
        !           808:                                }
        !           809: #endif
        !           810:                        } /* end switch(*key) */
        !           811:                } /* end for(;;) */
        !           812: BreakBreak:;
        !           813:                /* delete any excess characters */
        !           814:                if (cursor < to)
        !           815:                {
        !           816: #ifndef NO_EXTENSIONS
        !           817:                        /* if we aren't in the middle of a change, start one! */
        !           818:                        if (!inchg)
        !           819:                        {
        !           820:                                beforedo(FALSE);
        !           821:                                inchg = TRUE;
        !           822:                        }
        !           823: #endif
        !           824:                        delete(cursor, to);
        !           825:                }
        !           826: 
        !           827:        } /* end if doingdot else */
        !           828: 
        !           829:        /* put the new text into a cut buffer for possible reuse */
        !           830:        if (!doingdot)
        !           831:        {
        !           832:                blksync();
        !           833:                cutname('.');
        !           834:                cut(from, cursor);
        !           835:        }
        !           836: 
        !           837:        /* move to last char that we inputted, unless it was newline */
        !           838:        if (markidx(cursor) != 0)
        !           839:        {
        !           840:                cursor--;
        !           841:        }
        !           842:        redraw(cursor, FALSE);
        !           843: 
        !           844: #ifndef NO_EXTENSIONS
        !           845:        if (quit)
        !           846:        {
        !           847:                /* if this is a nested "do", then cut it short */
        !           848:                abortdo();
        !           849: 
        !           850:                /* exit, unless we can't write out the file */
        !           851:                cursor = v_xit(cursor, 0L, 'Z');
        !           852:        }
        !           853: #endif
        !           854: 
        !           855:        rptlines = 0L;
        !           856:        return cursor;
        !           857: }

unix.superglobalmegacorp.com

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