Annotation of coherent/d/usr/bin/elvis/move1.c, revision 1.1

1.1     ! root        1: /* move1.c */
        !             2: 
        !             3: /* Author:
        !             4:  *     Steve Kirkendall
        !             5:  *     16820 SW Tallac Way
        !             6:  *     Beaverton, OR 97006
        !             7:  *     [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
        !             8:  */
        !             9: 
        !            10: 
        !            11: /* This file contains most movement functions */
        !            12: 
        !            13: #include "config.h"
        !            14: #include <ctype.h>
        !            15: #include "vi.h"
        !            16: 
        !            17: #ifndef isascii
        !            18: # define isascii(c)    !((c) & ~0x7f)
        !            19: #endif
        !            20: 
        !            21: MARK   m_updnto(m, cnt, cmd)
        !            22:        MARK    m;      /* movement is relative to this mark */
        !            23:        long    cnt;    /* a numeric argument */
        !            24: {
        !            25:        DEFAULT(cmd == 'G' ? nlines : 1L);
        !            26: 
        !            27:        /* move up or down 'cnt' lines */
        !            28:        switch (cmd)
        !            29:        {
        !            30:          case ('P'&0x1f):
        !            31:          case '-':
        !            32:          case 'k':
        !            33:                m -= MARK_AT_LINE(cnt);
        !            34:                break;
        !            35: 
        !            36:          case 'G':
        !            37:                if (cnt < 1L || cnt > nlines)
        !            38:                {
        !            39:                        msg("Only %ld lines", nlines);
        !            40:                        return MARK_UNSET;
        !            41:                }
        !            42:                m = MARK_AT_LINE(cnt);
        !            43:                break;
        !            44: 
        !            45:          default:
        !            46:                m += MARK_AT_LINE(cnt);
        !            47:        }
        !            48: 
        !            49:        /* if that left us screwed up, then fail */
        !            50:        if (m < MARK_FIRST || markline(m) > nlines)
        !            51:        {
        !            52:                return MARK_UNSET;
        !            53:        }
        !            54: 
        !            55:        return m;
        !            56: }
        !            57: 
        !            58: /*ARGSUSED*/
        !            59: MARK   m_right(m, cnt)
        !            60:        MARK    m;      /* movement is relative to this mark */
        !            61:        long    cnt;    /* a numeric argument */
        !            62: {
        !            63:        int             idx;    /* index of the new cursor position */
        !            64: 
        !            65:        DEFAULT(1);
        !            66: 
        !            67:        /* move to right, if that's OK */
        !            68:        pfetch(markline(m));
        !            69:        idx = markidx(m) + cnt;
        !            70:        if (idx < plen)
        !            71:        {
        !            72:                m += cnt;
        !            73:        }
        !            74:        else
        !            75:        {
        !            76:                return MARK_UNSET;
        !            77:        }
        !            78: 
        !            79:        return m;
        !            80: }
        !            81: 
        !            82: /*ARGSUSED*/
        !            83: MARK   m_left(m, cnt)
        !            84:        MARK    m;      /* movement is relative to this mark */
        !            85:        long    cnt;    /* a numeric argument */
        !            86: {
        !            87:        DEFAULT(1);
        !            88: 
        !            89:        /* move to the left, if that's OK */
        !            90:        if (markidx(m) >= cnt)
        !            91:        {
        !            92:                m -= cnt;
        !            93:        }
        !            94:        else
        !            95:        {
        !            96:                return MARK_UNSET;
        !            97:        }
        !            98: 
        !            99:        return m;
        !           100: }
        !           101: 
        !           102: /*ARGSUSED*/
        !           103: MARK   m_tocol(m, cnt)
        !           104:        MARK    m;      /* movement is relative to this mark */
        !           105:        long    cnt;    /* a numeric argument */
        !           106: {
        !           107:        char    *text;  /* text of the line */
        !           108:        int     col;    /* column number */
        !           109:        int     idx;    /* index into the line */
        !           110: 
        !           111:        DEFAULT(1);
        !           112: 
        !           113:        /* internally, columns are numbered 0..COLS-1, not 1..COLS */
        !           114:        cnt--;
        !           115: 
        !           116:        /* if 0, that's easy */
        !           117:        if (cnt == 0)
        !           118:        {
        !           119:                m &= ~(BLKSIZE - 1);
        !           120:                return m;
        !           121:        }
        !           122: 
        !           123:        /* find that column within the line */
        !           124:        pfetch(markline(m));
        !           125:        text = ptext;
        !           126:        for (col = idx = 0; col < cnt && *text; text++, idx++)
        !           127:        {
        !           128:                if (*text == '\t' && !*o_list)
        !           129:                {
        !           130:                        col += *o_tabstop;
        !           131:                        col -= col % *o_tabstop;
        !           132:                }
        !           133:                else if (UCHAR(*text) < ' ' || *text == '\177')
        !           134:                {
        !           135:                        col += 2;
        !           136:                }
        !           137: #ifndef NO_CHARATTR
        !           138:                else if (text[0] == '\\' && text[1] == 'f' && text[2] && *o_charattr)
        !           139:                {
        !           140:                        text += 2; /* plus one more as part of for loop */
        !           141:                }
        !           142: #endif
        !           143:                else
        !           144:                {
        !           145:                        col++;
        !           146:                }
        !           147:        }
        !           148:        if (!*text)
        !           149:        {
        !           150:                return MARK_UNSET;
        !           151:        }
        !           152:        else
        !           153:        {
        !           154:                m = (m & ~(BLKSIZE - 1)) + idx;
        !           155:        }
        !           156:        return m;
        !           157: }
        !           158: 
        !           159: /*ARGSUSED*/
        !           160: MARK   m_front(m, cnt)
        !           161:        MARK    m;      /* movement is relative to this mark */
        !           162:        long    cnt;    /* a numeric argument (ignored) */
        !           163: {
        !           164:        char    *scan;
        !           165: 
        !           166:        /* move to the first non-whitespace character */
        !           167:        pfetch(markline(m));
        !           168:        scan = ptext;
        !           169:        m &= ~(BLKSIZE - 1);
        !           170:        while (*scan == ' ' || *scan == '\t')
        !           171:        {
        !           172:                scan++;
        !           173:                m++;
        !           174:        }
        !           175: 
        !           176:        return m;
        !           177: }
        !           178: 
        !           179: /*ARGSUSED*/
        !           180: MARK   m_rear(m, cnt)
        !           181:        MARK    m;      /* movement is relative to this mark */
        !           182:        long    cnt;    /* a numeric argument (ignored) */
        !           183: {
        !           184:        /* Try to move *EXTREMELY* far to the right.  It is fervently hoped
        !           185:         * that other code will convert this to a more reasonable MARK before
        !           186:         * anything tries to actually use it.  (See adjmove() in vi.c)
        !           187:         */
        !           188:        return m | (BLKSIZE - 1);
        !           189: }
        !           190: 
        !           191: #ifndef NO_SENTENCE
        !           192: /*ARGSUSED*/
        !           193: MARK   m_fsentence(m, cnt)
        !           194:        MARK    m;      /* movement is relative to this mark */
        !           195:        long    cnt;    /* a numeric argument */
        !           196: {
        !           197:        REG char        *text;
        !           198:        REG long        l;
        !           199: 
        !           200:        DEFAULT(1);
        !           201: 
        !           202:        /* get the current line */
        !           203:        l = markline(m);
        !           204:        pfetch(l);
        !           205:        text = ptext + markidx(m);
        !           206: 
        !           207:        /* for each requested sentence... */
        !           208:        while (cnt-- > 0)
        !           209:        {
        !           210:                /* search forward for one of [.?!] followed by spaces or EOL */
        !           211:                do
        !           212:                {
        !           213:                        /* wrap at end of line */
        !           214:                        if (!text[0])
        !           215:                        {
        !           216:                                if (l >= nlines)
        !           217:                                {
        !           218:                                        return MARK_UNSET;
        !           219:                                }
        !           220:                                l++;
        !           221:                                pfetch(l);
        !           222:                                text = ptext;
        !           223:                        }
        !           224:                        else
        !           225:                        {
        !           226:                                text++;
        !           227:                        }
        !           228:                } while (text[0] != '.' && text[0] != '?' && text[0] != '!'
        !           229:                        || text[1] && (text[1] != ' ' || text[2] && text[2] != ' '));
        !           230:        }
        !           231: 
        !           232:        /* construct a mark for this location */
        !           233:        m = buildmark(text);
        !           234: 
        !           235:        /* move forward to the first word of the next sentence */
        !           236:        m = m_fword(m, 1L);
        !           237: 
        !           238:        return m;
        !           239: }
        !           240: 
        !           241: /*ARGSUSED*/
        !           242: MARK   m_bsentence(m, cnt)
        !           243:        MARK    m;      /* movement is relative to this mark */
        !           244:        long    cnt;    /* a numeric argument */
        !           245: {
        !           246:        REG char        *text;  /* used to scan thru text */
        !           247:        REG long        l;      /* current line number */
        !           248:        int             flag;   /* have we passed at least one word? */
        !           249: 
        !           250:        DEFAULT(1);
        !           251: 
        !           252:        /* get the current line */
        !           253:        l = markline(m);
        !           254:        pfetch(l);
        !           255:        text = ptext + markidx(m);
        !           256: 
        !           257:        /* for each requested sentence... */
        !           258:        flag = TRUE;
        !           259:        while (cnt-- > 0)
        !           260:        {
        !           261:                /* search backward for one of [.?!] followed by spaces or EOL */
        !           262:                do
        !           263:                {
        !           264:                        /* wrap at beginning of line */
        !           265:                        if (text == ptext)
        !           266:                        {
        !           267:                                do
        !           268:                                {
        !           269:                                        if (l <= 1)
        !           270:                                        {
        !           271:                                                return MARK_UNSET;
        !           272:                                        }
        !           273:                                        l--;
        !           274:                                        pfetch(l);
        !           275:                                } while (!*ptext);
        !           276:                                text = ptext + plen - 1;
        !           277:                        }
        !           278:                        else
        !           279:                        {
        !           280:                                text--;
        !           281:                        }
        !           282: 
        !           283:                        /* are we moving past a "word"? */
        !           284:                        if (text[0] >= '0')
        !           285:                        {
        !           286:                                flag = FALSE;
        !           287:                        }
        !           288:                } while (flag || text[0] != '.' && text[0] != '?' && text[0] != '!'
        !           289:                        || text[1] && (text[1] != ' ' || text[2] && text[2] != ' '));
        !           290:        }
        !           291: 
        !           292:        /* construct a mark for this location */
        !           293:        m = buildmark(text);
        !           294: 
        !           295:        /* move to the front of the following sentence */
        !           296:        m = m_fword(m, 1L);
        !           297: 
        !           298:        return m;
        !           299: }
        !           300: #endif
        !           301: 
        !           302: /*ARGSUSED*/
        !           303: MARK   m_fparagraph(m, cnt)
        !           304:        MARK    m;      /* movement is relative to this mark */
        !           305:        long    cnt;    /* a numeric argument */
        !           306: {
        !           307:        char    *text;
        !           308:        char    *pscn;  /* used to scan thru value of "paragraphs" option */
        !           309:        long    l;
        !           310: 
        !           311:        DEFAULT(1);
        !           312: 
        !           313:        for (l = markline(m); cnt > 0 && l++ < nlines; )
        !           314:        {
        !           315:                text = fetchline(l);
        !           316:                if (!*text)
        !           317:                {
        !           318:                        cnt--;
        !           319:                }
        !           320: #ifndef NO_SENTENCE
        !           321:                else if (*text == '.')
        !           322:                {
        !           323:                        for (pscn = o_paragraphs; pscn[0] && pscn[1]; pscn += 2)
        !           324:                        {
        !           325:                                if (pscn[0] == text[1] && pscn[1] == text[2])
        !           326:                                {
        !           327:                                        cnt--;
        !           328:                                        break;
        !           329:                                }
        !           330:                        }
        !           331:                }
        !           332: #endif
        !           333:        }
        !           334:        if (l <= nlines)
        !           335:        {
        !           336:                m = MARK_AT_LINE(l);
        !           337:        }
        !           338:        else
        !           339:        {
        !           340:                m = MARK_LAST;
        !           341:        }
        !           342:        return m;
        !           343: }
        !           344: 
        !           345: /*ARGSUSED*/
        !           346: MARK   m_bparagraph(m, cnt)
        !           347:        MARK    m;      /* movement is relative to this mark */
        !           348:        long    cnt;    /* a numeric argument */
        !           349: {
        !           350:        char    *text;
        !           351:        char    *pscn;  /* used to scan thru value of "paragraph" option */
        !           352:        long    l;
        !           353: 
        !           354:        DEFAULT(1);
        !           355: 
        !           356:        for (l = markline(m); cnt > 0 && l-- > 1; )
        !           357:        {
        !           358:                text = fetchline(l);
        !           359:                if (!*text)
        !           360:                {
        !           361:                        cnt--;
        !           362:                }
        !           363: #ifndef NO_SENTENCE
        !           364:                else if (*text == '.')
        !           365:                {
        !           366:                        for (pscn = o_paragraphs; pscn[0] && pscn[1]; pscn += 2)
        !           367:                        {
        !           368:                                if (pscn[0] == text[1] && pscn[1] == text[2])
        !           369:                                {
        !           370:                                        cnt--;
        !           371:                                        break;
        !           372:                                }
        !           373:                        }
        !           374:                }
        !           375: #endif
        !           376:        }
        !           377:        if (l >= 1)
        !           378:        {
        !           379:                m = MARK_AT_LINE(l);
        !           380:        }
        !           381:        else
        !           382:        {
        !           383:                m = MARK_FIRST;
        !           384:        }
        !           385:        return m;
        !           386: }
        !           387: 
        !           388: /*ARGSUSED*/
        !           389: MARK   m_fsection(m, cnt, key)
        !           390:        MARK    m;      /* movement is relative to this mark */
        !           391:        long    cnt;    /* (ignored) */
        !           392:        int     key;    /* second key stroke - must be ']' */
        !           393: {
        !           394:        char    *text;
        !           395:        char    *sscn;  /* used to scan thru value of "sections" option */
        !           396:        long    l;
        !           397: 
        !           398:        /* make sure second key was ']' */
        !           399:        if (key != ']')
        !           400:        {
        !           401:                return MARK_UNSET;
        !           402:        }
        !           403: 
        !           404:        for (l = markline(m); l++ < nlines; )
        !           405:        {
        !           406:                text = fetchline(l);
        !           407:                if (*text == '{')
        !           408:                {
        !           409:                        break;
        !           410:                }
        !           411: #ifndef NO_SENTENCE
        !           412:                else if (*text == '.')
        !           413:                {
        !           414:                        for (sscn = o_sections; sscn[0] && sscn[1]; sscn += 2)
        !           415:                        {
        !           416:                                if (sscn[0] == text[1] && sscn[1] == text[2])
        !           417:                                {
        !           418:                                        goto BreakBreak;
        !           419:                                }
        !           420:                        }
        !           421:                }
        !           422: #endif
        !           423:        }
        !           424: BreakBreak:
        !           425:        if (l <= nlines)
        !           426:        {
        !           427:                m = MARK_AT_LINE(l);
        !           428:        }
        !           429:        else
        !           430:        {
        !           431:                m = MARK_LAST;
        !           432:        }
        !           433:        return m;
        !           434: }
        !           435: 
        !           436: /*ARGSUSED*/
        !           437: MARK   m_bsection(m, cnt, key)
        !           438:        MARK    m;      /* movement is relative to this mark */
        !           439:        long    cnt;    /* (ignored) */
        !           440:        int     key;    /* second key stroke - must be '[' */
        !           441: {
        !           442:        char    *text;
        !           443:        char    *sscn;  /* used to scan thru value of "sections" option */
        !           444:        long    l;
        !           445: 
        !           446:        /* make sure second key was '[' */
        !           447:        if (key != '[')
        !           448:        {
        !           449:                return MARK_UNSET;
        !           450:        }
        !           451: 
        !           452:        for (l = markline(m); l-- > 1; )
        !           453:        {
        !           454:                text = fetchline(l);
        !           455:                if (*text == '{')
        !           456:                {
        !           457:                        break;
        !           458:                }
        !           459: #ifndef NO_SENTENCE
        !           460:                else if (*text == '.')
        !           461:                {
        !           462:                        for (sscn = o_sections; sscn[0] && sscn[1]; sscn += 2)
        !           463:                        {
        !           464:                                if (sscn[0] == text[1] && sscn[1] == text[2])
        !           465:                                {
        !           466:                                        goto BreakBreak;
        !           467:                                }
        !           468:                        }
        !           469:                }
        !           470: #endif
        !           471:        }
        !           472: BreakBreak:
        !           473:        if (l >= 1)
        !           474:        {
        !           475:                m = MARK_AT_LINE(l);
        !           476:        }
        !           477:        else
        !           478:        {
        !           479:                m = MARK_FIRST;
        !           480:        }
        !           481:        return m;
        !           482: }
        !           483: 
        !           484: 
        !           485: /*ARGSUSED*/
        !           486: MARK   m_match(m, cnt)
        !           487:        MARK    m;      /* movement is relative to this mark */
        !           488:        long    cnt;    /* a numeric argument (ignored) */
        !           489: {
        !           490:        long    l;
        !           491:        REG char        *text;
        !           492:        REG char        match;
        !           493:        REG char        nest;
        !           494:        REG int         count;
        !           495: 
        !           496:        /* get the current line */
        !           497:        l = markline(m);
        !           498:        pfetch(l);
        !           499:        text = ptext + markidx(m);
        !           500: 
        !           501:        /* search forward within line for one of "[](){}" */
        !           502:        for (match = '\0'; !match && *text; text++)
        !           503:        {
        !           504:                /* tricky way to recognize 'em in ASCII */
        !           505:                nest = *text;
        !           506:                if ((nest & 0xdf) == ']' || (nest & 0xdf) == '[')
        !           507:                {
        !           508:                        match = nest ^ ('[' ^ ']');
        !           509:                }
        !           510:                else if ((nest & 0xfe) == '(')
        !           511:                {
        !           512:                        match = nest ^ ('(' ^ ')');
        !           513:                }
        !           514:                else
        !           515:                {
        !           516:                        match = 0;
        !           517:                }
        !           518:        }
        !           519:        if (!match)
        !           520:        {
        !           521:                return MARK_UNSET;
        !           522:        }
        !           523:        text--;
        !           524: 
        !           525:        /* search forward or backward for match */
        !           526:        if (match == '(' || match == '[' || match == '{')
        !           527:        {
        !           528:                /* search backward */
        !           529:                for (count = 1; count > 0; )
        !           530:                {
        !           531:                        /* wrap at beginning of line */
        !           532:                        if (text == ptext)
        !           533:                        {
        !           534:                                do
        !           535:                                {
        !           536:                                        if (l <= 1L)
        !           537:                                        {
        !           538:                                                return MARK_UNSET;
        !           539:                                        }
        !           540:                                        l--;
        !           541:                                        pfetch(l);
        !           542:                                } while (!*ptext);
        !           543:                                text = ptext + plen - 1;
        !           544:                        }
        !           545:                        else
        !           546:                        {
        !           547:                                text--;
        !           548:                        }
        !           549: 
        !           550:                        /* check the char */
        !           551:                        if (*text == match)
        !           552:                                count--;
        !           553:                        else if (*text == nest)
        !           554:                                count++;
        !           555:                }
        !           556:        }
        !           557:        else
        !           558:        {
        !           559:                /* search forward */
        !           560:                for (count = 1; count > 0; )
        !           561:                {
        !           562:                        /* wrap at end of line */
        !           563:                        if (!*text)
        !           564:                        {
        !           565:                                if (l >= nlines)
        !           566:                                {
        !           567:                                        return MARK_UNSET;
        !           568:                                }
        !           569:                                l++;
        !           570:                                pfetch(l);
        !           571:                                text = ptext;
        !           572:                        }
        !           573:                        else
        !           574:                        {
        !           575:                                text++;
        !           576:                        }
        !           577: 
        !           578:                        /* check the char */
        !           579:                        if (*text == match)
        !           580:                                count--;
        !           581:                        else if (*text == nest)
        !           582:                                count++;
        !           583:                }
        !           584:        }
        !           585: 
        !           586:        /* construct a mark for this place */
        !           587:        m = buildmark(text);
        !           588:        return m;
        !           589: }
        !           590: 
        !           591: /*ARGSUSED*/
        !           592: MARK   m_tomark(m, cnt, key)
        !           593:        MARK    m;      /* movement is relative to this mark */
        !           594:        long    cnt;    /* (ignored) */
        !           595:        int     key;    /* keystroke - the mark to move to */
        !           596: {
        !           597:        /* mark '' is a special case */
        !           598:        if (key == '\'' || key == '`')
        !           599:        {
        !           600:                if (mark[26] == MARK_UNSET)
        !           601:                {
        !           602:                        return MARK_FIRST;
        !           603:                }
        !           604:                else
        !           605:                {
        !           606:                        return mark[26];
        !           607:                }
        !           608:        }
        !           609: 
        !           610:        /* if not a valid mark number, don't move */
        !           611:        if (key < 'a' || key > 'z')
        !           612:        {
        !           613:                return MARK_UNSET;
        !           614:        }
        !           615: 
        !           616:        /* return the selected mark -- may be MARK_UNSET */
        !           617:        if (!mark[key - 'a'])
        !           618:        {
        !           619:                msg("mark '%c is unset", key);
        !           620:        }
        !           621:        return mark[key - 'a'];
        !           622: }
        !           623: 

unix.superglobalmegacorp.com

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