From 027387f70c671f62e3e08e0bdd09ec05b0232735 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 2 Jan 2016 22:25:52 +0100 Subject: 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) --- runtime/doc/editing.txt | 8 ++++---- src/ex_cmds2.c | 7 +++++-- src/ex_docmd.c | 6 +++--- src/gui.c | 2 +- src/gui_gtk_x11.c | 2 +- src/os_unix.c | 2 +- src/proto/ex_cmds2.pro | 2 +- src/testdir/test31.in | 20 ++++++++++++++++++++ src/testdir/test31.ok | 2 ++ src/version.c | 2 ++ 10 files changed, 40 insertions(+), 13 deletions(-) diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 5666e68b5a..4c013e9f5c 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1105,10 +1105,10 @@ The names can be in upper- or lowercase. the last file in the argument list has not been edited. See |:confirm| and 'confirm'. {not in Vi} -: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/ex_cmds2.c b/src/ex_cmds2.c index 30f9e9d18b..05baa7e99e 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -1636,10 +1636,13 @@ add_bufnum(bufnrs, bufnump, nr) /* * Return TRUE 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!". */ int -check_changed_any(hidden) +check_changed_any(hidden, unload) int hidden; /* Only check hidden buffers */ + int unload; { int ret = FALSE; buf_T *buf; @@ -1750,7 +1753,7 @@ buf_found: /* Open the changed buffer in the current window. */ if (buf != curbuf) - set_curbuf(buf, DOBUF_GOTO); + set_curbuf(buf, unload ? DOBUF_UNLOAD : DOBUF_GOTO); theend: vim_free(bufnrs); diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 648cc0d770..ac713dc13c 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7143,7 +7143,7 @@ ex_quit(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(); } @@ -7214,7 +7214,7 @@ ex_quit_all(eap) #endif exiting = TRUE; - if (eap->forceit || !check_changed_any(FALSE)) + if (eap->forceit || !check_changed_any(FALSE, FALSE)) getout(0); not_exiting(); } @@ -7609,7 +7609,7 @@ ex_exit(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(); } diff --git a/src/gui.c b/src/gui.c index 07365224d3..ec732e001c 100644 --- a/src/gui.c +++ b/src/gui.c @@ -825,7 +825,7 @@ gui_shell_closed() # endif /* If there are changed buffers, present the user with a dialog if * possible, otherwise give an error message. */ - if (!check_changed_any(FALSE)) + if (!check_changed_any(FALSE, FALSE)) getout(0); exiting = FALSE; diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index e543b0a375..9967795e07 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -2003,7 +2003,7 @@ sm_client_check_changed_any(GnomeClient *client UNUSED, * If there are changed buffers, present the user with * a dialog if possible, otherwise give an error message. */ - shutdown_cancelled = check_changed_any(FALSE); + shutdown_cancelled = check_changed_any(FALSE, FALSE); exiting = FALSE; cmdmod = save_cmdmod; diff --git a/src/os_unix.c b/src/os_unix.c index d4a0f6dbe8..36196369cb 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -7132,7 +7132,7 @@ xsmp_handle_interaction(smc_conn, client_data) save_cmdmod = cmdmod; cmdmod.confirm = TRUE; - if (check_changed_any(FALSE)) + if (check_changed_any(FALSE, FALSE)) /* Mustn't logout */ cancel_shutdown = True; cmdmod = save_cmdmod; diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro index 0ac3e14924..88758517f2 100644 --- a/src/proto/ex_cmds2.pro +++ b/src/proto/ex_cmds2.pro @@ -39,7 +39,7 @@ int check_changed __ARGS((buf_T *buf, int flags)); void browse_save_fname __ARGS((buf_T *buf)); void dialog_changed __ARGS((buf_T *buf, int checkall)); int can_abandon __ARGS((buf_T *buf, int forceit)); -int check_changed_any __ARGS((int hidden)); +int check_changed_any __ARGS((int hidden, int unload)); int check_fname __ARGS((void)); int buf_write_all __ARGS((buf_T *buf, int forceit)); int get_arglist __ARGS((garray_T *gap, char_u *str)); diff --git a/src/testdir/test31.in b/src/testdir/test31.in index 7dc2334781..3ba8431ccf 100644 --- a/src/testdir/test31.in +++ b/src/testdir/test31.in @@ -69,6 +69,26 @@ A 3:close! GA 4:all! :1wincmd w :w >>test.out +:" +:" test ":q!" and hidden buffer. +:bw! Xtest1 Xtest2 Xtest3 Xtest4 +:sp Xtest1 +:wincmd w +:bw! +:set modified +:bot sp Xtest2 +:set modified +:bot sp Xtest3 +:set modified +:wincmd t +:hide +:q! +:w >>test.out +:q! +:w >>test.out +:q! +:call append(line('$'), "Oh, Not finished yet.") +:w >>test.out :qa! ENDTEST diff --git a/src/testdir/test31.ok b/src/testdir/test31.ok index 185bdc768e..39531974c6 100644 --- a/src/testdir/test31.ok +++ b/src/testdir/test31.ok @@ -10,3 +10,5 @@ testtext 1 testtext 3 3 3 testtext 1 testtext 2 2 2 +testtext 3 +testtext 1 diff --git a/src/version.c b/src/version.c index 48c848529b..0ca4f8ab95 100644 --- a/src/version.c +++ b/src/version.c @@ -741,6 +741,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1037, /**/ 1036, /**/ -- cgit v1.2.3