diff options
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r-- | src/nvim/ex_docmd.c | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 6e7938046a..f64c9fded8 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9,6 +9,7 @@ #include <string.h> #include <stdbool.h> #include <stdint.h> +#include <stdlib.h> #include <inttypes.h> #include "nvim/vim.h" @@ -1668,8 +1669,8 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (*ea.cmd == ';') { if (!ea.skip) { curwin->w_cursor.lnum = ea.line2; - // Don't leave the cursor on an illegal line (caused by ';') - check_cursor_lnum(); + // don't leave the cursor on an illegal line or column + check_cursor(); } } else if (*ea.cmd != ',') { break; @@ -1813,7 +1814,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (text_locked() && !(ea.argt & CMDWIN) && !IS_USER_CMDIDX(ea.cmdidx)) { // Command not allowed when editing the command line. - errormsg = get_text_locked_msg(); + errormsg = (char_u *)_(get_text_locked_msg()); goto doend; } /* Disallow editing another buffer when "curbuf_lock" is set. @@ -5995,7 +5996,7 @@ static void ex_quit(exarg_T *eap) */ static void ex_cquit(exarg_T *eap) { - getout(1); + getout(eap->addr_count > 0 ? (int)eap->line2 : EXIT_FAILURE); } /* @@ -8810,11 +8811,12 @@ makeopens ( && buf->b_fname != NULL && buf->b_p_bl) { if (fprintf(fd, "badd +%" PRId64 " ", - buf->b_wininfo == NULL ? - (int64_t)1L : - (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 - || ses_fname(fd, buf, &ssop_flags) == FAIL) + buf->b_wininfo == NULL + ? (int64_t)1L + : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 + || ses_fname(fd, buf, &ssop_flags, true) == FAIL) { return FAIL; + } } } @@ -8885,11 +8887,13 @@ makeopens ( && !bt_nofile(wp->w_buffer) ) { if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0 - || ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL) + || ses_fname(fd, wp->w_buffer, &ssop_flags, true) == FAIL) { return FAIL; - need_tabnew = FALSE; - if (!wp->w_arg_idx_invalid) + } + need_tabnew = false; + if (!wp->w_arg_idx_invalid) { edited_win = wp; + } break; } } @@ -8933,6 +8937,8 @@ makeopens ( // resized when moving between windows. // Do this before restoring the view, so that the topline and the // cursor can be set. This is done again below. + // winminheight and winminwidth need to be set to avoid an error if the + // user has set winheight or winwidth. if (put_line(fd, "set winminheight=1 winminwidth=1 winheight=1 winwidth=1") == FAIL) { return FAIL; @@ -9221,24 +9227,35 @@ put_view ( if (wp->w_buffer->b_ffname != NULL && (!bt_nofile(wp->w_buffer) || wp->w_buffer->terminal) ) { - /* - * Editing a file in this buffer: use ":edit file". - * This may have side effects! (e.g., compressed or network file). - */ - if (fputs("edit ", fd) < 0 - || ses_fname(fd, wp->w_buffer, flagp) == FAIL) + // Editing a file in this buffer: use ":edit file". + // This may have side effects! (e.g., compressed or network file). + // + // Note, if a buffer for that file already exists, use :badd to + // edit that buffer, to not lose folding information (:edit resets + // folds in other buffers) + if (fputs("if bufexists('", fd) < 0 + || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL + || fputs("') | buffer ", fd) < 0 + || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL + || fputs(" | else | edit ", fd) < 0 + || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL + || fputs(" | endif", fd) < 0 + || put_eol(fd) == FAIL) { return FAIL; + } } else { - /* No file in this buffer, just make it empty. */ - if (put_line(fd, "enew") == FAIL) + // No file in this buffer, just make it empty. + if (put_line(fd, "enew") == FAIL) { return FAIL; + } if (wp->w_buffer->b_ffname != NULL) { - /* The buffer does have a name, but it's not a file name. */ + // The buffer does have a name, but it's not a file name. if (fputs("file ", fd) < 0 - || ses_fname(fd, wp->w_buffer, flagp) == FAIL) + || ses_fname(fd, wp->w_buffer, flagp, true) == FAIL) { return FAIL; + } } - do_cursor = FALSE; + do_cursor = false; } } @@ -9378,7 +9395,7 @@ ses_arglist ( (void)vim_FullName((char *)s, (char *)buf, MAXPATHL, FALSE); s = buf; } - if (fputs("argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL + if (fputs("$argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL || put_eol(fd) == FAIL) { xfree(buf); return FAIL; @@ -9389,12 +9406,10 @@ ses_arglist ( return OK; } -/* - * Write a buffer name to the session file. - * Also ends the line. - * Returns FAIL if writing fails. - */ -static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp) +/// Write a buffer name to the session file. +/// Also ends the line, if "add_eol" is true. +/// Returns FAIL if writing fails. +static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, bool add_eol) { char_u *name; @@ -9411,8 +9426,10 @@ static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp) name = buf->b_sfname; else name = buf->b_ffname; - if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL) + if (ses_put_fname(fd, name, flagp) == FAIL + || (add_eol && put_eol(fd) == FAIL)) { return FAIL; + } return OK; } @@ -9835,7 +9852,7 @@ static void ex_terminal(exarg_T *eap) if (*eap->arg != NUL) { // Run {cmd} in 'shell'. char *name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\"); snprintf(ex_cmd, sizeof(ex_cmd), - ":enew%s | call termopen(\"%s\") | startinsert", + ":enew%s | call termopen(\"%s\")", eap->forceit ? "!" : "", name); xfree(name); } else { // No {cmd}: run the job with tokenized 'shell'. @@ -9857,7 +9874,7 @@ static void ex_terminal(exarg_T *eap) shell_free_argv(argv); snprintf(ex_cmd, sizeof(ex_cmd), - ":enew%s | call termopen([%s]) | startinsert", + ":enew%s | call termopen([%s])", eap->forceit ? "!" : "", shell_argv + 1); } |