patch 9.2.0443: GUI: cancelling save dialog overwrites or discards unnamed buffer

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:  #20132
closes: #20143

Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Hirohito Higashi
2026-05-05 19:02:59 +00:00
committed by Christian Brabandt
parent 2bfddbea47
commit cf947e7ef0
3 changed files with 30 additions and 3 deletions
+6 -3
View File
@@ -141,7 +141,7 @@ browse_save_fname(buf_T *buf)
char_u *fname;
fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
NULL, NULL, NULL, NULL, buf);
(char_u *)"Untitled", NULL, NULL, NULL, buf);
if (fname == NULL)
return;
@@ -182,6 +182,10 @@ dialog_changed(
# ifdef FEAT_BROWSE
// May get file name, when there is none
browse_save_fname(buf);
// User cancelled the file dialog; keep the buffer modified.
if (buf->b_fname == NULL)
return;
# endif
empty_bufname = buf->b_fname == NULL ? TRUE : FALSE;
if (empty_bufname)
@@ -194,13 +198,12 @@ dialog_changed(
return;
}
// restore to empty when write failed
// restore to empty when write failed or was cancelled
if (empty_bufname)
{
buf->b_fname = NULL;
VIM_CLEAR(buf->b_ffname);
VIM_CLEAR(buf->b_sfname);
unchanged(buf, TRUE, FALSE);
}
}
else if (ret == VIM_NO)
+22
View File
@@ -342,6 +342,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
+2
View File
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
443,
/**/
442,
/**/