home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / amiga / vim46src.lha / vim-4.6 / src / cmdcmds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-27  |  33.5 KB  |  1,482 lines

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