vim-patch:7.4.1037

Problem:    Using "q!" when there is a modified hidden buffer does not unload
            the current buffer, resulting in the need to abandon it again.
Solution:   When using "q!" unload the current buffer when needed. (Yasuhiro
            Matsumoto, Hirohito Higashi)

027387f70c
This commit is contained in:
James McCoy 2016-05-10 22:50:31 -04:00
parent 529e2ab178
commit 8c399d6b37
5 changed files with 48 additions and 22 deletions

View File

@ -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.

View File

@ -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 */
)
/// 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)
{
int ret = FALSE;
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);

View File

@ -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 */

View File

@ -645,7 +645,7 @@ static int included_patches[] = {
// 1040 NA
// 1039,
// 1038 NA
// 1037,
1037,
// 1036,
1035,
// 1034,

View File

@ -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()