diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 71 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 8 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 25 | ||||
-rw-r--r-- | src/nvim/ex_eval.c | 35 | ||||
-rw-r--r-- | src/nvim/fileio.c | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_startup.vim | 50 |
6 files changed, 135 insertions, 58 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 839d61cd2e..a5e8097133 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -602,8 +602,12 @@ void close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) * Remove the buffer from the list. */ if (wipe_buf) { - xfree(buf->b_ffname); - xfree(buf->b_sfname); + if (buf->b_sfname != buf->b_ffname) { + XFREE_CLEAR(buf->b_sfname); + } else { + buf->b_sfname = NULL; + } + XFREE_CLEAR(buf->b_ffname); if (buf->b_prev == NULL) { firstbuf = buf->b_next; } else { @@ -1693,15 +1697,18 @@ static inline void buf_init_changedtick(buf_T *const buf) /// if the buffer already exists. /// This is the ONLY way to create a new buffer. /// -/// @param ffname full path of fname or relative -/// @param sfname short fname or NULL +/// @param ffname_arg full path of fname or relative +/// @param sfname_arg short fname or NULL /// @param lnum preferred cursor line /// @param flags BLN_ defines /// @param bufnr /// /// @return pointer to the buffer -buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) +buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, + int flags) { + char_u *ffname = ffname_arg; + char_u *sfname = sfname_arg; buf_T *buf; fname_expand(curbuf, &ffname, &sfname); // will allocate ffname @@ -1787,8 +1794,12 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) buf->b_wininfo = xcalloc(1, sizeof(wininfo_T)); if (ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL)) { + if (buf->b_sfname != buf->b_ffname) { + XFREE_CLEAR(buf->b_sfname); + } else { + buf->b_sfname = NULL; + } XFREE_CLEAR(buf->b_ffname); - XFREE_CLEAR(buf->b_sfname); if (buf != curbuf) { free_buffer(buf); } @@ -2778,28 +2789,32 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) return OK; } -/* - * Set the file name for "buf"' to 'ffname', short file name to 'sfname'. - * The file name with the full path is also remembered, for when :cd is used. - * Returns FAIL for failure (file name already in use by other buffer) - * OK otherwise. - */ -int -setfname( +// Set the file name for "buf" to "ffname_arg", short file name to +// "sfname_arg". +// The file name with the full path is also remembered, for when :cd is used. +// Returns FAIL for failure (file name already in use by other buffer) +// OK otherwise. +int setfname( buf_T *buf, - char_u *ffname, - char_u *sfname, + char_u *ffname_arg, + char_u *sfname_arg, bool message // give message when buffer already exists ) { + char_u *ffname = ffname_arg; + char_u *sfname = sfname_arg; buf_T *obuf = NULL; FileID file_id; bool file_id_valid = false; if (ffname == NULL || *ffname == NUL) { // Removing the name. + if (buf->b_sfname != buf->b_ffname) { + XFREE_CLEAR(buf->b_sfname); + } else { + buf->b_sfname = NULL; + } XFREE_CLEAR(buf->b_ffname); - XFREE_CLEAR(buf->b_sfname); } else { fname_expand(buf, &ffname, &sfname); // will allocate ffname if (ffname == NULL) { // out of memory @@ -2830,8 +2845,10 @@ setfname( #ifdef USE_FNAME_CASE path_fix_case(sfname); // set correct case for short file name #endif + if (buf->b_sfname != buf->b_ffname) { + xfree(buf->b_sfname); + } xfree(buf->b_ffname); - xfree(buf->b_sfname); buf->b_ffname = ffname; buf->b_sfname = sfname; } @@ -2857,7 +2874,9 @@ void buf_set_name(int fnum, char_u *name) buf = buflist_findnr(fnum); if (buf != NULL) { - xfree(buf->b_sfname); + if (buf->b_sfname != buf->b_ffname) { + xfree(buf->b_sfname); + } xfree(buf->b_ffname); buf->b_ffname = vim_strsave(name); buf->b_sfname = NULL; @@ -4633,16 +4652,18 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) return true; } -/* - * Make "ffname" a full file name, set "sfname" to "ffname" if not NULL. - * "ffname" becomes a pointer to allocated memory (or NULL). - */ +// Make "*ffname" a full file name, set "*sfname" to "*ffname" if not NULL. +// "*ffname" becomes a pointer to allocated memory (or NULL). +// When resolving a link both "*sfname" and "*ffname" will point to the same +// allocated memory. +// The "*ffname" and "*sfname" pointer values on call will not be freed. +// Note that the resulting "*ffname" pointer should be considered not allocaed. void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) { - if (*ffname == NULL) { // if no file name given, nothing to do + if (*ffname == NULL) { // no file name given, nothing to do return; } - if (*sfname == NULL) { // if no short file name given, use ffname + if (*sfname == NULL) { // no short file name given, use ffname *sfname = *ffname; } *ffname = (char_u *)fix_fname((char *)(*ffname)); // expand to full path diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 44a9b39939..cc09b7e989 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -533,9 +533,11 @@ struct file_buffer { // b_fname is the same as b_sfname, unless ":cd" has been done, // then it is the same as b_ffname (NULL for no name). // - char_u *b_ffname; // full path file name - char_u *b_sfname; // short file name - char_u *b_fname; // current file name + char_u *b_ffname; // full path file name, allocated + char_u *b_sfname; // short file name, allocated, may be equal to + // b_ffname + char_u *b_fname; // current file name, points to b_ffname or + // b_sfname bool file_id_valid; FileID file_id; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index c87f253340..b23209e1b6 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2066,19 +2066,20 @@ static int check_readonly(int *forceit, buf_T *buf) return FALSE; } -/* - * Try to abandon current file and edit a new or existing file. - * "fnum" is the number of the file, if zero use ffname/sfname. - * "lnum" is the line number for the cursor in the new file (if non-zero). - * - * Return: - * GETFILE_ERROR for "normal" error, - * GETFILE_NOT_WRITTEN for "not written" error, - * GETFILE_SAME_FILE for success - * GETFILE_OPEN_OTHER for successfully opening another file. - */ -int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum, int forceit) +// Try to abandon the current file and edit a new or existing file. +// "fnum" is the number of the file, if zero use "ffname_arg"/"sfname_arg". +// "lnum" is the line number for the cursor in the new file (if non-zero). +// +// Return: +// GETFILE_ERROR for "normal" error, +// GETFILE_NOT_WRITTEN for "not written" error, +// GETFILE_SAME_FILE for success +// GETFILE_OPEN_OTHER for successfully opening another file. +int getfile(int fnum, char_u *ffname_arg, char_u *sfname_arg, int setpm, + linenr_T lnum, int forceit) { + char_u *ffname = ffname_arg; + char_u *sfname = sfname_arg; int other; int retval; char_u *free_me = NULL; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 0c7562980a..0917c6dd02 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -518,10 +518,13 @@ fail: * Discard an exception. "was_finished" is set when the exception has been * caught and the catch clause has been ended normally. */ -static void discard_exception(except_T *excp, int was_finished) +static void discard_exception(except_T *excp, bool was_finished) { char_u *saved_IObuff; + if (current_exception == excp) { + current_exception = NULL; + } if (excp == NULL) { internal_error("discard_exception()"); return; @@ -569,7 +572,6 @@ void discard_current_exception(void) { if (current_exception != NULL) { discard_exception(current_exception, false); - current_exception = NULL; } // Note: all globals manipulated here should be saved/restored in // try_enter/try_leave. @@ -652,8 +654,8 @@ static void finish_exception(except_T *excp) set_vim_var_string(VV_THROWPOINT, NULL, -1); } - /* Discard the exception, but use the finish message for 'verbose'. */ - discard_exception(excp, TRUE); + // Discard the exception, but use the finish message for 'verbose'. + discard_exception(excp, true); } /* @@ -1812,11 +1814,12 @@ void leave_cleanup(cleanup_T *csp) * made pending by it. Report this to the user if required by the * 'verbose' option or when debugging. */ if (aborting() || need_rethrow) { - if (pending & CSTP_THROW) - /* Cancel the pending exception (includes report). */ - discard_exception(csp->exception, FALSE); - else + if (pending & CSTP_THROW) { + // Cancel the pending exception (includes report). + discard_exception(csp->exception, false); + } else { report_discard_pending(pending, NULL); + } /* If an error was about to be converted to an exception when * enter_cleanup() was called, free the message list. */ @@ -1916,15 +1919,13 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) default: if (cstack->cs_flags[idx] & CSF_FINALLY) { if (cstack->cs_pending[idx] & CSTP_THROW) { - /* Cancel the pending exception. This is in the - * finally clause, so that the stack of the - * caught exceptions is not involved. */ - discard_exception((except_T *) - cstack->cs_exception[idx], - FALSE); - } else - report_discard_pending(cstack->cs_pending[idx], - NULL); + // Cancel the pending exception. This is in the + // finally clause, so that the stack of the + // caught exceptions is not involved. + discard_exception((except_T *)cstack->cs_exception[idx], false); + } else { + report_discard_pending(cstack->cs_pending[idx], NULL); + } cstack->cs_pending[idx] = CSTP_NONE; } break; diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index f4dd90fad2..3a84b5d41c 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -4217,7 +4217,9 @@ void shorten_buf_fname(buf_T *buf, char_u *dirname, int force) && (force || buf->b_sfname == NULL || path_is_absolute(buf->b_sfname))) { - XFREE_CLEAR(buf->b_sfname); + if (buf->b_sfname != buf->b_ffname) { + XFREE_CLEAR(buf->b_sfname); + } p = path_shorten_fname(buf->b_ffname, dirname); if (p != NULL) { buf->b_sfname = vim_strsave(p); diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 6214975ef5..e7f332bc4c 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -686,3 +686,53 @@ func Test_v_argv() call assert_true(idx > 2) call assert_equal(['arg1', '--cmd', 'echo v:argv', '--cmd', 'q'']'], list[idx:]) endfunc + +" Test the '-T' argument which sets the 'term' option. +func Test_T_arg() + throw 'skipped: Nvim does not support "-T" argument' + CheckNotGui + let after =<< trim [CODE] + call writefile([&term], "Xtest_T_arg") + qall + [CODE] + + for t in ['builtin_dumb', 'builtin_ansi'] + if RunVim([], after, '-T ' .. t) + let lines = readfile('Xtest_T_arg') + call assert_equal([t], lines) + endif + endfor + + call delete('Xtest_T_arg') +endfunc + +" Test the '-x' argument to read/write encrypted files. +func Test_x_arg() + CheckRunVimInTerminal + CheckFeature cryptv + + " Create an encrypted file Xtest_x_arg. + let buf = RunVimInTerminal('-n -x Xtest_x_arg', #{rows: 10, wait_for_ruler: 0}) + call WaitForAssert({-> assert_match('^Enter encryption key: ', term_getline(buf, 10))}) + call term_sendkeys(buf, "foo\n") + call WaitForAssert({-> assert_match('^Enter same key again: ', term_getline(buf, 10))}) + call term_sendkeys(buf, "foo\n") + call WaitForAssert({-> assert_match(' All$', term_getline(buf, 10))}) + call term_sendkeys(buf, "itest\<Esc>:w\<Enter>") + call WaitForAssert({-> assert_match('"Xtest_x_arg" \[New\]\[blowfish2\] 1L, 5B written', + \ term_getline(buf, 10))}) + call StopVimInTerminal(buf) + + " Read the encrypted file and check that it contains the expected content "test" + let buf = RunVimInTerminal('-n -x Xtest_x_arg', #{rows: 10, wait_for_ruler: 0}) + call WaitForAssert({-> assert_match('^Enter encryption key: ', term_getline(buf, 10))}) + call term_sendkeys(buf, "foo\n") + call WaitForAssert({-> assert_match('^Enter same key again: ', term_getline(buf, 10))}) + call term_sendkeys(buf, "foo\n") + call WaitForAssert({-> assert_match('^test', term_getline(buf, 1))}) + call StopVimInTerminal(buf) + + call delete('Xtest_x_arg') +endfunc + +" vim: shiftwidth=2 sts=2 expandtab |