A window is quitted without warning and any changes is lost

51 views
Skip to first unread message

Rick Howe

unread,
Oct 19, 2017, 1:26:18 AM10/19/17
to vim_dev
Usually, :q command will show a warning
E37: No write since last change (add ! to override)
and will not quit the window if the buffer is being changed.

However, the current buffer has been splitted into 2 or more windows
and use :{count}q command to a window of other buffers,
that window is quitted without warning and any changes is lost.

This happens on 8.0.2 and 8.0.1203.

I am not exactly sure but the following change in ex_docmd.c may fix the problem.
Looks like the current buffer is to be quitted as of 8.0.1203.

--- ex_docmdX.c 2017-10-16 18:16:44.114732500 +0900
+++ ex_docmd.c 2017-10-16 18:46:28.990821600 +0900
@@ -7224,10 +7224,10 @@
wp = curwin;

#ifdef FEAT_AUTOCMD
- apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer);
/* Refuse to quit when locked or when the buffer in the last window is
* being closed (can only happen in autocommands). */
- if (curbuf_locked() || !win_valid(wp)
+ if (!win_valid(wp)
|| (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0))
return;
#endif
@@ -7241,8 +7241,8 @@
*/
if (check_more(FALSE, eap->forceit) == OK && only_one_window())
exiting = TRUE;
- if ((!buf_hide(curbuf)
- && check_changed(curbuf, (p_awa ? CCGD_AW : 0)
+ if ((!buf_hide(wp->w_buffer)
+ && check_changed(wp->w_buffer, (p_awa ? CCGD_AW : 0)
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD))
|| check_more(TRUE, eap->forceit) == FAIL

Bram Moolenaar

unread,
Oct 19, 2017, 6:38:17 AM10/19/17
to vim...@googlegroups.com, Rick Howe

Rich Howe wrote:

> Usually, :q command will show a warning
> E37: No write since last change (add ! to override)
> and will not quit the window if the buffer is being changed.
>
> However, the current buffer has been splitted into 2 or more windows
> and use :{count}q command to a window of other buffers,
> that window is quitted without warning and any changes is lost.
>
> This happens on 8.0.2 and 8.0.1203.
>
> I am not exactly sure but the following change in ex_docmd.c may fix
> the problem. Looks like the current buffer is to be quitted as of
> 8.0.1203.

Can you give reproduction steps? I tried this:

vim foo
[add some text]
split bar
[add some text]
:1q
Get E37
:2q
Get E37

>
> --- ex_docmdX.c 2017-10-16 18:16:44.114732500 +0900
> +++ ex_docmd.c 2017-10-16 18:46:28.990821600 +0900
> @@ -7224,10 +7224,10 @@
> wp = curwin;
>
> #ifdef FEAT_AUTOCMD
> - apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
> + apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer);

That's a separate issue, I'll make a test for that.

> /* Refuse to quit when locked or when the buffer in the last window is
> * being closed (can only happen in autocommands). */
> - if (curbuf_locked() || !win_valid(wp)
> + if (!win_valid(wp)
> || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0))
> return;

This was correct, but curbuf_locked() should be called before
apply_autocmds().

> #endif
> @@ -7241,8 +7241,8 @@
> */
> if (check_more(FALSE, eap->forceit) == OK && only_one_window())
> exiting = TRUE;
> - if ((!buf_hide(curbuf)
> - && check_changed(curbuf, (p_awa ? CCGD_AW : 0)
> + if ((!buf_hide(wp->w_buffer)
> + && check_changed(wp->w_buffer, (p_awa ? CCGD_AW : 0)
> | (eap->forceit ? CCGD_FORCEIT : 0)
> | CCGD_EXCMD))
> || check_more(TRUE, eap->forceit) == FAIL

Should have a test for this change.

--
You know you use Vim too much when you have this alias in your
~/.bashrc file: alias :e=/bin/vim (Eljay Love-Jensen)

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Message has been deleted

Rick Howe

unread,
Oct 19, 2017, 9:43:48 AM10/19/17
to vim_dev
Thank you for your question.

> Can you give reproduction steps? I tried this:
>
> vim foo
> [add some text]
> split bar
> [add some text]
> :1q
> Get E37
> :2q
> Get E37

vim foo.txt
:split
:new
[add some text]
:3wincmd w
:1q

then the 1st window is quitted without E37 warning.

And QuitPre event is passed to the 1st (current) buffer, not 2nd.

Bram Moolenaar

unread,
Oct 19, 2017, 11:06:40 AM10/19/17
to vim...@googlegroups.com, Rick Howe

Rick Howe wrote:

> Thank you for your question.
> > Can you give reproduction steps? I tried this:
> >
> > vim foo
> > [add some text]
> > split bar
> > [add some text]
> > :1q
> > Get E37
> > :2q
> > Get E37
>
> vim foo.txt
> :split
> :new
> [add some text]
> :3wincmd w
> :1q
>
> then the 1st window is quitted without E37 warning.

Glad you found this. I'll add a test.

> And QuitPre event is passed to the 1st (current) buffer, not 2nd.

That should be fixed now.

--
ARTHUR: Well, I can't just call you `Man'.
DENNIS: Well, you could say `Dennis'.
ARTHUR: Well, I didn't know you were called `Dennis.'
DENNIS: Well, you didn't bother to find out, did you?
The Quest for the Holy Grail (Monty Python)

Rick Howe

unread,
Oct 19, 2017, 12:07:16 PM10/19/17
to vim_dev
Thank you. I found it fixed in the patch 1204 and 1205.

Tony Mechelynck

unread,
Oct 19, 2017, 2:03:25 PM10/19/17
to vim_dev, Rick Howe, Bram Moolenaar
BTW I can't find any documentation about :[count]q in the Vim help (in
particular editing.txt, last change 2017 Aug 21; and version8.txt,
last change 2017 Apr 23). :[range]wq refers to the lines to be
written, which is obviously not what this thread is about. Is this a
new feature? Or was it a bug which is evolving to an undocumented
feature, hopefully to be documented someday?

Best regards,
Tony.
> --
> --
> You received this message from the "vim_dev" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> ---
> You received this message because you are subscribed to the Google Groups "vim_dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

James McCoy

unread,
Oct 19, 2017, 2:31:41 PM10/19/17
to vim_dev, Rick Howe, Bram Moolenaar
On Oct 19, 2017 14:03, "Tony Mechelynck" <antoine.m...@gmail.com> wrote:
BTW I can't find any documentation about :[count]q in the Vim help (in
particular editing.txt, last change 2017 Aug 21; and version8.txt,
last change 2017 Apr 23). :[range]wq refers to the lines to be
written, which is obviously not what this thread is about.

Apparently, :q is documented in two places and the place with the :q tag doesn't mention this behavior. However, it does point you to the other location (:help CTRL-W_q), which does document it.

Cheers,
James

Tony Mechelynck

unread,
Oct 19, 2017, 3:09:18 PM10/19/17
to vim_dev, Rick Howe, Bram Moolenaar
Ah, I see. Thanks!

I didn't follow the CTRL-W_q link because I was looking for an
ex-command, not a Normal-mode command; and I tried

:helpgrep :\[count\]q
but not
:helpgrep :{count}q
which would have found it.

Best regards,
Tony.
Reply all
Reply to author
Forward
0 new messages