Annotation of coherent/g/usr/bin/vi/input.c, revision 1.1.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.