/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
/*
* ex_cmds2.c: some more functions for command line commands
*/
#include "vim.h"
#include "version.h"
/*
* If 'autowrite' option set, try to write the file.
* Careful: autocommands may make "buf" invalid!
*
* return FAIL for failure, OK otherwise
*/
int
autowrite(buf_T *buf, int forceit)
{
int r;
bufref_T bufref;
if (!(p_aw || p_awa) || !p_write
#ifdef FEAT_QUICKFIX
// never autowrite a "nofile" or "nowrite" buffer
|| bt_dontwrite(buf)
#endif
|| (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
return FAIL;
set_bufref(&bufref, buf);
r = buf_write_all(buf, forceit);
// Writing may succeed but the buffer still changed, e.g., when there is a
// conversion error. We do want to return FAIL then.
if (bufref_valid(&bufref) && bufIsChanged(buf))
r = FAIL;
return r;
}
/*
* Flush all buffers, except the ones that are readonly or are never written.
*/
void
autowrite_all(void)
{
buf_T *buf;
if (!(p_aw || p_awa) || !p_write)
return;
FOR_ALL_BUFFERS(buf)
if (bufIsChanged(buf) && !buf->b_p_ro && !bt_dontwrite(buf))
{
bufref_T bufref;
set_bufref(&bufref, buf);
(void)buf_write_all(buf, FALSE);
// an autocommand may have deleted the buffer
if (!bufref_valid(&bufref))
buf = firstbuf;
}
}
/*
* Return TRUE if buffer was changed and cannot be abandoned.
* For flags use the CCGD_ values.
*/
int
check_changed(buf_T *buf, int flags)
{
int forceit = (flags & CCGD_FORCEIT);
bufref_T bufref;
set_bufref(&bufref, buf);
if ( !forceit
&& bufIsChanged(buf)
&& ((flags & CCGD_MULTWIN) || buf->b_nwindows <= 1)
&& (!(flags & CCGD_AW) || autowrite(buf, forceit) == FAIL))
{
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && p_write)
{
buf_T *buf2;
int count = 0;
if (flags & CCGD_ALLBUF)
FOR_ALL_BUFFERS(buf2)
if (bufIsChanged(buf2)
&& (buf2->b_ffname != NULL
# ifdef FEAT_BROWSE
|| (cmdmod.cmod_flags & CMOD_BROWSE)
# endif
))
++count;
if (!bufref_valid(&bufref))
// Autocommand deleted buffer, oops! It's not changed now.
return FALSE;
dialog_changed(buf, count > 1);
if (!bufref_valid(&bufref))
// Autocommand deleted buffer, oops! It's not changed now.
return FALSE;
return bufIsChanged(buf);
}
#endif
if (flags & CCGD_EXCMD)
no_write_message();
else
no_write_message_nobang(curbuf);
return TRUE;
}
return FALSE;
}
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
#if defined(FEAT_BROWSE) || defined(PROTO)
/*
* When wanting to write a file without a file name, ask the user for a name.
*/
void
browse_save_fname(buf_T *buf)
{
if (buf->b_fname == NULL)
{
char_u *fname;
fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
NULL, NULL, NULL, NULL, buf);
if (fname != NULL)
{
if (setfname(buf, fname, NULL, TRUE) == OK)
buf->b_flags |= BF_NOTEDITED;
vim_free(fname);
}
}
}
#endif
/*
* Ask the user what to do when abandoning a changed buffer.
* Must check 'write' option first!
*/
void
dialog_changed(
buf_T *buf,
int checkall) // may abandon all changed buffers
{
char_u buff[DIALOG_MSG_SIZE];
int ret;
buf_T *buf2;
exarg_T ea;
dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname);
if (checkall)
ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
else
ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
// Init ea pseudo-structure, this is needed for the check_overwrite()
// function.
CLEAR_FIELD(ea);
if (ret == VIM_YES)
{
#ifdef FEAT_BROWSE
// May get file name, when there is none
browse_save_fname(buf);
#endif
if (buf->b_fname !=