Merge #5470 from justinmk/pr5445

This commit is contained in:
Justin M. Keyes
2016-10-13 00:13:39 +02:00
committed by GitHub
7 changed files with 94 additions and 38 deletions

View File

@ -276,30 +276,25 @@ bool buf_valid(buf_T *buf)
return false; return false;
} }
/* /// Close the link to a buffer.
* Close the link to a buffer. ///
* "action" is used when there is no longer a window for the buffer. /// @param win If not NULL, set b_last_cursor.
* It can be: /// @param buf
* 0 buffer becomes hidden /// @param action Used when there is no longer a window for the buffer.
* DOBUF_UNLOAD buffer is unloaded /// Possible values:
* DOBUF_DELETE buffer is unloaded and removed from buffer list /// 0 buffer becomes hidden
* DOBUF_WIPE buffer is unloaded and really deleted /// DOBUF_UNLOAD buffer is unloaded
* When doing all but the first one on the current buffer, the caller should /// DOBUF_DELETE buffer is unloaded and removed from buffer list
* get a new buffer very soon! /// DOBUF_WIPE buffer is unloaded and really deleted
* /// When doing all but the first one on the current buffer, the
* The 'bufhidden' option can force freeing and deleting. /// caller should get a new buffer very soon!
* /// The 'bufhidden' option can force freeing and deleting.
* When "abort_if_last" is TRUE then do not close the buffer if autocommands /// @param abort_if_last
* cause there to be only one window with this buffer. e.g. when ":quit" is /// If TRUE, do not close the buffer if autocommands cause
* supposed to close the window but autocommands close all other windows. /// there to be only one window with this buffer. e.g. when
*/ /// ":quit" is supposed to close the window but autocommands
void /// close all other windows.
close_buffer ( void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
win_T *win, /* if not NULL, set b_last_cursor */
buf_T *buf,
int action,
int abort_if_last
)
{ {
bool unload_buf = (action != 0); bool unload_buf = (action != 0);
bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);

View File

@ -1286,10 +1286,9 @@ bool edit(int cmdchar, bool startln, long count)
{ {
if (curbuf->terminal) { if (curbuf->terminal) {
if (ex_normal_busy) { if (ex_normal_busy) {
// don't enter terminal mode from `ex_normal`, which can result in all // Do not enter terminal mode from ex_normal(), which would cause havoc
// kinds of havoc(such as terminal mode recursiveness). Instead, set a // (such as terminal-mode recursiveness). Instead set a flag to force-set
// flag that allow us to force-set the value of `restart_edit` before // the value of `restart_edit` before `ex_normal` returns.
// `ex_normal` returns
restart_edit = 'i'; restart_edit = 'i';
force_restart_edit = true; force_restart_edit = true;
} else { } else {

View File

@ -2116,6 +2116,14 @@ do_ecmd (
} }
} }
// Re-editing a terminal buffer: skip most buffer re-initialization.
if (!other_file && curbuf->terminal) {
check_arg_idx(curwin); // Needed when called from do_argfile().
maketitle(); // Title may show the arg index, e.g. "(2 of 5)".
retval = OK;
goto theend;
}
/* /*
* if the file was changed we may not be allowed to abandon it * if the file was changed we may not be allowed to abandon it
* - if we are going to re-edit the same file * - if we are going to re-edit the same file

View File

@ -6726,11 +6726,6 @@ do_exedit (
old_curwin == NULL ? curwin : NULL); old_curwin == NULL ? curwin : NULL);
} else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit) } else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit)
|| *eap->arg != NUL) { || *eap->arg != NUL) {
// ":edit <blank>" is a no-op in terminal buffers. #2822
if (curbuf->terminal != NULL && eap->cmdidx == CMD_edit && *eap->arg == NUL) {
return;
}
/* Can't edit another file when "curbuf_lock" is set. Only ":edit" /* Can't edit another file when "curbuf_lock" is set. Only ":edit"
* can bring us here, others are stopped earlier. */ * can bring us here, others are stopped earlier. */
if (*eap->arg != NUL && curbuf_locked()) if (*eap->arg != NUL && curbuf_locked())
@ -7921,9 +7916,8 @@ static void ex_normal(exarg_T *eap)
if (force_restart_edit) { if (force_restart_edit) {
force_restart_edit = false; force_restart_edit = false;
} else { } else {
// some function called was aware of ex_normal and decided to override the // Some function (terminal_enter()) was aware of ex_normal and decided to
// value of restart_edit anyway. So far only used in terminal mode(see // override the value of restart_edit anyway.
// terminal_enter() in edit.c)
restart_edit = save_restart_edit; restart_edit = save_restart_edit;
} }
p_im = save_insertmode; p_im = save_insertmode;

View File

@ -320,14 +320,18 @@ int main(int argc, char **argv)
// open terminals when opening files that start with term:// // open terminals when opening files that start with term://
#define PROTO "term://" #define PROTO "term://"
do_cmdline_cmd("augroup nvim_terminal");
do_cmdline_cmd("autocmd!");
do_cmdline_cmd("autocmd BufReadCmd " PROTO "* nested " do_cmdline_cmd("autocmd BufReadCmd " PROTO "* nested "
":call termopen( " ":if !exists('b:term_title')|call termopen( "
// Capture the command string // Capture the command string
"matchstr(expand(\"<amatch>\"), " "matchstr(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), " "'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
// capture the working directory // capture the working directory
"{'cwd': get(matchlist(expand(\"<amatch>\"), " "{'cwd': get(matchlist(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})"); "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})"
"|endif");
do_cmdline_cmd("augroup END");
#undef PROTO #undef PROTO
/* Execute --cmd arguments. */ /* Execute --cmd arguments. */

View File

@ -0,0 +1,30 @@
local helpers = require("test.functional.helpers")(after_each)
local eq, execute, funcs = helpers.eq, helpers.execute, helpers.funcs
local ok = helpers.ok
local clear = helpers.clear
describe(":argument", function()
before_each(function()
clear()
end)
it("does not restart :terminal buffer", function()
execute("terminal")
helpers.feed([[<C-\><C-N>]])
execute("argadd")
helpers.feed([[<C-\><C-N>]])
local bufname_before = funcs.bufname("%")
local bufnr_before = funcs.bufnr("%")
helpers.ok(nil ~= string.find(bufname_before, "^term://")) -- sanity
execute("argument 1")
helpers.feed([[<C-\><C-N>]])
local bufname_after = funcs.bufname("%")
local bufnr_after = funcs.bufnr("%")
eq("\n["..bufname_before.."] ", helpers.eval('execute("args")'))
ok(funcs.line('$') > 1)
eq(bufname_before, bufname_after)
eq(bufnr_before, bufnr_after)
end)
end)

View File

@ -0,0 +1,26 @@
local helpers = require("test.functional.helpers")(after_each)
local eq, execute, funcs = helpers.eq, helpers.execute, helpers.funcs
local ok = helpers.ok
local clear = helpers.clear
describe(":edit", function()
before_each(function()
clear()
end)
it("without arguments does not restart :terminal buffer", function()
execute("terminal")
helpers.feed([[<C-\><C-N>]])
local bufname_before = funcs.bufname("%")
local bufnr_before = funcs.bufnr("%")
helpers.ok(nil ~= string.find(bufname_before, "^term://")) -- sanity
execute("edit")
local bufname_after = funcs.bufname("%")
local bufnr_after = funcs.bufnr("%")
ok(funcs.line('$') > 1)
eq(bufname_before, bufname_after)
eq(bufnr_before, bufnr_after)
end)
end)