diff options
-rw-r--r-- | runtime/doc/editing.txt | 8 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 29 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 9 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | test/functional/legacy/031_close_commands_spec.lua | 24 |
5 files changed, 49 insertions, 23 deletions
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index b1dd3239ea..21496b135e 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1042,10 +1042,10 @@ The names can be in upper- or lowercase. the last file in the argument list has not been edited. See |:confirm| and 'confirm'. -:q[uit]! Quit without writing, also when currently visible - buffers have changes. Does not exit when this is the - last window and there is a changed hidden buffer. - In this case, the first changed hidden buffer becomes +:q[uit]! Quit without writing, also when currentl buffer has + changes. If this is the last window and there is a + modified hidden buffer, the current buffer is + abandoned and the first changed hidden buffer becomes the current buffer. Use ":qall!" to exit always. diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 12efddc205..b1dad21b02 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1241,16 +1241,18 @@ static void add_bufnum(int *bufnrs, int *bufnump, int nr) *bufnump = *bufnump + 1; } -/* - * Return TRUE if any buffer was changed and cannot be abandoned. - * That changed buffer becomes the current buffer. - */ -int -check_changed_any ( - int hidden /* Only check hidden buffers */ -) -{ - int ret = FALSE; +/// Check if any buffer was changed and cannot be abandoned. +/// That changed buffer becomes the current buffer. +/// When "unload" is true the current buffer is unloaded instead of making it +/// hidden. This is used for ":q!". +/// +/// @param[in] hidden specifies whether to check only hidden buffers. +/// @param[in] unload specifies whether to unload, instead of hide, the buffer. +/// +/// @returns true if any buffer is changed and cannot be abandoned +int check_changed_any(bool hidden, bool unload) +{ + bool ret = false; int save; int i; int bufnum = 0; @@ -1346,9 +1348,10 @@ check_changed_any ( } buf_found: - /* Open the changed buffer in the current window. */ - if (buf != curbuf) - set_curbuf(buf, DOBUF_GOTO); + // Open the changed buffer in the current window. + if (buf != curbuf) { + set_curbuf(buf, unload ? DOBUF_UNLOAD : DOBUF_GOTO); + } theend: xfree(bufnrs); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 89c35a3c45..bbe3525403 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5674,7 +5674,7 @@ static void ex_quit(exarg_T *eap) | (eap->forceit ? CCGD_FORCEIT : 0) | CCGD_EXCMD)) || check_more(TRUE, eap->forceit) == FAIL - || (only_one_window() && check_changed_any(eap->forceit))) { + || (only_one_window() && check_changed_any(eap->forceit, true))) { not_exiting(); } else { // quit last window @@ -5723,9 +5723,10 @@ static void ex_quit_all(exarg_T *eap) if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing)) return; - exiting = TRUE; - if (eap->forceit || !check_changed_any(FALSE)) + exiting = true; + if (eap->forceit || !check_changed_any(false, false)) { getout(0); + } not_exiting(); } @@ -6019,7 +6020,7 @@ static void ex_exit(exarg_T *eap) || curbufIsChanged()) && do_write(eap) == FAIL) || check_more(TRUE, eap->forceit) == FAIL - || (only_one_window() && check_changed_any(eap->forceit))) { + || (only_one_window() && check_changed_any(eap->forceit, false))) { not_exiting(); } else { if (only_one_window()) /* quit last window, exit Vim */ diff --git a/src/nvim/version.c b/src/nvim/version.c index 506bb1e3cf..7ee3b596de 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -645,7 +645,7 @@ static int included_patches[] = { // 1040 NA // 1039, // 1038 NA - // 1037, + 1037, // 1036, 1035, // 1034, diff --git a/test/functional/legacy/031_close_commands_spec.lua b/test/functional/legacy/031_close_commands_spec.lua index 3597cba12a..b79b1903ba 100644 --- a/test/functional/legacy/031_close_commands_spec.lua +++ b/test/functional/legacy/031_close_commands_spec.lua @@ -10,7 +10,7 @@ -- :edit local helpers = require('test.functional.helpers') -local feed, insert = helpers.feed, helpers.insert +local feed, insert, source = helpers.feed, helpers.insert, helpers.source local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('Commands that close windows and/or buffers', function() @@ -84,6 +84,28 @@ describe('Commands that close windows and/or buffers', function() feed('GA 4<Esc>:all!<CR>') execute('1wincmd w') expect('testtext 2 2 2') + + -- Test ":q!" and hidden buffer. + execute('bw! Xtest1 Xtest2 Xtest3 Xtest4') + execute('sp Xtest1') + execute('wincmd w') + execute('bw!') + execute('set modified') + execute('bot sp Xtest2') + execute('set modified') + execute('bot sp Xtest3') + execute('set modified') + execute('wincmd t') + execute('hide') + execute('q!') + expect('testtext 3') + execute('q!') + feed('<CR>') + expect('testtext 1') + source([[ + q! + " Now nvim should have exited + throw "Oh, Not finished yet."]]) end) teardown(function() |