aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/editing.txt8
-rw-r--r--src/nvim/ex_cmds2.c29
-rw-r--r--src/nvim/ex_docmd.c9
-rw-r--r--src/nvim/version.c2
-rw-r--r--test/functional/legacy/031_close_commands_spec.lua24
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()