diff options
Diffstat (limited to 'src/nvim/buffer.c')
| -rw-r--r-- | src/nvim/buffer.c | 125 | 
1 files changed, 90 insertions, 35 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index b5ca6543c5..90a564bb6a 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -91,6 +91,57 @@ static char *e_auabort = N_("E855: Autocommands caused command to abort");  // Number of times free_buffer() was called.  static int buf_free_count = 0; +// Read data from buffer for retrying. +static int +read_buffer( +    int     read_stdin,     // read file from stdin, otherwise fifo +    exarg_T *eap,           // for forced 'ff' and 'fenc' or NULL +    int     flags)          // extra flags for readfile() +{ +  int       retval = OK; +  linenr_T  line_count; + +  // +  // Read from the buffer which the text is already filled in and append at +  // the end.  This makes it possible to retry when 'fileformat' or +  // 'fileencoding' was guessed wrong. +  // +  line_count = curbuf->b_ml.ml_line_count; +  retval = readfile( +      read_stdin ? NULL : curbuf->b_ffname, +      read_stdin ? NULL : curbuf->b_fname, +      (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, +      flags | READ_BUFFER); +  if (retval == OK) { +    // Delete the binary lines. +    while (--line_count >= 0) { +      ml_delete((linenr_T)1, false); +    } +  } else { +    // Delete the converted lines. +    while (curbuf->b_ml.ml_line_count > line_count) { +      ml_delete(line_count, false); +    } +  } +  // Put the cursor on the first line. +  curwin->w_cursor.lnum = 1; +  curwin->w_cursor.col = 0; + +  if (read_stdin) { +    // Set or reset 'modified' before executing autocommands, so that +    // it can be changed there. +    if (!readonlymode && !bufempty()) { +      changed(); +    } else if (retval != FAIL) { +      unchanged(curbuf, false); +    } + +    apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, false, +                          curbuf, &retval); +  } +  return retval; +} +  /*   * Open current buffer, that is: open the memfile and read the file into   * memory. @@ -106,6 +157,7 @@ open_buffer (    int retval = OK;    bufref_T       old_curbuf;    long old_tw = curbuf->b_p_tw; +  int read_fifo = false;    /*     * The 'readonly' flag is only set when BF_NEVERLOADED is being reset. @@ -156,13 +208,45 @@ open_buffer (    if (curbuf->b_ffname != NULL) {      int old_msg_silent = msg_silent; +#ifdef UNIX +    int save_bin = curbuf->b_p_bin; +    int perm; + +    perm = os_getperm((const char *)curbuf->b_ffname); +    if (perm >= 0 && (0 +# ifdef S_ISFIFO +                      || S_ISFIFO(perm) +# endif +# ifdef S_ISSOCK +                      || S_ISSOCK(perm) +# endif +# ifdef OPEN_CHR_FILES +                      || (S_ISCHR(perm) +                          && is_dev_fd_file(curbuf->b_ffname)) +# endif +                      ) +        ) { +      read_fifo = true; +    } +    if (read_fifo) { +      curbuf->b_p_bin = true; +    } +#endif      if (shortmess(SHM_FILEINFO)) {        msg_silent = 1;      }      retval = readfile(curbuf->b_ffname, curbuf->b_fname,                        (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, -                      flags | READ_NEW); +                      flags | READ_NEW | (read_fifo ? READ_FIFO : 0)); +#ifdef UNIX +    if (read_fifo) { +      curbuf->b_p_bin = save_bin; +      if (retval == OK) { +        retval = read_buffer(false, eap, flags); +      } +    } +#endif      msg_silent = old_msg_silent;      // Help buffer is filtered. @@ -171,7 +255,6 @@ open_buffer (      }    } else if (read_stdin) {      int save_bin = curbuf->b_p_bin; -    linenr_T line_count;      /*       * First read the text in binary mode into the buffer. @@ -185,41 +268,13 @@ open_buffer (          flags | (READ_NEW + READ_STDIN));      curbuf->b_p_bin = save_bin;      if (retval == OK) { -      line_count = curbuf->b_ml.ml_line_count; -      retval = readfile(NULL, NULL, (linenr_T)line_count, -          (linenr_T)0, (linenr_T)MAXLNUM, eap, -          flags | READ_BUFFER); -      if (retval == OK) { -        /* Delete the binary lines. */ -        while (--line_count >= 0) -          ml_delete((linenr_T)1, FALSE); -      } else { -        /* Delete the converted lines. */ -        while (curbuf->b_ml.ml_line_count > line_count) -          ml_delete(line_count, FALSE); -      } -      /* Put the cursor on the first line. */ -      curwin->w_cursor.lnum = 1; -      curwin->w_cursor.col = 0; - -      // Set or reset 'modified' before executing autocommands, so that -      // it can be changed there. -      if (!readonlymode && !bufempty()) { -        changed(); -      } else if (retval == OK) { -        unchanged(curbuf, false); -      } - -      if (retval == OK) { -        apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, false, -                              curbuf, &retval); -      } +      retval = read_buffer(true, eap, flags);      }    }    /* if first time loading this buffer, init b_chartab[] */    if (curbuf->b_flags & BF_NEVERLOADED) { -    (void)buf_init_chartab(curbuf, FALSE); +    (void)buf_init_chartab(curbuf, false);      parse_cino(curbuf);    } @@ -234,7 +289,7 @@ open_buffer (        || modified_was_set               // ":set modified" used in autocmd        || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)) {      changed(); -  } else if (retval == OK && !read_stdin) { +  } else if (retval != FAIL && !read_stdin && !read_fifo) {      unchanged(curbuf, false);    }    save_file_ff(curbuf);                 // keep this fileformat @@ -416,8 +471,8 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)        return;      } -    /* When the buffer becomes hidden, but is not unloaded, trigger -     * BufHidden */ +    // When the buffer becomes hidden, but is not unloaded, trigger +    // BufHidden      if (!unload_buf) {        buf->b_locked++;        if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,  | 
