[BACK]Return to cmdcmds.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/cmdcmds.c, Revision 1.1

1.1     ! downsj      1: /* $OpenBSD$   */
        !             2: /* vi:set ts=4 sw=4:
        !             3:  *
        !             4:  * VIM - Vi IMproved       by Bram Moolenaar
        !             5:  *
        !             6:  * Do ":help uganda"  in Vim to read copying and usage conditions.
        !             7:  * Do ":help credits" in Vim to see a list of people who contributed.
        !             8:  */
        !             9:
        !            10: /*
        !            11:  * cmdcmds.c: functions for command line commands
        !            12:  */
        !            13:
        !            14: #include "vim.h"
        !            15: #include "globals.h"
        !            16: #include "proto.h"
        !            17: #include "option.h"
        !            18:
        !            19: #ifdef USE_TMPNAM
        !            20: # define mktemp(a) tmpnam(a)
        !            21: #endif
        !            22:
        !            23: extern char        *mktemp __ARGS((char *));
        !            24:
        !            25: #ifdef OS2
        !            26: static void check_tmpenv __ARGS((void));
        !            27: #endif
        !            28:
        !            29: #ifdef VIMINFO
        !            30: static char_u *viminfo_filename __ARGS((char_u     *));
        !            31: static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int want_info, int want_marks, int force_read));
        !            32: static int read_viminfo_up_to_marks __ARGS((char_u *line, FILE *fp, int force));
        !            33: #endif /* VIMINFO */
        !            34:
        !            35:    void
        !            36: do_ascii()
        !            37: {
        !            38:    int     c;
        !            39:    char    buf1[20];
        !            40:    char    buf2[20];
        !            41:    char_u  buf3[3];
        !            42:
        !            43:    c = gchar_cursor();
        !            44:    if (c == NL)            /* NUL is stored as NL */
        !            45:        c = NUL;
        !            46:    if (isprintchar(c) && (c < ' ' || c > '~'))
        !            47:    {
        !            48:        transchar_nonprint(buf3, c);
        !            49:        sprintf(buf1, "  <%s>", (char *)buf3);
        !            50:    }
        !            51:    else
        !            52:        buf1[0] = NUL;
        !            53:    if (c >= 0x80)
        !            54:        sprintf(buf2, "  <M-%s>", transchar(c & 0x7f));
        !            55:    else
        !            56:        buf2[0] = NUL;
        !            57:    sprintf((char *)IObuff, "<%s>%s%s  %d,  Hex %02x,  Octal %03o",
        !            58:                                           transchar(c), buf1, buf2, c, c, c);
        !            59:    msg(IObuff);
        !            60: }
        !            61:
        !            62: /*
        !            63:  * align text:
        !            64:  * type = -1  left aligned
        !            65:  * type = 0   centered
        !            66:  * type = 1   right aligned
        !            67:  */
        !            68:    void
        !            69: do_align(start, end, width, type)
        !            70:    linenr_t    start;
        !            71:    linenr_t    end;
        !            72:    int         width;
        !            73:    int         type;
        !            74: {
        !            75:    FPOS    pos;
        !            76:    int     len;
        !            77:    int     indent = 0;
        !            78:    int     new_indent = 0;         /* init for GCC */
        !            79:    char_u  *first;
        !            80:    char_u  *last;
        !            81:    int     save;
        !            82:
        !            83: #ifdef RIGHTLEFT
        !            84:    if (curwin->w_p_rl)
        !            85:        type = -type;   /* switch left and right aligning */
        !            86: #endif
        !            87:
        !            88:    pos = curwin->w_cursor;
        !            89:    if (type == -1)     /* left align: width is used for new indent */
        !            90:    {
        !            91:        if (width >= 0)
        !            92:            indent = width;
        !            93:    }
        !            94:    else
        !            95:    {
        !            96:        /*
        !            97:         * if 'textwidth' set, use it
        !            98:         * else if 'wrapmargin' set, use it
        !            99:         * if invalid value, use 80
        !           100:         */
        !           101:        if (width <= 0)
        !           102:            width = curbuf->b_p_tw;
        !           103:        if (width == 0 && curbuf->b_p_wm > 0)
        !           104:            width = Columns - curbuf->b_p_wm;
        !           105:        if (width <= 0)
        !           106:            width = 80;
        !           107:    }
        !           108:
        !           109:    if (u_save((linenr_t)(start - 1), (linenr_t)(end + 1)) == FAIL)
        !           110:        return;
        !           111:    for (curwin->w_cursor.lnum = start;
        !           112:                        curwin->w_cursor.lnum <= end; ++curwin->w_cursor.lnum)
        !           113:    {
        !           114:            /* find the first non-blank character */
        !           115:        first = skipwhite(ml_get_curline());
        !           116:            /* find the character after the last non-blank character */
        !           117:        for (last = first + STRLEN(first);
        !           118:                                last > first && vim_iswhite(last[-1]); --last)
        !           119:            ;
        !           120:        save = *last;
        !           121:        *last = NUL;
        !           122:        len = linetabsize(first);                   /* get line length */
        !           123:        *last = save;
        !           124:        if (len == 0)                               /* skip blank lines */
        !           125:            continue;
        !           126:        switch (type)
        !           127:        {
        !           128:            case -1:    new_indent = indent;            /* left align */
        !           129:                        break;
        !           130:            case 0:     new_indent = (width - len) / 2; /* center */
        !           131:                        break;
        !           132:            case 1:     new_indent = width - len;       /* right align */
        !           133:                        break;
        !           134:        }
        !           135:        if (new_indent < 0)
        !           136:            new_indent = 0;
        !           137:        set_indent(new_indent, TRUE);           /* set indent */
        !           138:    }
        !           139:    curwin->w_cursor = pos;
        !           140:    beginline(TRUE);
        !           141:    updateScreen(NOT_VALID);
        !           142: }
        !           143:
        !           144:    void
        !           145: do_retab(start, end, new_ts, force)
        !           146:    linenr_t    start;
        !           147:    linenr_t    end;
        !           148:    int         new_ts;
        !           149:    int         force;
        !           150: {
        !           151:    linenr_t    lnum;
        !           152:    int         got_tab = FALSE;
        !           153:    long        num_spaces = 0;
        !           154:    long        num_tabs;
        !           155:    long        len;
        !           156:    long        col;
        !           157:    long        vcol;
        !           158:    long        start_col = 0;          /* For start of white-space string */
        !           159:    long        start_vcol = 0;         /* For start of white-space string */
        !           160:    int         temp;
        !           161:    long        old_len;
        !           162:    char_u      *ptr;
        !           163:    char_u      *new_line = (char_u *)1;    /* init to non-NULL */
        !           164:    int         did_something = FALSE;
        !           165:    int         did_undo;               /* called u_save for current line */
        !           166:
        !           167:    if (new_ts == 0)
        !           168:        new_ts = curbuf->b_p_ts;
        !           169:    for (lnum = start; !got_int && lnum <= end; ++lnum)
        !           170:    {
        !           171:        ptr = ml_get(lnum);
        !           172:        col = 0;
        !           173:        vcol = 0;
        !           174:        did_undo = FALSE;
        !           175:        for (;;)
        !           176:        {
        !           177:            if (vim_iswhite(ptr[col]))
        !           178:            {
        !           179:                if (!got_tab && num_spaces == 0)
        !           180:                {
        !           181:                    /* First consecutive white-space */
        !           182:                    start_vcol = vcol;
        !           183:                    start_col = col;
        !           184:                }
        !           185:                if (ptr[col] == ' ')
        !           186:                    num_spaces++;
        !           187:                else
        !           188:                    got_tab = TRUE;
        !           189:            }
        !           190:            else
        !           191:            {
        !           192:                if (got_tab || (force && num_spaces > 1))
        !           193:                {
        !           194:                    /* Retabulate this string of white-space */
        !           195:
        !           196:                    /* len is virtual length of white string */
        !           197:                    len = num_spaces = vcol - start_vcol;
        !           198:                    num_tabs = 0;
        !           199:                    if (!curbuf->b_p_et)
        !           200:                    {
        !           201:                        temp = new_ts - (start_vcol % new_ts);
        !           202:                        if (num_spaces >= temp)
        !           203:                        {
        !           204:                            num_spaces -= temp;
        !           205:                            num_tabs++;
        !           206:                        }
        !           207:                        num_tabs += num_spaces / new_ts;
        !           208:                        num_spaces -= (num_spaces / new_ts) * new_ts;
        !           209:                    }
        !           210:                    if (curbuf->b_p_et || got_tab ||
        !           211:                                        (num_spaces + num_tabs < len))
        !           212:                    {
        !           213:                        if (did_undo == FALSE)
        !           214:                        {
        !           215:                            did_undo = TRUE;
        !           216:                            if (u_save((linenr_t)(lnum - 1),
        !           217:                                                (linenr_t)(lnum + 1)) == FAIL)
        !           218:                            {
        !           219:                                new_line = NULL;        /* flag out-of-memory */
        !           220:                                break;
        !           221:                            }
        !           222:                        }
        !           223:
        !           224:                        /* len is actual number of white characters used */
        !           225:                        len = num_spaces + num_tabs;
        !           226:                        old_len = STRLEN(ptr);
        !           227:                        new_line = lalloc(old_len - col + start_col + len + 1,
        !           228:                                                                        TRUE);
        !           229:                        if (new_line == NULL)
        !           230:                            break;
        !           231:                        if (start_col > 0)
        !           232:                            vim_memmove(new_line, ptr, (size_t)start_col);
        !           233:                        vim_memmove(new_line + start_col + len,
        !           234:                                      ptr + col, (size_t)(old_len - col + 1));
        !           235:                        ptr = new_line + start_col;
        !           236:                        for (col = 0; col < len; col++)
        !           237:                            ptr[col] = (col < num_tabs) ? '\t' : ' ';
        !           238:                        ml_replace(lnum, new_line, FALSE);
        !           239:                        did_something = TRUE;
        !           240:                        ptr = new_line;
        !           241:                        col = start_col + len;
        !           242:                    }
        !           243:                }
        !           244:                got_tab = FALSE;
        !           245:                num_spaces = 0;
        !           246:            }
        !           247:            if (ptr[col] == NUL)
        !           248:                break;
        !           249:            vcol += chartabsize(ptr[col++], (colnr_t)vcol);
        !           250:        }
        !           251:        if (new_line == NULL)               /* out of memory */
        !           252:            break;
        !           253:        line_breakcheck();
        !           254:    }
        !           255:    if (got_int)
        !           256:        emsg(e_interr);
        !           257:    if (did_something)
        !           258:        CHANGED;
        !           259:    curbuf->b_p_ts = new_ts;
        !           260:    coladvance(curwin->w_curswant);
        !           261: }
        !           262:
        !           263: /*
        !           264:  * :move command - move lines line1-line2 to line n
        !           265:  *
        !           266:  * return FAIL for failure, OK otherwise
        !           267:  */
        !           268:    int
        !           269: do_move(line1, line2, n)
        !           270:    linenr_t    line1;
        !           271:    linenr_t    line2;
        !           272:    linenr_t    n;
        !           273: {
        !           274:    char_u      *str;
        !           275:    linenr_t    l;
        !           276:    linenr_t    extra;      /* Num lines added before line1 */
        !           277:    linenr_t    num_lines;  /* Num lines moved */
        !           278:    linenr_t    last_line;  /* Last line in file after adding new text */
        !           279:    int         has_mark;
        !           280:
        !           281:    if (n >= line1 && n < line2)
        !           282:    {
        !           283:        EMSG("Move lines into themselves");
        !           284:        return FAIL;
        !           285:    }
        !           286:
        !           287:    num_lines = line2 - line1 + 1;
        !           288:
        !           289:    /*
        !           290:     * First we copy the old text to its new location -- webb
        !           291:     */
        !           292:    if (u_save(n, n + 1) == FAIL)
        !           293:        return FAIL;
        !           294:    for (extra = 0, l = line1; l <= line2; l++)
        !           295:    {
        !           296:        str = strsave(ml_get(l + extra));
        !           297:        if (str != NULL)
        !           298:        {
        !           299:            has_mark = ml_has_mark(l + extra);
        !           300:            ml_append(n + l - line1, str, (colnr_t)0, FALSE);
        !           301:            vim_free(str);
        !           302:            if (has_mark)
        !           303:                ml_setmarked(n + l - line1 + 1);
        !           304:            if (n < line1)
        !           305:                extra++;
        !           306:        }
        !           307:    }
        !           308:
        !           309:    /*
        !           310:     * Now we must be careful adjusting our marks so that we don't overlap our
        !           311:     * mark_adjust() calls.
        !           312:     *
        !           313:     * We adjust the marks within the old text so that they refer to the
        !           314:     * last lines of the file (temporarily), because we know no other marks
        !           315:     * will be set there since these line numbers did not exist until we added
        !           316:     * our new lines.
        !           317:     *
        !           318:     * Then we adjust the marks on lines between the old and new text positions
        !           319:     * (either forwards or backwards).
        !           320:     *
        !           321:     * And Finally we adjust the marks we put at the end of the file back to
        !           322:     * their final destination at the new text position -- webb
        !           323:     */
        !           324:    last_line = curbuf->b_ml.ml_line_count;
        !           325:    mark_adjust(line1, line2, last_line - line2, 0L);
        !           326:    if (n >= line2)
        !           327:        mark_adjust(line2 + 1, n, -num_lines, 0L);
        !           328:    else
        !           329:        mark_adjust(n + 1, line1 - 1, num_lines, 0L);
        !           330:    mark_adjust(last_line - num_lines + 1, last_line,
        !           331:                                                -(last_line - n - extra), 0L);
        !           332:
        !           333:    /*
        !           334:     * Now we delete the original text -- webb
        !           335:     */
        !           336:    if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL)
        !           337:        return FAIL;
        !           338:
        !           339:    for (l = line1; l <= line2; l++)
        !           340:        ml_delete(line1 + extra, TRUE);
        !           341:
        !           342:    CHANGED;
        !           343:    if (!global_busy && num_lines > p_report)
        !           344:        smsg((char_u *)"%ld line%s moved", num_lines, plural(num_lines));
        !           345:    return OK;
        !           346: }
        !           347:
        !           348: /*
        !           349:  * :copy command - copy lines line1-line2 to line n
        !           350:  */
        !           351:    void
        !           352: do_copy(line1, line2, n)
        !           353:    linenr_t    line1;
        !           354:    linenr_t    line2;
        !           355:    linenr_t    n;
        !           356: {
        !           357:    linenr_t        lnum;
        !           358:    char_u          *p;
        !           359:
        !           360:    mark_adjust(n + 1, MAXLNUM, line2 - line1 + 1, 0L);
        !           361:
        !           362:    /*
        !           363:     * there are three situations:
        !           364:     * 1. destination is above line1
        !           365:     * 2. destination is between line1 and line2
        !           366:     * 3. destination is below line2
        !           367:     *
        !           368:     * n = destination (when starting)
        !           369:     * curwin->w_cursor.lnum = destination (while copying)
        !           370:     * line1 = start of source (while copying)
        !           371:     * line2 = end of source (while copying)
        !           372:     */
        !           373:    if (u_save(n, n + 1) == FAIL)
        !           374:        return;
        !           375:    curwin->w_cursor.lnum = n;
        !           376:    lnum = line2 - line1 + 1;
        !           377:    while (line1 <= line2)
        !           378:    {
        !           379:        /* need to use strsave() because the line will be unlocked
        !           380:            within ml_append */
        !           381:        p = strsave(ml_get(line1));
        !           382:        if (p != NULL)
        !           383:        {
        !           384:            ml_append(curwin->w_cursor.lnum, p, (colnr_t)0, FALSE);
        !           385:            vim_free(p);
        !           386:        }
        !           387:                /* situation 2: skip already copied lines */
        !           388:        if (line1 == n)
        !           389:            line1 = curwin->w_cursor.lnum;
        !           390:        ++line1;
        !           391:        if (curwin->w_cursor.lnum < line1)
        !           392:            ++line1;
        !           393:        if (curwin->w_cursor.lnum < line2)
        !           394:            ++line2;
        !           395:        ++curwin->w_cursor.lnum;
        !           396:    }
        !           397:    CHANGED;
        !           398:    msgmore((long)lnum);
        !           399: }
        !           400:
        !           401: /*
        !           402:  * Handle the ":!cmd" command.  Also for ":r !cmd" and ":w !cmd"
        !           403:  * Bangs in the argument are replaced with the previously entered command.
        !           404:  * Remember the argument.
        !           405:  */
        !           406:    void
        !           407: do_bang(addr_count, line1, line2, forceit, arg, do_in, do_out)
        !           408:    int         addr_count;
        !           409:    linenr_t    line1, line2;
        !           410:    int         forceit;
        !           411:    char_u      *arg;
        !           412:    int         do_in, do_out;
        !           413: {
        !           414:    static  char_u  *prevcmd = NULL;        /* the previous command */
        !           415:    char_u          *newcmd = NULL;         /* the new command */
        !           416:    int             ins_prevcmd;
        !           417:    char_u          *t;
        !           418:    char_u          *p;
        !           419:    char_u          *trailarg;
        !           420:    int             len;
        !           421:    int             scroll_save = msg_scroll;
        !           422:
        !           423:    /*
        !           424:     * Disallow shell commands from .exrc and .vimrc in current directory for
        !           425:     * security reasons.
        !           426:     */
        !           427:    if (secure)
        !           428:    {
        !           429:        secure = 2;
        !           430:        emsg(e_curdir);
        !           431:        return;
        !           432:    }
        !           433:
        !           434:    if (addr_count == 0)                /* :! */
        !           435:    {
        !           436:        msg_scroll = FALSE;         /* don't scroll here */
        !           437:        autowrite_all();
        !           438:        msg_scroll = scroll_save;
        !           439:    }
        !           440:
        !           441:    /*
        !           442:     * Try to find an embedded bang, like in :!<cmd> ! [args]
        !           443:     * (:!! is indicated by the 'forceit' variable)
        !           444:     */
        !           445:    ins_prevcmd = forceit;
        !           446:    trailarg = arg;
        !           447:    do
        !           448:    {
        !           449:        len = STRLEN(trailarg) + 1;
        !           450:        if (newcmd != NULL)
        !           451:            len += STRLEN(newcmd);
        !           452:        if (ins_prevcmd)
        !           453:        {
        !           454:            if (prevcmd == NULL)
        !           455:            {
        !           456:                emsg(e_noprev);
        !           457:                vim_free(newcmd);
        !           458:                return;
        !           459:            }
        !           460:            len += STRLEN(prevcmd);
        !           461:        }
        !           462:        if ((t = alloc(len)) == NULL)
        !           463:        {
        !           464:            vim_free(newcmd);
        !           465:            return;
        !           466:        }
        !           467:        *t = NUL;
        !           468:        if (newcmd != NULL)
        !           469:            STRCAT(t, newcmd);
        !           470:        if (ins_prevcmd)
        !           471:            STRCAT(t, prevcmd);
        !           472:        p = t + STRLEN(t);
        !           473:        STRCAT(t, trailarg);
        !           474:        vim_free(newcmd);
        !           475:        newcmd = t;
        !           476:
        !           477:        /*
        !           478:         * Scan the rest of the argument for '!', which is replaced by the
        !           479:         * previous command.  "\!" is replaced by "!" (this is vi compatible).
        !           480:         */
        !           481:        trailarg = NULL;
        !           482:        while (*p)
        !           483:        {
        !           484:            if (*p == '!')
        !           485:            {
        !           486:                if (p > newcmd && p[-1] == '\\')
        !           487:                    vim_memmove(p - 1, p, (size_t)(STRLEN(p) + 1));
        !           488:                else
        !           489:                {
        !           490:                    trailarg = p;
        !           491:                    *trailarg++ = NUL;
        !           492:                    ins_prevcmd = TRUE;
        !           493:                    break;
        !           494:                }
        !           495:            }
        !           496:            ++p;
        !           497:        }
        !           498:    } while (trailarg != NULL);
        !           499:
        !           500:    vim_free(prevcmd);
        !           501:    prevcmd = newcmd;
        !           502:
        !           503:    if (bangredo)           /* put cmd in redo buffer for ! command */
        !           504:    {
        !           505:        AppendToRedobuff(prevcmd);
        !           506:        AppendToRedobuff((char_u *)"\n");
        !           507:        bangredo = FALSE;
        !           508:    }
        !           509:    if (addr_count == 0)                /* :! */
        !           510:    {
        !           511:            /* echo the command */
        !           512:        msg_start();
        !           513:        msg_outchar(':');
        !           514:        msg_outchar('!');
        !           515:        msg_outtrans(prevcmd);
        !           516:        msg_clr_eos();
        !           517:        windgoto(msg_row, msg_col);
        !           518:
        !           519:        do_shell(prevcmd);
        !           520:    }
        !           521:    else                                /* :range! */
        !           522:        do_filter(line1, line2, prevcmd, do_in, do_out);
        !           523: }
        !           524:
        !           525: /*
        !           526:  * call a shell to execute a command
        !           527:  */
        !           528:    void
        !           529: do_shell(cmd)
        !           530:    char_u  *cmd;
        !           531: {
        !           532:    BUF     *buf;
        !           533:    int     save_nwr;
        !           534:
        !           535:    /*
        !           536:     * Disallow shell commands from .exrc and .vimrc in current directory for
        !           537:     * security reasons.
        !           538:     */
        !           539:    if (secure)
        !           540:    {
        !           541:        secure = 2;
        !           542:        emsg(e_curdir);
        !           543:        msg_end();
        !           544:        return;
        !           545:    }
        !           546:
        !           547: #ifdef WIN32
        !           548:    /*
        !           549:     * Check if external commands are allowed now.
        !           550:     */
        !           551:    if (can_end_termcap_mode(TRUE) == FALSE)
        !           552:        return;
        !           553: #endif
        !           554:
        !           555:    /*
        !           556:     * For autocommands we want to get the output on the current screen, to
        !           557:     * avoid having to type return below.
        !           558:     */
        !           559:    msg_outchar('\r');                  /* put cursor at start of line */
        !           560: #ifdef AUTOCMD
        !           561:    if (!autocmd_busy)
        !           562: #endif
        !           563:        stoptermcap();
        !           564:    msg_outchar('\n');                  /* may shift screen one line up */
        !           565:
        !           566:        /* warning message before calling the shell */
        !           567:    if (p_warn
        !           568: #ifdef AUTOCMD
        !           569:                && !autocmd_busy
        !           570: #endif
        !           571:                                   )
        !           572:        for (buf = firstbuf; buf; buf = buf->b_next)
        !           573:            if (buf->b_changed)
        !           574:            {
        !           575:                MSG_OUTSTR("[No write since last change]\n");
        !           576:                break;
        !           577:            }
        !           578:
        !           579: /* This windgoto is required for when the '\n' resulted in a "delete line 1"
        !           580:  * command to the terminal. */
        !           581:
        !           582:    windgoto(msg_row, msg_col);
        !           583:    cursor_on();
        !           584:    (void)call_shell(cmd, SHELL_COOKED);
        !           585:    need_check_timestamps = TRUE;
        !           586:
        !           587: /*
        !           588:  * put the message cursor at the end of the screen, avoids wait_return() to
        !           589:  * overwrite the text that the external command showed
        !           590:  */
        !           591:    msg_pos((int)Rows - 1, 0);
        !           592:
        !           593: #ifdef AUTOCMD
        !           594:    if (!autocmd_busy)
        !           595: #endif
        !           596:    {
        !           597:        /*
        !           598:         * If K_TI is defined, we assume that we switch screens when
        !           599:         * starttermcap() is called. In that case we really want to wait for
        !           600:         * "hit return to continue".
        !           601:         */
        !           602:        save_nwr = no_wait_return;
        !           603:        if (*T_TI != NUL)
        !           604:            no_wait_return = FALSE;
        !           605: #ifdef AMIGA
        !           606:        wait_return(term_console ? -1 : TRUE);      /* see below */
        !           607: #else
        !           608:        wait_return(TRUE);
        !           609: #endif
        !           610:        no_wait_return = save_nwr;
        !           611:        starttermcap();     /* start termcap if not done by wait_return() */
        !           612:
        !           613:        /*
        !           614:         * In an Amiga window redrawing is caused by asking the window size.
        !           615:         * If we got an interrupt this will not work. The chance that the
        !           616:         * window size is wrong is very small, but we need to redraw the
        !           617:         * screen.  Don't do this if ':' hit in wait_return().  THIS IS UGLY
        !           618:         * but it saves an extra redraw.
        !           619:         */
        !           620: #ifdef AMIGA
        !           621:        if (skip_redraw)                /* ':' hit in wait_return() */
        !           622:            must_redraw = CLEAR;
        !           623:        else if (term_console)
        !           624:        {
        !           625:            OUTSTR("\033[0 q");         /* get window size */
        !           626:            if (got_int)
        !           627:                must_redraw = CLEAR;    /* if got_int is TRUE, redraw needed */
        !           628:            else
        !           629:                must_redraw = 0;        /* no extra redraw needed */
        !           630:        }
        !           631: #endif /* AMIGA */
        !           632:    }
        !           633: #ifdef AUTOCMD
        !           634:    else
        !           635:        must_redraw = CLEAR;
        !           636: #endif
        !           637: }
        !           638:
        !           639: /*
        !           640:  * do_filter: filter lines through a command given by the user
        !           641:  *
        !           642:  * We use temp files and the call_shell() routine here. This would normally
        !           643:  * be done using pipes on a UNIX machine, but this is more portable to
        !           644:  * non-unix machines. The call_shell() routine needs to be able
        !           645:  * to deal with redirection somehow, and should handle things like looking
        !           646:  * at the PATH env. variable, and adding reasonable extensions to the
        !           647:  * command name given by the user. All reasonable versions of call_shell()
        !           648:  * do this.
        !           649:  * We use input redirection if do_in is TRUE.
        !           650:  * We use output redirection if do_out is TRUE.
        !           651:  */
        !           652:    void
        !           653: do_filter(line1, line2, buff, do_in, do_out)
        !           654:    linenr_t    line1, line2;
        !           655:    char_u      *buff;
        !           656:    int         do_in, do_out;
        !           657: {
        !           658: #ifdef USE_TMPNAM
        !           659:    char_u      itmp[L_tmpnam];     /* use tmpnam() */
        !           660:    char_u      otmp[L_tmpnam];
        !           661: #else
        !           662:    char_u      itmp[TMPNAMELEN];
        !           663:    char_u      otmp[TMPNAMELEN];
        !           664: #endif
        !           665:    linenr_t    linecount;
        !           666:    FPOS        cursor_save;
        !           667:
        !           668:    /*
        !           669:     * Disallow shell commands from .exrc and .vimrc in current directory for
        !           670:     * security reasons.
        !           671:     */
        !           672:    if (secure)
        !           673:    {
        !           674:        secure = 2;
        !           675:        emsg(e_curdir);
        !           676:        return;
        !           677:    }
        !           678:    if (*buff == NUL)       /* no filter command */
        !           679:        return;
        !           680:
        !           681: #ifdef WIN32
        !           682:    /*
        !           683:     * Check if external commands are allowed now.
        !           684:     */
        !           685:    if (can_end_termcap_mode(TRUE) == FALSE)
        !           686:        return;
        !           687: #endif
        !           688:
        !           689:    cursor_save = curwin->w_cursor;
        !           690:    linecount = line2 - line1 + 1;
        !           691:    curwin->w_cursor.lnum = line1;
        !           692:    curwin->w_cursor.col = 0;
        !           693:
        !           694:    /*
        !           695:     * 1. Form temp file names
        !           696:     * 2. Write the lines to a temp file
        !           697:     * 3. Run the filter command on the temp file
        !           698:     * 4. Read the output of the command into the buffer
        !           699:     * 5. Delete the original lines to be filtered
        !           700:     * 6. Remove the temp files
        !           701:     */
        !           702:
        !           703: #ifndef USE_TMPNAM      /* tmpnam() will make its own name */
        !           704: # ifdef OS2
        !           705:    check_tmpenv();
        !           706:    expand_env(TMPNAME1, itmp, TMPNAMELEN);
        !           707:    expand_env(TMPNAME2, otmp, TMPNAMELEN);
        !           708: # else
        !           709:    STRCPY(itmp, TMPNAME1);
        !           710:    STRCPY(otmp, TMPNAME2);
        !           711: # endif
        !           712: #endif
        !           713:
        !           714:    if ((do_in && *mktemp((char *)itmp) == NUL) ||
        !           715:                                     (do_out && *mktemp((char *)otmp) == NUL))
        !           716:    {
        !           717:        emsg(e_notmp);
        !           718:        return;
        !           719:    }
        !           720:
        !           721: /*
        !           722:  * The writing and reading of temp files will not be shown.
        !           723:  * Vi also doesn't do this and the messages are not very informative.
        !           724:  */
        !           725:    ++no_wait_return;           /* don't call wait_return() while busy */
        !           726:    if (do_in && buf_write(curbuf, itmp, NULL, line1, line2,
        !           727:                                              FALSE, 0, FALSE, TRUE) == FAIL)
        !           728:    {
        !           729:        msg_outchar('\n');                  /* keep message from buf_write() */
        !           730:        --no_wait_return;
        !           731:        (void)emsg2(e_notcreate, itmp);     /* will call wait_return */
        !           732:        goto filterend;
        !           733:    }
        !           734:    if (!do_out)
        !           735:        msg_outchar('\n');
        !           736:
        !           737: #if (defined(UNIX) && !defined(ARCHIE)) || defined(OS2)
        !           738: /*
        !           739:  * put braces around the command (for concatenated commands)
        !           740:  */
        !           741:    sprintf((char *)IObuff, "(%s)", (char *)buff);
        !           742:    if (do_in)
        !           743:    {
        !           744:        STRCAT(IObuff, " < ");
        !           745:        STRCAT(IObuff, itmp);
        !           746:    }
        !           747: #else
        !           748: /*
        !           749:  * for shells that don't understand braces around commands, at least allow
        !           750:  * the use of commands in a pipe.
        !           751:  */
        !           752:    STRCPY(IObuff, buff);
        !           753:    if (do_in)
        !           754:    {
        !           755:        char_u      *p;
        !           756:    /*
        !           757:     * If there is a pipe, we have to put the '<' in front of it
        !           758:     */
        !           759:        p = vim_strchr(IObuff, '|');
        !           760:        if (p)
        !           761:            *p = NUL;
        !           762:        STRCAT(IObuff, " < ");
        !           763:        STRCAT(IObuff, itmp);
        !           764:        p = vim_strchr(buff, '|');
        !           765:        if (p)
        !           766:            STRCAT(IObuff, p);
        !           767:    }
        !           768: #endif
        !           769:    if (do_out)
        !           770:    {
        !           771:        char_u *p;
        !           772:
        !           773:        if ((p = vim_strchr(p_srr, '%')) != NULL && p[1] == 's')
        !           774:        {
        !           775:            p = IObuff + STRLEN(IObuff);
        !           776:            *p++ = ' '; /* not really needed? Not with sh, ksh or bash */
        !           777:            sprintf((char *)p, (char *)p_srr, (char *)otmp);
        !           778:        }
        !           779:        else
        !           780:            sprintf((char *)IObuff + STRLEN(IObuff), " %s %s",
        !           781:                                                 (char *)p_srr, (char *)otmp);
        !           782:    }
        !           783:
        !           784:    windgoto((int)Rows - 1, 0);
        !           785:    cursor_on();
        !           786:
        !           787:    /*
        !           788:     * When not redirecting the output the command can write anything to the
        !           789:     * screen. If 'shellredir' is equal to ">", screen may be messed up by
        !           790:     * stderr output of external command. Clear the screen later.
        !           791:     * If do_in is FALSE, this could be something like ":r !cat", which may
        !           792:     * also mess up the screen, clear it later.
        !           793:     */
        !           794:    if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in)
        !           795:        must_redraw = CLEAR;
        !           796:    else
        !           797:        redraw_later(NOT_VALID);
        !           798:
        !           799:    /*
        !           800:     * When call_shell() fails wait_return() is called to give the user a
        !           801:     * chance to read the error messages. Otherwise errors are ignored, so you
        !           802:     * can see the error messages from the command that appear on stdout; use
        !           803:     * 'u' to fix the text
        !           804:     * Switch to cooked mode when not redirecting stdin, avoids that something
        !           805:     * like ":r !cat" hangs.
        !           806:     */
        !           807:    if (call_shell(IObuff, SHELL_FILTER | SHELL_COOKED) == FAIL)
        !           808:    {
        !           809:        must_redraw = CLEAR;
        !           810:        wait_return(FALSE);
        !           811:    }
        !           812:    need_check_timestamps = TRUE;
        !           813:
        !           814:    if (do_out)
        !           815:    {
        !           816:        if (u_save((linenr_t)(line2), (linenr_t)(line2 + 1)) == FAIL)
        !           817:        {
        !           818:            goto error;
        !           819:        }
        !           820:        if (readfile(otmp, NULL, line2, FALSE, (linenr_t)0, MAXLNUM, TRUE)
        !           821:                                                                      == FAIL)
        !           822:        {
        !           823:            msg_outchar('\n');
        !           824:            emsg2(e_notread, otmp);
        !           825:            goto error;
        !           826:        }
        !           827:
        !           828:        if (do_in)
        !           829:        {
        !           830:            /* put cursor on first filtered line for ":range!cmd" */
        !           831:            curwin->w_cursor.lnum = line1;
        !           832:            dellines(linecount, TRUE, TRUE);
        !           833:            curbuf->b_op_start.lnum -= linecount;       /* adjust '[ */
        !           834:            curbuf->b_op_end.lnum -= linecount;         /* adjust '] */
        !           835:        }
        !           836:        else
        !           837:        {
        !           838:            /* put cursor on last new line for ":r !cmd" */
        !           839:            curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
        !           840:            linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
        !           841:        }
        !           842:        beginline(TRUE);                /* cursor on first non-blank */
        !           843:        --no_wait_return;
        !           844:
        !           845:        if (linecount > p_report)
        !           846:        {
        !           847:            if (do_in)
        !           848:            {
        !           849:                sprintf((char *)msg_buf, "%ld lines filtered", (long)linecount);
        !           850:                if (msg(msg_buf) && !msg_scroll)
        !           851:                    keep_msg = msg_buf;     /* display message after redraw */
        !           852:            }
        !           853:            else
        !           854:                msgmore((long)linecount);
        !           855:        }
        !           856:    }
        !           857:    else
        !           858:    {
        !           859: error:
        !           860:        /* put cursor back in same position for ":w !cmd" */
        !           861:        curwin->w_cursor = cursor_save;
        !           862:        --no_wait_return;
        !           863:        wait_return(FALSE);
        !           864:    }
        !           865:
        !           866: filterend:
        !           867:    vim_remove(itmp);
        !           868:    vim_remove(otmp);
        !           869: }
        !           870:
        !           871: #ifdef OS2
        !           872: /*
        !           873:  * If $TMP is not defined, construct a sensible default.
        !           874:  * This is required for TMPNAME1 and TMPNAME2 to work.
        !           875:  */
        !           876:    static void
        !           877: check_tmpenv()
        !           878: {
        !           879:    char_u  *envent;
        !           880:
        !           881:    if (getenv("TMP") == NULL)
        !           882:    {
        !           883:        envent = alloc(8);
        !           884:        if (envent != NULL)
        !           885:        {
        !           886:            strcpy(envent, "TMP=C:/");
        !           887:            putenv(envent);
        !           888:        }
        !           889:    }
        !           890: }
        !           891: #endif /* OS2 */
        !           892:
        !           893: #ifdef VIMINFO
        !           894:
        !           895: static int no_viminfo __ARGS((void));
        !           896:
        !           897:    static int
        !           898: no_viminfo()
        !           899: {
        !           900:    /* "vim -i NONE" does not read or write a viminfo file */
        !           901:    return (use_viminfo != NULL && STRCMP(use_viminfo, "NONE") == 0);
        !           902: }
        !           903:
        !           904: /*
        !           905:  * read_viminfo() -- Read the viminfo file.  Registers etc. which are already
        !           906:  * set are not over-written unless force is TRUE. -- webb
        !           907:  */
        !           908:    int
        !           909: read_viminfo(file, want_info, want_marks, force)
        !           910:    char_u  *file;
        !           911:    int     want_info;
        !           912:    int     want_marks;
        !           913:    int     force;
        !           914: {
        !           915:    FILE    *fp;
        !           916:
        !           917:    if (no_viminfo())
        !           918:        return FAIL;
        !           919:
        !           920:    file = viminfo_filename(file);          /* may set to default if NULL */
        !           921:    if ((fp = fopen((char *)file, READBIN)) == NULL)
        !           922:        return FAIL;
        !           923:
        !           924:    do_viminfo(fp, NULL, want_info, want_marks, force);
        !           925:
        !           926:    fclose(fp);
        !           927:
        !           928:    return OK;
        !           929: }
        !           930:
        !           931: /*
        !           932:  * write_viminfo() -- Write the viminfo file.  The old one is read in first so
        !           933:  * that effectively a merge of current info and old info is done.  This allows
        !           934:  * multiple vims to run simultaneously, without losing any marks etc.  If
        !           935:  * force is TRUE, then the old file is not read in, and only internal info is
        !           936:  * written to the file. -- webb
        !           937:  */
        !           938:    void
        !           939: write_viminfo(file, force)
        !           940:    char_u  *file;
        !           941:    int     force;
        !           942: {
        !           943:    FILE    *fp_in = NULL;
        !           944:    FILE    *fp_out = NULL;
        !           945: #ifdef USE_TMPNAM
        !           946:    char_u  tmpname[L_tmpnam];      /* use tmpnam() */
        !           947: #else
        !           948:    char_u  tmpname[TMPNAMELEN];
        !           949: #endif
        !           950:
        !           951:    if (no_viminfo())
        !           952:        return;
        !           953:
        !           954: #ifndef USE_TMPNAM      /* tmpnam() will make its own name */
        !           955: # ifdef OS2
        !           956:    check_tmpenv();
        !           957:    expand_env(TMPNAME2, tmpname, TMPNAMELEN);
        !           958: # else
        !           959:    STRCPY(tmpname, TMPNAME2);
        !           960: # endif
        !           961: #endif
        !           962:
        !           963:    file = viminfo_filename(file);      /* may set to default if NULL */
        !           964:    file = strsave(file);               /* make a copy, don't want NameBuff */
        !           965:    if (file != NULL)
        !           966:    {
        !           967:        fp_in = fopen((char *)file, READBIN);
        !           968:        if (fp_in == NULL)
        !           969:            fp_out = fopen((char *)file, WRITEBIN);
        !           970:        else if (*mktemp((char *)tmpname) != NUL)
        !           971:            fp_out = fopen((char *)tmpname, WRITEBIN);
        !           972:    }
        !           973:    if (file == NULL || fp_out == NULL)
        !           974:    {
        !           975:        EMSG2("Can't write viminfo file %s!", file == NULL ? (char_u *)"" :
        !           976:                                              fp_in == NULL ? file : tmpname);
        !           977:        if (fp_in != NULL)
        !           978:            fclose(fp_in);
        !           979:        vim_free(file);
        !           980:        return;
        !           981:    }
        !           982:
        !           983:    do_viminfo(fp_in, fp_out, !force, !force, FALSE);
        !           984:
        !           985:    fclose(fp_out);         /* errors are ignored !? */
        !           986:    if (fp_in != NULL)
        !           987:    {
        !           988:        fclose(fp_in);
        !           989:        if (vim_rename(tmpname, file) == -1)
        !           990:            vim_remove(tmpname);
        !           991:    }
        !           992:    vim_free(file);
        !           993: }
        !           994:
        !           995:    static char_u *
        !           996: viminfo_filename(file)
        !           997:    char_u      *file;
        !           998: {
        !           999:    if (file == NULL || *file == NUL)
        !          1000:    {
        !          1001:        expand_env(use_viminfo == NULL ? (char_u *)VIMINFO_FILE : use_viminfo,
        !          1002:                                                          NameBuff, MAXPATHL);
        !          1003:        return NameBuff;
        !          1004:    }
        !          1005:    return file;
        !          1006: }
        !          1007:
        !          1008: /*
        !          1009:  * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
        !          1010:  */
        !          1011:    static void
        !          1012: do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
        !          1013:    FILE    *fp_in;
        !          1014:    FILE    *fp_out;
        !          1015:    int     want_info;
        !          1016:    int     want_marks;
        !          1017:    int     force_read;
        !          1018: {
        !          1019:    int     count = 0;
        !          1020:    int     eof = FALSE;
        !          1021:    char_u  *line;
        !          1022:
        !          1023:    if ((line = alloc(LSIZE)) == NULL)
        !          1024:        return;
        !          1025:
        !          1026:    if (fp_in != NULL)
        !          1027:    {
        !          1028:        if (want_info)
        !          1029:            eof = read_viminfo_up_to_marks(line, fp_in, force_read);
        !          1030:        else
        !          1031:            /* Skip info, find start of marks */
        !          1032:            while (!(eof = vim_fgets(line, LSIZE, fp_in)) && line[0] != '>')
        !          1033:                ;
        !          1034:    }
        !          1035:    if (fp_out != NULL)
        !          1036:    {
        !          1037:        /* Write the info: */
        !          1038:        fprintf(fp_out, "# This viminfo file was generated by vim\n");
        !          1039:        fprintf(fp_out, "# You may edit it if you're careful!\n\n");
        !          1040:        write_viminfo_search_pattern(fp_out);
        !          1041:        write_viminfo_sub_string(fp_out);
        !          1042:        write_viminfo_history(fp_out);
        !          1043:        write_viminfo_registers(fp_out);
        !          1044:        write_viminfo_filemarks(fp_out);
        !          1045:        count = write_viminfo_marks(fp_out);
        !          1046:    }
        !          1047:    if (fp_in != NULL && want_marks)
        !          1048:        copy_viminfo_marks(line, fp_in, fp_out, count, eof);
        !          1049:    vim_free(line);
        !          1050: }
        !          1051:
        !          1052: /*
        !          1053:  * read_viminfo_up_to_marks() -- Only called from do_viminfo().  Reads in the
        !          1054:  * first part of the viminfo file which contains everything but the marks that
        !          1055:  * are local to a file.  Returns TRUE when end-of-file is reached. -- webb
        !          1056:  */
        !          1057:    static int
        !          1058: read_viminfo_up_to_marks(line, fp, force)
        !          1059:    char_u  *line;
        !          1060:    FILE    *fp;
        !          1061:    int     force;
        !          1062: {
        !          1063:    int     eof;
        !          1064:
        !          1065:    prepare_viminfo_history(force ? 9999 : 0);
        !          1066:    eof = vim_fgets(line, LSIZE, fp);
        !          1067:    while (!eof && line[0] != '>')
        !          1068:    {
        !          1069:        switch (line[0])
        !          1070:        {
        !          1071:            case NUL:
        !          1072:            case '\r':
        !          1073:            case '\n':
        !          1074:            case '#':       /* A comment */
        !          1075:                eof = vim_fgets(line, LSIZE, fp);
        !          1076:                break;
        !          1077:            case '"':
        !          1078:                eof = read_viminfo_register(line, fp, force);
        !          1079:                break;
        !          1080:            case '/':       /* Search string */
        !          1081:            case '&':       /* Substitute search string */
        !          1082:            case '~':       /* Last search string, followed by '/' or '&' */
        !          1083:                eof = read_viminfo_search_pattern(line, fp, force);
        !          1084:                break;
        !          1085:            case '$':
        !          1086:                eof = read_viminfo_sub_string(line, fp, force);
        !          1087:                break;
        !          1088:            case ':':
        !          1089:            case '?':
        !          1090:                eof = read_viminfo_history(line, fp);
        !          1091:                break;
        !          1092:            case '\'':
        !          1093:                /* How do we have a file mark when the file is not in the
        !          1094:                 * buffer list?
        !          1095:                 */
        !          1096:                eof = read_viminfo_filemark(line, fp, force);
        !          1097:                break;
        !          1098: #if 0
        !          1099:            case '+':
        !          1100:                /* eg: "+40 /path/dir file", for running vim with no args */
        !          1101:                eof = vim_fgets(line, LSIZE, fp);
        !          1102:                break;
        !          1103: #endif
        !          1104:            default:
        !          1105:                EMSG2("viminfo: Illegal starting char in line %s", line);
        !          1106:                eof = vim_fgets(line, LSIZE, fp);
        !          1107:                break;
        !          1108:        }
        !          1109:    }
        !          1110:    finish_viminfo_history();
        !          1111:    return eof;
        !          1112: }
        !          1113:
        !          1114: /*
        !          1115:  * check string read from viminfo file
        !          1116:  * remove '\n' at the end of the line
        !          1117:  * - replace CTRL-V CTRL-V with CTRL-V
        !          1118:  * - replace CTRL-V 'n'    with '\n'
        !          1119:  */
        !          1120:    void
        !          1121: viminfo_readstring(p)
        !          1122:    char_u      *p;
        !          1123: {
        !          1124:    while (*p != NUL && *p != '\n')
        !          1125:    {
        !          1126:        if (*p == Ctrl('V'))
        !          1127:        {
        !          1128:            if (p[1] == 'n')
        !          1129:                p[0] = '\n';
        !          1130:            vim_memmove(p + 1, p + 2, STRLEN(p));
        !          1131:        }
        !          1132:        ++p;
        !          1133:    }
        !          1134:    *p = NUL;
        !          1135: }
        !          1136:
        !          1137: /*
        !          1138:  * write string to viminfo file
        !          1139:  * - replace CTRL-V with CTRL-V CTRL-V
        !          1140:  * - replace '\n'   with CTRL-V 'n'
        !          1141:  * - add a '\n' at the end
        !          1142:  */
        !          1143:    void
        !          1144: viminfo_writestring(fd, p)
        !          1145:    FILE    *fd;
        !          1146:    char_u  *p;
        !          1147: {
        !          1148:    register int    c;
        !          1149:
        !          1150:    while ((c = *p++) != NUL)
        !          1151:    {
        !          1152:        if (c == Ctrl('V') || c == '\n')
        !          1153:        {
        !          1154:            putc(Ctrl('V'), fd);
        !          1155:            if (c == '\n')
        !          1156:                c = 'n';
        !          1157:        }
        !          1158:        putc(c, fd);
        !          1159:    }
        !          1160:    putc('\n', fd);
        !          1161: }
        !          1162: #endif /* VIMINFO */
        !          1163:
        !          1164: /*
        !          1165:  * Implementation of ":fixdel", also used by get_stty().
        !          1166:  *  <BS>    resulting <Del>
        !          1167:  *   ^?        ^H
        !          1168:  * not ^?      ^?
        !          1169:  */
        !          1170:    void
        !          1171: do_fixdel()
        !          1172: {
        !          1173:    char_u  *p;
        !          1174:
        !          1175:    p = find_termcode((char_u *)"kb");
        !          1176:    add_termcode((char_u *)"kD", p != NULL && *p == 0x7f ?
        !          1177:                                         (char_u *)"\010" : (char_u *)"\177");
        !          1178: }
        !          1179:
        !          1180:    void
        !          1181: print_line(lnum, use_number)
        !          1182:    linenr_t    lnum;
        !          1183:    int         use_number;
        !          1184: {
        !          1185:    char_u      numbuf[20];
        !          1186:
        !          1187:    msg_outchar('\n');
        !          1188:    if (curwin->w_p_nu || use_number)
        !          1189:    {
        !          1190:        sprintf((char *)numbuf, "%7ld ", (long)lnum);
        !          1191:        set_highlight('n');     /* Highlight line numbers */
        !          1192:        start_highlight();
        !          1193:        msg_outstr(numbuf);
        !          1194:        stop_highlight();
        !          1195:    }
        !          1196:    msg_prt_line(ml_get(lnum));
        !          1197: }
        !          1198:
        !          1199: /*
        !          1200:  * Implementation of ":file [fname]".
        !          1201:  */
        !          1202:    void
        !          1203: do_file(arg, forceit)
        !          1204:    char_u  *arg;
        !          1205:    int     forceit;
        !          1206: {
        !          1207:    char_u      *fname, *sfname;
        !          1208:    BUF         *buf;
        !          1209:
        !          1210:    if (*arg != NUL)
        !          1211:    {
        !          1212:        /*
        !          1213:         * The name of the current buffer will be changed.
        !          1214:         * A new buffer entry needs to be made to hold the old
        !          1215:         * file name, which will become the alternate file name.
        !          1216:         */
        !          1217:        fname = curbuf->b_filename;
        !          1218:        sfname = curbuf->b_sfilename;
        !          1219:        curbuf->b_filename = NULL;
        !          1220:        curbuf->b_sfilename = NULL;
        !          1221:        if (setfname(arg, NULL, TRUE) == FAIL)
        !          1222:        {
        !          1223:            curbuf->b_filename = fname;
        !          1224:            curbuf->b_sfilename = sfname;
        !          1225:            return;
        !          1226:        }
        !          1227:        curbuf->b_notedited = TRUE;
        !          1228:        buf = buflist_new(fname, sfname, curwin->w_cursor.lnum, FALSE);
        !          1229:        if (buf != NULL)
        !          1230:            curwin->w_alt_fnum = buf->b_fnum;
        !          1231:        vim_free(fname);
        !          1232:        vim_free(sfname);
        !          1233:    }
        !          1234:    /* print full filename if :cd used */
        !          1235:    fileinfo(did_cd, FALSE, forceit);
        !          1236: }