Prevent overwriting existing file in :write <explicit filename>
Add a -force (equivalent to w!) switch that enables overwriting.
This commit is contained in:
parent
4d99434ddd
commit
40e3614cf4
|
@ -58,13 +58,17 @@ of the file onto the filesystem
|
|||
Otherwise, does nothing.
|
||||
|
||||
|
||||
*write[!]* [-sync] [-method <writemethod>] [<filename>]::
|
||||
*write[!]* [-force] [-sync] [-method <writemethod>] [<filename>]::
|
||||
*alias* w +
|
||||
write buffer to <filename> or use its name if filename is not
|
||||
given. If the file is write-protected, its permissions are temporarily
|
||||
changed to allow saving the buffer and restored afterwards when
|
||||
the write! command is used.
|
||||
|
||||
*-force*:::
|
||||
Equivalent to `!`, allow overwiting existing files if `<filename>`
|
||||
is given and set permissions temporarily if necessary.
|
||||
|
||||
*-sync*:::
|
||||
Synchronise the filesystem after the write
|
||||
|
||||
|
|
|
@ -460,6 +460,7 @@ const ParameterDesc write_params{
|
|||
{
|
||||
{ "sync", { false, "force the synchronization of the file onto the filesystem" } },
|
||||
{ "method", { true, "explicit writemethod (replace|overwrite)" } },
|
||||
{ "force", { false, "Allow overwriting existing file with explicit filename" } },
|
||||
},
|
||||
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
|
||||
};
|
||||
|
@ -488,7 +489,12 @@ void do_write_buffer(Context& context, Optional<String> filename, WriteFlags fla
|
|||
(not filename or real_path(*filename) == buffer.name()))
|
||||
throw runtime_error("cannot overwrite the buffer when in readonly mode");
|
||||
|
||||
auto effective_filename = not filename ? buffer.name() : parse_filename(*filename);
|
||||
auto effective_filename = filename ? parse_filename(*filename) : buffer.name();
|
||||
if (filename and not (flags & WriteFlags::Force) and
|
||||
real_path(effective_filename) != buffer.name() and
|
||||
regular_file_exists(effective_filename))
|
||||
throw runtime_error("cannot overwrite existing file without -force");
|
||||
|
||||
auto method = write_method.value_or_compute([&] { return context.options()["writemethod"].get<WriteMethod>(); });
|
||||
|
||||
context.hooks().run_hook(Hook::BufWritePre, effective_filename, context);
|
||||
|
@ -502,7 +508,7 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
|
|||
return do_write_buffer(context,
|
||||
parser.positional_count() > 0 ? parser[0] : Optional<String>{},
|
||||
(parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None) |
|
||||
(force ? WriteFlags::Force : WriteFlags::None),
|
||||
(parser.get_switch("force") or force ? WriteFlags::Force : WriteFlags::None),
|
||||
parser.get_switch("method").map(parse_write_method));
|
||||
}
|
||||
|
||||
|
|
|
@ -247,6 +247,13 @@ bool file_exists(StringView filename)
|
|||
return stat(filename.zstr(), &st) == 0;
|
||||
}
|
||||
|
||||
bool regular_file_exists(StringView filename)
|
||||
{
|
||||
struct stat st;
|
||||
return stat(filename.zstr(), &st) == 0 and
|
||||
(st.st_mode & S_IFMT) == S_IFREG;
|
||||
}
|
||||
|
||||
void write(int fd, StringView data)
|
||||
{
|
||||
const char* ptr = data.data();
|
||||
|
|
|
@ -81,6 +81,7 @@ void write_buffer_to_backup_file(Buffer& buffer);
|
|||
|
||||
String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths);
|
||||
bool file_exists(StringView filename);
|
||||
bool regular_file_exists(StringView filename);
|
||||
|
||||
Vector<String> list_files(StringView directory);
|
||||
|
||||
|
|
6
test/run
6
test/run
|
@ -16,7 +16,7 @@ main() {
|
|||
try %{ source rc }
|
||||
hook global RuntimeError .+ %{
|
||||
echo -debug -- error: %val{hook_param}
|
||||
eval -buffer *debug* write debug
|
||||
eval -buffer *debug* write -force debug
|
||||
quit!
|
||||
}
|
||||
try %{ exec -with-maps -with-hooks "%sh{cat cmd}" }
|
||||
|
@ -151,14 +151,14 @@ show_diff() {
|
|||
|
||||
finished_commands() {
|
||||
printf %s 'eval -client client0 %{
|
||||
eval -buffer *debug* write debug
|
||||
eval -buffer *debug* write -force debug
|
||||
nop %sh{
|
||||
'
|
||||
for env_var in $env_vars; do
|
||||
printf 'printf %%s\\\\n "$%s" >%s\n' "$env_var" "$env_var"
|
||||
done
|
||||
printf %s ' }
|
||||
write out
|
||||
write -force out
|
||||
quit!
|
||||
}
|
||||
'
|
||||
|
|
Loading…
Reference in New Issue
Block a user