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

1.1     ! root        1: /* cmd2.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 some of the commands - mostly ones that change text */
        !            12: 
        !            13: #include <ctype.h>
        !            14: #include "config.h"
        !            15: #include "vi.h"
        !            16: #include "regexp.h"
        !            17: #if TOS
        !            18: # include <stat.h>
        !            19: #else
        !            20: # if OSK
        !            21: #  include "osk.h"
        !            22: # else
        !            23: #  include <sys/stat.h>
        !            24: # endif
        !            25: #endif
        !            26: 
        !            27: 
        !            28: /*ARGSUSED*/
        !            29: void cmd_substitute(frommark, tomark, cmd, bang, extra)
        !            30:        MARK    frommark;
        !            31:        MARK    tomark;
        !            32:        CMD     cmd;
        !            33:        int     bang;
        !            34:        char    *extra; /* rest of the command line */
        !            35: {
        !            36:        char    *line;  /* a line from the file */
        !            37:        regexp  *re;    /* the compiled search expression */
        !            38:        char    *subst; /* the substitution string */
        !            39:        char    *opt;   /* substitution options */
        !            40:        long    l;      /* a line number */
        !            41:        char    *s, *d; /* used during subtitutions */
        !            42:        char    *conf;  /* used during confirmation */
        !            43:        long    chline; /* # of lines changed */
        !            44:        long    chsub;  /* # of substitutions made */
        !            45:        static  optp;   /* boolean option: print when done? */
        !            46:        static  optg;   /* boolean option: substitute globally in line? */
        !            47:        static  optc;   /* boolean option: confirm before subst? */
        !            48: 
        !            49: 
        !            50:        /* for now, assume this will fail */
        !            51:        rptlines = -1L;
        !            52: 
        !            53:        if (cmd == CMD_SUBAGAIN)
        !            54:        {
        !            55: #ifndef NO_MAGIC
        !            56:                if (*o_magic)
        !            57:                        subst = "~";
        !            58:                else
        !            59: #endif
        !            60:                subst = "\\~";
        !            61:                re = regcomp("");
        !            62: 
        !            63:                /* if visual "&", then turn off the "p" and "c" options */
        !            64:                if (bang)
        !            65:                {
        !            66:                        optp = optc = FALSE;
        !            67:                }
        !            68:        }
        !            69:        else
        !            70:        {
        !            71:                /* make sure we got a search pattern */
        !            72:                if (*extra != '/' && *extra != '?')
        !            73:                {
        !            74:                        msg("Usage: s/regular expression/new text/");
        !            75:                        return;
        !            76:                }
        !            77: 
        !            78:                /* parse & compile the search pattern */
        !            79:                subst = parseptrn(extra);
        !            80:                re = regcomp(extra + 1);
        !            81:        }
        !            82: 
        !            83:        /* abort if RE error -- error message already given by regcomp() */
        !            84:        if (!re)
        !            85:        {
        !            86:                return;
        !            87:        }
        !            88: 
        !            89:        if (cmd == CMD_SUBSTITUTE)
        !            90:        {
        !            91:                /* parse the substitution string & find the option string */
        !            92:                for (opt = subst; *opt && *opt != *extra; opt++)
        !            93:                {
        !            94:                        if (*opt == '\\' && opt[1])
        !            95:                        {
        !            96:                                opt++;
        !            97:                        }
        !            98:                }
        !            99:                if (*opt)
        !           100:                {
        !           101:                        *opt++ = '\0';
        !           102:                }
        !           103: 
        !           104:                /* analyse the option string */
        !           105:                if (!*o_edcompatible)
        !           106:                {
        !           107:                        optp = optg = optc = FALSE;
        !           108:                }
        !           109:                while (*opt)
        !           110:                {
        !           111:                        switch (*opt++)
        !           112:                        {
        !           113:                          case 'p':     optp = !optp;   break;
        !           114:                          case 'g':     optg = !optg;   break;
        !           115:                          case 'c':     optc = !optc;   break;
        !           116:                          case ' ':
        !           117:                          case '\t':                    break;
        !           118:                          default:
        !           119:                                msg("Subst options are p, c, and g -- not %c", opt[-1]);
        !           120:                                return;
        !           121:                        }
        !           122:                }
        !           123:        }
        !           124: 
        !           125:        /* if "c" or "p" flag was given, and we're in visual mode, then NEWLINE */
        !           126:        if ((optc || optp) && mode == MODE_VI)
        !           127:        {
        !           128:                addch('\n');
        !           129:                exrefresh();
        !           130:        }
        !           131: 
        !           132:        ChangeText
        !           133:        {
        !           134:                /* reset the change counters */
        !           135:                chline = chsub = 0L;
        !           136: 
        !           137:                /* for each selected line */
        !           138:                for (l = markline(frommark); l <= markline(tomark); l++)
        !           139:                {
        !           140:                        /* fetch the line */
        !           141:                        line = fetchline(l);
        !           142: 
        !           143:                        /* if it contains the search pattern... */
        !           144:                        if (regexec(re, line, TRUE))
        !           145:                        {
        !           146:                                /* increment the line change counter */
        !           147:                                chline++;
        !           148: 
        !           149:                                /* initialize the pointers */
        !           150:                                s = line;
        !           151:                                d = tmpblk.c;
        !           152: 
        !           153:                                /* do once or globally ... */
        !           154:                                do
        !           155:                                {
        !           156: #ifndef CRUNCH
        !           157:                                        /* confirm, if necessary */
        !           158:                                        if (optc)
        !           159:                                        {
        !           160:                                                for (conf = line; conf < re->startp[0]; conf++)
        !           161:                                                        addch(*conf);
        !           162:                                                standout();
        !           163:                                                for ( ; conf < re->endp[0]; conf++)
        !           164:                                                        addch(*conf);
        !           165:                                                standend();
        !           166:                                                for (; *conf; conf++)
        !           167:                                                        addch(*conf);
        !           168:                                                addch('\n');
        !           169:                                                exrefresh();
        !           170:                                                if (getkey(0) != 'y')
        !           171:                                                {
        !           172:                                                        /* copy accross the original chars */
        !           173:                                                        while (s < re->endp[0])
        !           174:                                                                *d++ = *s++;
        !           175: 
        !           176:                                                        /* skip to next match on this line, if any */
        !           177:                                                        continue;
        !           178:                                                }
        !           179:                                        }
        !           180: #endif /* not CRUNCH */
        !           181: 
        !           182:                                        /* increment the substitution change counter */
        !           183:                                        chsub++;
        !           184: 
        !           185:                                        /* this may be the first line to redraw */
        !           186:                                        redrawrange(l, l + 1L, l + 1L);
        !           187: 
        !           188:                                        /* copy stuff from before the match */
        !           189:                                        while (s < re->startp[0])
        !           190:                                        {
        !           191:                                                *d++ = *s++;
        !           192:                                        }
        !           193:        
        !           194:                                        /* substitute for the matched part */
        !           195:                                        regsub(re, subst, d);
        !           196:                                        s = re->endp[0];
        !           197:                                        d += strlen(d);
        !           198: 
        !           199:                                } while (optg && regexec(re, s, FALSE));
        !           200: 
        !           201:                                /* copy stuff from after the match */
        !           202:                                while (*d++ = *s++)     /* yes, ASSIGNMENT! */
        !           203:                                {
        !           204:                                }
        !           205: 
        !           206:                                /* replace the old version of the line with the new */
        !           207:                                d[-1] = '\n';
        !           208:                                d[0] = '\0';
        !           209:                                change(MARK_AT_LINE(l), MARK_AT_LINE(l + 1), tmpblk.c);
        !           210: 
        !           211:                                /* if supposed to print it, do so */
        !           212:                                if (optp)
        !           213:                                {
        !           214:                                        addstr(tmpblk.c);
        !           215:                                        exrefresh();
        !           216:                                }
        !           217: 
        !           218:                                /* move the cursor to that line */
        !           219:                                cursor = MARK_AT_LINE(l);
        !           220:                        }
        !           221:                }
        !           222:        }
        !           223: 
        !           224:        /* tweak for redrawing */
        !           225:        mustredraw = TRUE;
        !           226: 
        !           227:        /* free the regexp */
        !           228:        free(re);
        !           229: 
        !           230:        /* if done from within a ":g" command, then finish silently */
        !           231:        if (doingglobal)
        !           232:        {
        !           233:                rptlines = chline;
        !           234:                rptlabel = "changed";
        !           235:                return;
        !           236:        }
        !           237: 
        !           238:        /* Reporting */
        !           239:        if (chsub == 0)
        !           240:        {
        !           241:                msg("Substitution failed");
        !           242:        }
        !           243:        else if (chline >= *o_report)
        !           244:        {
        !           245:                msg("%ld substitutions on %ld lines", chsub, chline);
        !           246:        }
        !           247: }
        !           248: 
        !           249: 
        !           250: 
        !           251: 
        !           252: /*ARGSUSED*/
        !           253: void cmd_delete(frommark, tomark, cmd, bang, extra)
        !           254:        MARK    frommark;
        !           255:        MARK    tomark;
        !           256:        CMD     cmd;
        !           257:        int     bang;
        !           258:        char    *extra;
        !           259: {
        !           260:        MARK    curs2;  /* an altered form of the cursor */
        !           261: 
        !           262:        /* choose your cut buffer */
        !           263:        if (*extra == '"')
        !           264:        {
        !           265:                extra++;
        !           266:        }
        !           267:        if (*extra)
        !           268:        {
        !           269:                cutname(*extra);
        !           270:        }
        !           271: 
        !           272:        /* make sure we're talking about whole lines here */
        !           273:        frommark = frommark & ~(BLKSIZE - 1);
        !           274:        tomark = (tomark & ~(BLKSIZE - 1)) + BLKSIZE;
        !           275: 
        !           276:        /* yank the lines */
        !           277:        cut(frommark, tomark);
        !           278: 
        !           279:        /* if CMD_DELETE then delete the lines */
        !           280:        if (cmd != CMD_YANK)
        !           281:        {
        !           282:                curs2 = cursor;
        !           283:                ChangeText
        !           284:                {
        !           285:                        /* delete the lines */
        !           286:                        delete(frommark, tomark);
        !           287:                }
        !           288:                if (curs2 > tomark)
        !           289:                {
        !           290:                        cursor = curs2 - tomark + frommark;
        !           291:                }
        !           292:                else if (curs2 > frommark)
        !           293:                {
        !           294:                        cursor = frommark;
        !           295:                }
        !           296:        }
        !           297: }
        !           298: 
        !           299: 
        !           300: /*ARGSUSED*/
        !           301: void cmd_append(frommark, tomark, cmd, bang, extra)
        !           302:        MARK    frommark;
        !           303:        MARK    tomark;
        !           304:        CMD     cmd;
        !           305:        int     bang;
        !           306:        char    *extra;
        !           307: {
        !           308:        long    l;      /* line counter */
        !           309: 
        !           310:        ChangeText
        !           311:        {
        !           312:                /* if we're doing a change, delete the old version */
        !           313:                if (cmd == CMD_CHANGE)
        !           314:                {
        !           315:                        /* delete 'em */
        !           316:                        cmd_delete(frommark, tomark, cmd, bang, extra);
        !           317:                }
        !           318: 
        !           319:                /* new lines start at the frommark line, or after it */
        !           320:                l = markline(frommark);
        !           321:                if (cmd == CMD_APPEND)
        !           322:                {
        !           323:                        l++;
        !           324:                }
        !           325: 
        !           326:                /* get lines until no more lines, or "." line, and insert them */
        !           327:                while (vgets('\0', tmpblk.c, BLKSIZE) >= 0)
        !           328:                {
        !           329:                        addch('\n');
        !           330:                        if (!strcmp(tmpblk.c, "."))
        !           331:                        {
        !           332:                                break;
        !           333:                        }
        !           334: 
        !           335:                        strcat(tmpblk.c, "\n");
        !           336:                        add(MARK_AT_LINE(l), tmpblk.c);
        !           337:                        l++;
        !           338:                }
        !           339:        }
        !           340: 
        !           341:        /* on the odd chance that we're calling this from vi mode ... */
        !           342:        redraw(MARK_UNSET, FALSE);
        !           343: }
        !           344: 
        !           345: 
        !           346: /*ARGSUSED*/
        !           347: void cmd_put(frommark, tomark, cmd, bang, extra)
        !           348:        MARK    frommark;
        !           349:        MARK    tomark;
        !           350:        CMD     cmd;
        !           351:        int     bang;
        !           352:        char    *extra;
        !           353: {
        !           354:        /* choose your cut buffer */
        !           355:        if (*extra == '"')
        !           356:        {
        !           357:                extra++;
        !           358:        }
        !           359:        if (*extra)
        !           360:        {
        !           361:                cutname(*extra);
        !           362:        }
        !           363: 
        !           364:        /* paste it */
        !           365:        ChangeText
        !           366:        {
        !           367:                cursor = paste(frommark, TRUE, FALSE);
        !           368:        }
        !           369: }
        !           370: 
        !           371: 
        !           372: /*ARGSUSED*/
        !           373: void cmd_join(frommark, tomark, cmd, bang, extra)
        !           374:        MARK    frommark;
        !           375:        MARK    tomark;
        !           376:        CMD     cmd;
        !           377:        int     bang;
        !           378:        char    *extra;
        !           379: {
        !           380:        long    l;
        !           381:        char    *scan;
        !           382:        int     len;    /* length of the new line */
        !           383: 
        !           384:        /* if only one line is specified, assume the following one joins too */
        !           385:        if (markline(frommark) == nlines)
        !           386:        {
        !           387:                msg("Nothing to join with this line");
        !           388:                return;
        !           389:        }
        !           390:        if (markline(frommark) == markline(tomark))
        !           391:        {
        !           392:                tomark += BLKSIZE;
        !           393:        }
        !           394: 
        !           395:        /* get the first line */
        !           396:        l = markline(frommark);
        !           397:        strcpy(tmpblk.c, fetchline(l));
        !           398:        len = strlen(tmpblk.c);
        !           399: 
        !           400:        /* build the longer line */
        !           401:        while (++l <= markline(tomark))
        !           402:        {
        !           403:                /* get the next line */
        !           404:                scan = fetchline(l);
        !           405: 
        !           406:                /* remove any leading whitespace */
        !           407:                while (*scan == '\t' || *scan == ' ')
        !           408:                {
        !           409:                        scan++;
        !           410:                }
        !           411: 
        !           412:                /* see if the line will fit */
        !           413:                if (strlen(scan) + len + 3 > BLKSIZE)
        !           414:                {
        !           415:                        msg("Can't join -- the resulting line would be too long");
        !           416:                        return;
        !           417:                }
        !           418: 
        !           419:                /* catenate it, with a space (or two) in between */
        !           420:                if (len >= 1 &&
        !           421:                        (tmpblk.c[len - 1] == '.'
        !           422:                         || tmpblk.c[len - 1] == '?'
        !           423:                         || tmpblk.c[len - 1] == '!'))
        !           424:                {
        !           425:                         tmpblk.c[len++] = ' ';
        !           426:                }
        !           427:                tmpblk.c[len++] = ' ';
        !           428:                strcpy(tmpblk.c + len, scan);
        !           429:                len += strlen(scan);
        !           430:        }
        !           431:        tmpblk.c[len++] = '\n';
        !           432:        tmpblk.c[len] = '\0';
        !           433: 
        !           434:        /* make the change */
        !           435:        ChangeText
        !           436:        {
        !           437:                frommark &= ~(BLKSIZE - 1);
        !           438:                tomark &= ~(BLKSIZE - 1);
        !           439:                tomark += BLKSIZE;
        !           440:                change(frommark, tomark, tmpblk.c);
        !           441:        }
        !           442: 
        !           443:        /* Reporting... */
        !           444:        rptlines = markline(tomark) - markline(frommark) - 1L;
        !           445:        rptlabel = "joined";
        !           446: }
        !           447: 
        !           448: 
        !           449: 
        !           450: /*ARGSUSED*/
        !           451: void cmd_shift(frommark, tomark, cmd, bang, extra)
        !           452:        MARK    frommark;
        !           453:        MARK    tomark;
        !           454:        CMD     cmd;
        !           455:        int     bang;
        !           456:        char    *extra;
        !           457: {
        !           458:        long    l;      /* line number counter */
        !           459:        int     oldidx; /* number of chars previously used for indent */
        !           460:        int     newidx; /* number of chars in the new indent string */
        !           461:        int     oldcol; /* previous indent amount */
        !           462:        int     newcol; /* new indent amount */
        !           463:        char    *text;  /* pointer to the old line's text */
        !           464: 
        !           465:        /* figure out how much of the screen we must redraw (for vi mode) */
        !           466:        if (markline(frommark) != markline(tomark))
        !           467:        {
        !           468:                mustredraw = TRUE;
        !           469:                redrawrange(markline(frommark), markline(tomark) + 1L, markline(tomark) + 1L);
        !           470:        }
        !           471: 
        !           472:        ChangeText
        !           473:        {
        !           474:                /* for each line to shift... */
        !           475:                for (l = markline(frommark); l <= markline(tomark); l++)
        !           476:                {
        !           477:                        /* get the line - ignore empty lines unless ! mode */
        !           478:                        text = fetchline(l);
        !           479:                        if (!*text && !bang)
        !           480:                                continue;
        !           481: 
        !           482:                        /* calc oldidx and oldcol */
        !           483:                        for (oldidx = 0, oldcol = 0;
        !           484:                             text[oldidx] == ' ' || text[oldidx] == '\t';
        !           485:                             oldidx++)
        !           486:                        {
        !           487:                                if (text[oldidx] == ' ')
        !           488:                                {
        !           489:                                        oldcol += 1;
        !           490:                                }
        !           491:                                else
        !           492:                                {
        !           493:                                        oldcol += *o_tabstop - (oldcol % *o_tabstop);
        !           494:                                }
        !           495:                        }
        !           496:        
        !           497:                        /* calc newcol */
        !           498:                        if (cmd == CMD_SHIFTR)
        !           499:                        {
        !           500:                                newcol = oldcol + (*o_shiftwidth & 0xff);
        !           501:                        }
        !           502:                        else
        !           503:                        {
        !           504:                                newcol = oldcol - (*o_shiftwidth & 0xff);
        !           505:                                if (newcol < 0)
        !           506:                                        newcol = 0;
        !           507:                        }
        !           508: 
        !           509:                        /* if no change, then skip to next line */
        !           510:                        if (oldcol == newcol)
        !           511:                                continue;
        !           512: 
        !           513:                        /* build a new indent string */
        !           514:                        newidx = 0;
        !           515:                        while (newcol >= *o_tabstop)
        !           516:                        {
        !           517:                                tmpblk.c[newidx++] = '\t';
        !           518:                                newcol -= *o_tabstop;
        !           519:                        }
        !           520:                        while (newcol > 0)
        !           521:                        {
        !           522:                                tmpblk.c[newidx++] = ' ';
        !           523:                                newcol--;
        !           524:                        }
        !           525:                        tmpblk.c[newidx] = '\0';
        !           526:                        
        !           527:                        /* change the old indent string into the new */
        !           528:                        change(MARK_AT_LINE(l), MARK_AT_LINE(l) + oldidx, tmpblk.c);
        !           529:                }
        !           530:        }
        !           531: 
        !           532:        /* Reporting... */
        !           533:        rptlines = markline(tomark) - markline(frommark) + 1L;
        !           534:        if (cmd == CMD_SHIFTR)
        !           535:        {
        !           536:                rptlabel = ">ed";
        !           537:        }
        !           538:        else
        !           539:        {
        !           540:                rptlabel = "<ed";
        !           541:        }
        !           542: }
        !           543: 
        !           544: 
        !           545: /*ARGSUSED*/
        !           546: void cmd_read(frommark, tomark, cmd, bang, extra)
        !           547:        MARK    frommark;
        !           548:        MARK    tomark;
        !           549:        CMD     cmd;
        !           550:        int     bang;
        !           551:        char    *extra;
        !           552: {
        !           553:        int     fd, rc; /* used while reading from the file */
        !           554:        char    *scan;  /* used for finding NUL characters */
        !           555:        int     hadnul; /* boolean: any NULs found? */
        !           556:        int     addnl;  /* boolean: forced to add newlines? */
        !           557:        int     len;    /* number of chars in current line */
        !           558:        long    lines;  /* number of lines in current block */
        !           559:        struct stat statb;
        !           560: 
        !           561:        /* special case: if ":r !cmd" then let the filter() function do it */
        !           562:        if (extra[0] == '!')
        !           563:        {
        !           564:                filter(frommark, MARK_UNSET, extra + 1);
        !           565:                return;
        !           566:        }
        !           567: 
        !           568:        /* open the file */
        !           569:        fd = open(extra, O_RDONLY);
        !           570:        if (fd < 0)
        !           571:        {
        !           572:                msg("Can't open \"%s\"", extra);
        !           573:                return;
        !           574:        }
        !           575: 
        !           576: #ifndef CRUNCH
        !           577:        if (stat(extra, &statb) < 0)
        !           578:        {
        !           579:                msg("Can't stat \"%s\"", extra);
        !           580:        }
        !           581: # if TOS
        !           582:        if (statb.st_mode & S_IJDIR)
        !           583: # else
        !           584: #  if OSK
        !           585:        if (statb.st_mode & S_IFDIR)
        !           586: #  else
        !           587:        if ((statb.st_mode & S_IFMT) != S_IFREG)
        !           588: #  endif
        !           589: # endif
        !           590:        {
        !           591:                msg("\"%s\" is not a regular file", extra);
        !           592:                return;
        !           593:        }
        !           594: #endif /* not CRUNCH */
        !           595: 
        !           596:        /* get blocks from the file, and add them */
        !           597:        ChangeText
        !           598:        {
        !           599:                /* insertion starts at the line following frommark */
        !           600:                tomark = frommark = (frommark | (BLKSIZE - 1L)) + 1L;
        !           601:                len = 0;
        !           602:                hadnul = addnl = FALSE;
        !           603: 
        !           604:                /* add an extra newline, so partial lines at the end of
        !           605:                 * the file don't trip us up
        !           606:                 */
        !           607:                add(tomark, "\n");
        !           608: 
        !           609:                /* for each chunk of text... */
        !           610:                while ((rc = read(fd, tmpblk.c, BLKSIZE - 1)) > 0)
        !           611:                {
        !           612:                        /* count newlines, convert NULs, etc. ... */
        !           613:                        for (lines = 0, scan = tmpblk.c; rc > 0; rc--, scan++)
        !           614:                        {
        !           615:                                /* break up long lines */
        !           616:                                if (*scan != '\n' && len + 2 > BLKSIZE)
        !           617:                                {
        !           618:                                        *scan = '\n';
        !           619:                                        addnl = TRUE;
        !           620:                                }
        !           621: 
        !           622:                                /* protect against NUL chars in file */
        !           623:                                if (!*scan)
        !           624:                                {
        !           625:                                        *scan = 0x80;
        !           626:                                        hadnul = TRUE;
        !           627:                                }
        !           628: 
        !           629:                                /* starting a new line? */
        !           630:                                if (*scan == '\n')
        !           631:                                {
        !           632:                                        /* reset length at newline */
        !           633:                                        len = 0;
        !           634:                                        lines++;
        !           635:                                }
        !           636:                                else
        !           637:                                {
        !           638:                                        len++;
        !           639:                                }
        !           640:                        }
        !           641: 
        !           642:                        /* add the text */
        !           643:                        *scan = '\0';
        !           644:                        add(tomark, tmpblk.c);
        !           645:                        tomark += MARK_AT_LINE(lines) + len - markidx(tomark);
        !           646:                }
        !           647: 
        !           648:                /* if partial last line, then retain that first newline */
        !           649:                if (len > 0)
        !           650:                {
        !           651:                        msg("Last line had no newline");
        !           652:                        tomark += BLKSIZE; /* <- for the rptlines calc */
        !           653:                }
        !           654:                else /* delete that first newline */
        !           655:                {
        !           656:                        delete(tomark, (tomark | (BLKSIZE - 1L)) + 1L);
        !           657:                }
        !           658:        }
        !           659: 
        !           660:        /* close the file */
        !           661:        close(fd);
        !           662: 
        !           663:        /* Reporting... */
        !           664:        rptlines = markline(tomark) - markline(frommark);
        !           665:        rptlabel = "read";
        !           666: 
        !           667:        if (addnl)
        !           668:                msg("Newlines were added to break up long lines");
        !           669:        if (hadnul)
        !           670:                msg("NULs were converted to 0x80");
        !           671: }
        !           672: 
        !           673: 
        !           674: 
        !           675: /*ARGSUSED*/
        !           676: void cmd_undo(frommark, tomark, cmd, bang, extra)
        !           677:        MARK    frommark;
        !           678:        MARK    tomark;
        !           679:        CMD     cmd;
        !           680:        int     bang;
        !           681:        char    *extra;
        !           682: {
        !           683:        undo();
        !           684: }
        !           685: 
        !           686: 
        !           687: /* print the selected lines */
        !           688: /*ARGSUSED*/
        !           689: void cmd_print(frommark, tomark, cmd, bang, extra)
        !           690:        MARK    frommark;
        !           691:        MARK    tomark;
        !           692:        CMD     cmd;
        !           693:        int     bang;
        !           694:        char    *extra;
        !           695: {
        !           696:        REG char        *scan;
        !           697:        REG long        l;
        !           698:        REG int         col;
        !           699: 
        !           700:        for (l = markline(frommark); l <= markline(tomark); l++)
        !           701:        {
        !           702:                /* display a line number, if CMD_NUMBER */
        !           703:                if (cmd == CMD_NUMBER)
        !           704:                {
        !           705:                        sprintf(tmpblk.c, "%6ld  ", l);
        !           706:                        qaddstr(tmpblk.c);
        !           707:                        col = 8;
        !           708:                }
        !           709:                else
        !           710:                {
        !           711:                        col = 0;
        !           712:                }
        !           713: 
        !           714:                /* get the next line & display it */
        !           715:                for (scan = fetchline(l); *scan; scan++)
        !           716:                {
        !           717:                        /* expand tabs to the proper width */
        !           718:                        if (*scan == '\t' && cmd != CMD_LIST)
        !           719:                        {
        !           720:                                do
        !           721:                                {
        !           722:                                        qaddch(' ');
        !           723:                                        col++;
        !           724:                                } while (col % *o_tabstop != 0);
        !           725:                        }
        !           726:                        else if (*scan >= 0 && *scan < ' ' || *scan == '\177')
        !           727:                        {
        !           728:                                qaddch('^');
        !           729:                                qaddch(*scan ^ 0x40);
        !           730:                                col += 2;
        !           731:                        }
        !           732:                        else if ((*scan & 0x80) && cmd == CMD_LIST)
        !           733:                        {
        !           734:                                sprintf(tmpblk.c, "\\%03o", *scan);
        !           735:                                qaddstr(tmpblk.c);
        !           736:                                col += 4;
        !           737:                        }
        !           738:                        else
        !           739:                        {
        !           740:                                qaddch(*scan);
        !           741:                                col++;
        !           742:                        }
        !           743: 
        !           744:                        /* wrap at the edge of the screen */
        !           745:                        if (!has_AM && col >= COLS)
        !           746:                        {
        !           747:                                addch('\n');
        !           748:                                col -= COLS;
        !           749:                        }
        !           750:                }
        !           751:                if (cmd == CMD_LIST)
        !           752:                {
        !           753:                        qaddch('$');
        !           754:                }
        !           755:                addch('\n');
        !           756:                exrefresh();
        !           757:        }
        !           758: }
        !           759: 
        !           760: 
        !           761: /* move or copy selected lines */
        !           762: /*ARGSUSED*/
        !           763: void cmd_move(frommark, tomark, cmd, bang, extra)
        !           764:        MARK    frommark;
        !           765:        MARK    tomark;
        !           766:        CMD     cmd;
        !           767:        int     bang;
        !           768:        char    *extra;
        !           769: {
        !           770:        MARK    destmark;
        !           771: 
        !           772:        /* parse the destination linespec.  No defaults.  Line 0 is okay */
        !           773:        destmark = cursor;
        !           774:        if (!strcmp(extra, "0"))
        !           775:        {
        !           776:                destmark = 0L;
        !           777:        }
        !           778:        else if (linespec(extra, &destmark) == extra || !destmark)
        !           779:        {
        !           780:                msg("invalid destination address");
        !           781:                return;
        !           782:        }
        !           783: 
        !           784:        /* flesh the marks out to encompass whole lines */
        !           785:        frommark &= ~(BLKSIZE - 1);
        !           786:        tomark = (tomark & ~(BLKSIZE - 1)) + BLKSIZE;
        !           787:        destmark = (destmark & ~(BLKSIZE - 1)) + BLKSIZE;
        !           788: 
        !           789:        /* make sure the destination is valid */
        !           790:        if (cmd == CMD_MOVE && destmark >= frommark && destmark < tomark)
        !           791:        {
        !           792:                msg("invalid destination address");
        !           793:        }
        !           794: 
        !           795:        /* Do it */
        !           796:        ChangeText
        !           797:        {
        !           798:                /* save the text to a cut buffer */
        !           799:                cutname('\0');
        !           800:                cut(frommark, tomark);
        !           801: 
        !           802:                /* if we're not copying, delete the old text & adjust destmark */
        !           803:                if (cmd != CMD_COPY)
        !           804:                {
        !           805:                        delete(frommark, tomark);
        !           806:                        if (destmark >= frommark)
        !           807:                        {
        !           808:                                destmark -= (tomark - frommark);
        !           809:                        }
        !           810:                }
        !           811: 
        !           812:                /* add the new text */
        !           813:                paste(destmark, FALSE, FALSE);
        !           814:        }
        !           815: 
        !           816:        /* move the cursor to the last line of the moved text */
        !           817:        cursor = destmark + (tomark - frommark) - BLKSIZE;
        !           818:        if (cursor < MARK_FIRST || cursor >= MARK_LAST + BLKSIZE)
        !           819:        {
        !           820:                cursor = MARK_LAST;
        !           821:        }
        !           822: 
        !           823:        /* Reporting... */
        !           824:        rptlabel = ( (cmd == CMD_COPY) ? "copied" : "moved" );
        !           825: }
        !           826: 
        !           827: 
        !           828: 
        !           829: /* execute EX commands from a file */
        !           830: /*ARGSUSED*/
        !           831: void cmd_source(frommark, tomark, cmd, bang, extra)
        !           832:        MARK    frommark;
        !           833:        MARK    tomark;
        !           834:        CMD     cmd;
        !           835:        int     bang;
        !           836:        char    *extra;
        !           837: {
        !           838:        /* must have a filename */
        !           839:        if (!*extra)
        !           840:        {
        !           841:                msg("\"source\" requires a filename");
        !           842:                return;
        !           843:        }
        !           844: 
        !           845:        doexrc(extra);
        !           846: }
        !           847: 
        !           848: 
        !           849: #ifndef NO_AT
        !           850: /*ARGSUSED*/
        !           851: void cmd_at(frommark, tomark, cmd, bang, extra)
        !           852:        MARK    frommark;
        !           853:        MARK    tomark;
        !           854:        CMD     cmd;
        !           855:        int     bang;
        !           856:        char    *extra;
        !           857: {
        !           858:        static  nest = FALSE;
        !           859:        int     result;
        !           860:        char    buf[MAXRCLEN];
        !           861: 
        !           862:        /* don't allow nested macros */
        !           863:        if (nest)
        !           864:        {
        !           865:                msg("@ macros can't be nested");
        !           866:                return;
        !           867:        }
        !           868:        nest = TRUE;
        !           869: 
        !           870:        /* require a buffer name */
        !           871:        if (*extra == '"')
        !           872:                extra++;
        !           873:        if (!*extra || !isascii(*extra) ||!islower(*extra))
        !           874:        {
        !           875:                msg("@ requires a cut buffer name (a-z)");
        !           876:        }
        !           877: 
        !           878:        /* get the contents of the buffer */
        !           879:        result = cb2str(*extra, buf, (unsigned)(sizeof buf));
        !           880:        if (result <= 0)
        !           881:        {
        !           882:                msg("buffer \"%c is empty", *extra);
        !           883:        }
        !           884:        else if (result >= sizeof buf)
        !           885:        {
        !           886:                msg("buffer \"%c is too large to execute", *extra);
        !           887:        }
        !           888:        else
        !           889:        {
        !           890:                /* execute the contents of the buffer as ex commands */
        !           891:                exstring(buf, result);
        !           892:        }
        !           893: 
        !           894:        nest = FALSE;
        !           895: }
        !           896: #endif

unix.superglobalmegacorp.com

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