mirror of
https://github.com/neovim/neovim.git
synced 2025-10-13 05:16:09 +00:00
feat: ":wall ++p" creates parent dirs for each buf #36121
`:wall ++p` will create parent directories if they do not exist, for each modified buffer
This commit is contained in:
@@ -996,11 +996,13 @@ slower (but safer).
|
|||||||
WRITING WITH MULTIPLE BUFFERS *buffer-write*
|
WRITING WITH MULTIPLE BUFFERS *buffer-write*
|
||||||
|
|
||||||
*:wa* *:wall*
|
*:wa* *:wall*
|
||||||
:wa[ll] Write all changed buffers. Buffers without a file
|
:wa[ll] [++opt] Write all changed buffers. Buffers without a file
|
||||||
name cause an error message. Buffers which are
|
name cause an error message. Buffers which are
|
||||||
readonly are not written.
|
readonly are not written.
|
||||||
|
For ++opt see |++opt|, but only ++p is effective, and
|
||||||
|
applies to each written file.
|
||||||
|
|
||||||
:wa[ll]! Write all changed buffers, even the ones that are
|
:wa[ll]! [++opt] Write all changed buffers, even the ones that are
|
||||||
readonly. Buffers without a file name are not
|
readonly. Buffers without a file name are not
|
||||||
written and cause an error message.
|
written and cause an error message.
|
||||||
|
|
||||||
|
@@ -197,6 +197,8 @@ EDITOR
|
|||||||
• |gx| in help buffers opens the online documentation for the tag under the
|
• |gx| in help buffers opens the online documentation for the tag under the
|
||||||
cursor.
|
cursor.
|
||||||
• |:Undotree| for visually navigating the |undo-tree|
|
• |:Undotree| for visually navigating the |undo-tree|
|
||||||
|
• |:wall| permits a |++p| option for creating parent directories when writing
|
||||||
|
changed buffers.
|
||||||
|
|
||||||
EVENTS
|
EVENTS
|
||||||
|
|
||||||
|
@@ -1806,6 +1806,15 @@ static int check_writable(const char *fname)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int handle_mkdir_p_arg(exarg_T *eap, char *fname)
|
||||||
|
{
|
||||||
|
if (eap->mkdir_p && os_file_mkdir(fname, 0755) < 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/// Write current buffer to file "eap->arg".
|
/// Write current buffer to file "eap->arg".
|
||||||
/// If "eap->append" is true, append to the file.
|
/// If "eap->append" is true, append to the file.
|
||||||
///
|
///
|
||||||
@@ -1943,11 +1952,9 @@ int do_write(exarg_T *eap)
|
|||||||
fname = curbuf->b_sfname;
|
fname = curbuf->b_sfname;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap->mkdir_p) {
|
if (handle_mkdir_p_arg(eap, fname) == FAIL) {
|
||||||
if (os_file_mkdir(fname, 0755) < 0) {
|
retval = FAIL;
|
||||||
retval = FAIL;
|
goto theend;
|
||||||
goto theend;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int name_was_missing = curbuf->b_ffname == NULL;
|
int name_was_missing = curbuf->b_ffname == NULL;
|
||||||
@@ -2123,7 +2130,8 @@ void do_wqall(exarg_T *eap)
|
|||||||
} else {
|
} else {
|
||||||
bufref_T bufref;
|
bufref_T bufref;
|
||||||
set_bufref(&bufref, buf);
|
set_bufref(&bufref, buf);
|
||||||
if (buf_write_all(buf, eap->forceit) == FAIL) {
|
if (handle_mkdir_p_arg(eap, buf->b_fname) == FAIL
|
||||||
|
|| buf_write_all(buf, eap->forceit) == FAIL) {
|
||||||
error++;
|
error++;
|
||||||
}
|
}
|
||||||
// An autocommand may have deleted the buffer.
|
// An autocommand may have deleted the buffer.
|
||||||
|
@@ -3187,7 +3187,7 @@ M.cmds = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
command = 'wall',
|
command = 'wall',
|
||||||
flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK),
|
flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK, ARGOPT),
|
||||||
addr_type = 'ADDR_NONE',
|
addr_type = 'ADDR_NONE',
|
||||||
func = 'do_wqall',
|
func = 'do_wqall',
|
||||||
},
|
},
|
||||||
|
@@ -23,6 +23,9 @@ describe(':write', function()
|
|||||||
os.remove('test_fifo')
|
os.remove('test_fifo')
|
||||||
os.remove('test/write/p_opt.txt')
|
os.remove('test/write/p_opt.txt')
|
||||||
os.remove('test/write')
|
os.remove('test/write')
|
||||||
|
os.remove('test/write2/p_opt.txt')
|
||||||
|
os.remove('test/write2/p_opt2.txt')
|
||||||
|
os.remove('test/write2')
|
||||||
os.remove('test')
|
os.remove('test')
|
||||||
os.remove(fname)
|
os.remove(fname)
|
||||||
os.remove(fname_bak)
|
os.remove(fname_bak)
|
||||||
@@ -111,6 +114,21 @@ describe(':write', function()
|
|||||||
command('write ++p test/write/p_opt.txt')
|
command('write ++p test/write/p_opt.txt')
|
||||||
eq(1, eval("filereadable('test/write/p_opt.txt')"))
|
eq(1, eval("filereadable('test/write/p_opt.txt')"))
|
||||||
|
|
||||||
|
eq(0, eval("filereadable('test/write2/p_opt.txt')"))
|
||||||
|
eq(0, eval("filereadable('test/write2/p_opt2.txt')"))
|
||||||
|
eq(0, eval("filereadable('test/write3/p_opt3.txt')"))
|
||||||
|
command('file test/write2/p_opt.txt')
|
||||||
|
command('set modified')
|
||||||
|
command('sp test/write2/p_opt2.txt')
|
||||||
|
command('set modified')
|
||||||
|
command('sp test/write3/p_opt3.txt')
|
||||||
|
-- don't set p_opt3.txt modified - assert it isn't written
|
||||||
|
-- and that write3/ isn't created
|
||||||
|
command('wall ++p')
|
||||||
|
eq(1, eval("filereadable('test/write2/p_opt.txt')"))
|
||||||
|
eq(1, eval("filereadable('test/write2/p_opt2.txt')"))
|
||||||
|
eq(0, eval("filereadable('test/write3/p_opt3.txt')"))
|
||||||
|
|
||||||
eq('Vim(write):E32: No file name', pcall_err(command, 'write ++p test_write/'))
|
eq('Vim(write):E32: No file name', pcall_err(command, 'write ++p test_write/'))
|
||||||
if not is_os('win') then
|
if not is_os('win') then
|
||||||
eq(
|
eq(
|
||||||
|
Reference in New Issue
Block a user