vim-patch:9.2.0443: GUI: cancelling save dialog overwrites or discards unnamed buffer (#39617)

Problem:  When closing gvim with an unsaved unnamed buffer, choosing
          "Yes" in the "Save changes?" dialog and then "Cancel" in the
          file selection dialog either silently writes the buffer to a
          file named "Untitled" (overwriting any existing file with
          that name) or discards the buffer altogether
          (vibs29, after v9.1.0265).
Solution: In dialog_changed(), if browse_save_fname() leaves the buffer
          without a file name, treat it as a cancel and return without
          saving.  Also stop clearing the modified flag in the restore
          path on write failure, so the unsaved changes are kept and
          the caller (e.g. gui_shell_closed()) can also cancel the
          close.  Pre-fill the file dialog with "Untitled" to match
          the preceding "Save changes to ..." prompt.  Add a test for
          the write-failure path (Hirohito Higashi).

fixes:  vim/vim#20132
closes: vim/vim#20143

https://github.com/vim/vim/commit/cf947e7ef09fc8a63f447b54b107585b8f3b7abe

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
This commit is contained in:
zeertzjq
2026-05-06 08:19:30 +08:00
committed by GitHub
parent f39f6f72a7
commit 2bb426ce4a
2 changed files with 23 additions and 2 deletions
+1 -2
View File
@@ -223,12 +223,11 @@ void dialog_changed(buf_T *buf, bool checkall)
}
}
// restore to empty when write failed
// restore to empty when write failed or was cancelled
if (empty_bufname) {
buf->b_fname = NULL;
XFREE_CLEAR(buf->b_ffname);
XFREE_CLEAR(buf->b_sfname);
unchanged(buf, true, false);
}
} else if (ret == VIM_NO) {
unchanged(buf, true, false);
+22
View File
@@ -344,6 +344,28 @@ func Test_goto_buf_with_confirm()
close!
endfunc
" Test for issue #20132: when saving an unnamed buffer fails the modified
" flag must be kept, otherwise the buffer is silently discarded.
func Test_dialog_changed_keep_modified_on_write_fail()
CheckUnix
CheckNotGui
CheckFeature dialog_con
CheckNotFeature dialog_con_gui
CheckNotRoot
call writefile(['existing'], 'Untitled', 'D')
call setfperm('Untitled', 'r--r--r--')
new
call setline(1, 'test')
call feedkeys('y', 'L')
silent! confirm bdel
call assert_true(&modified)
call assert_equal(['existing'], readfile('Untitled'))
bw!
endfunc
" Test for splitting buffer with 'switchbuf'
func Test_buffer_switchbuf()
new Xswitchbuf