Replace write -atomic
with write -method <method>
`-atomic` becomes `-method replace` and `-method overwrite` is now supported explicitely instead of only available through the writemethod option. Fixes #3827
This commit is contained in:
parent
9a5cf2fc9f
commit
90043e7df0
|
@ -10,6 +10,9 @@ released versions.
|
||||||
* Menu completions such as command name completion are now auto-inserted on
|
* Menu completions such as command name completion are now auto-inserted on
|
||||||
space
|
space
|
||||||
|
|
||||||
|
* `write -atomic` was replaced with `write -method [replace|overwrite]` to
|
||||||
|
make both write method available explicitely
|
||||||
|
|
||||||
== Kakoune 2020.09.01
|
== Kakoune 2020.09.01
|
||||||
|
|
||||||
* The `repl` and `send-text` aliases have been renamed respectively into
|
* The `repl` and `send-text` aliases have been renamed respectively into
|
||||||
|
|
|
@ -58,7 +58,7 @@ of the file onto the filesystem
|
||||||
Otherwise, does nothing.
|
Otherwise, does nothing.
|
||||||
|
|
||||||
|
|
||||||
*write[!]* [-sync] [-atomic] [<filename>]::
|
*write[!]* [-sync] [-method <writemethod>] [<filename>]::
|
||||||
*alias* w +
|
*alias* w +
|
||||||
write buffer to <filename> or use its name if filename is not
|
write buffer to <filename> or use its name if filename is not
|
||||||
given. If the file is write-protected, its permissions are temporarily
|
given. If the file is write-protected, its permissions are temporarily
|
||||||
|
@ -68,11 +68,20 @@ of the file onto the filesystem
|
||||||
*-sync*:::
|
*-sync*:::
|
||||||
Synchronise the filesystem after the write
|
Synchronise the filesystem after the write
|
||||||
|
|
||||||
*-atomic*:::
|
*-method <writemethod>*:::
|
||||||
Force writing to a temporary file then renaming to the target file
|
Enforce write method instead of relying on the `writemethod` option
|
||||||
so that the modification appears atomically.
|
|
||||||
|
|
||||||
*write-all* [-sync]::
|
`replace`::::
|
||||||
|
Write to a temporary file then rename to the target file so that
|
||||||
|
the modification appears atomically.
|
||||||
|
|
||||||
|
`overwrite`::::
|
||||||
|
Open the existing file and overwrite its content with the new
|
||||||
|
content.
|
||||||
|
|
||||||
|
(See <<options#builtin-options,`:doc options builtin-options`>>)
|
||||||
|
|
||||||
|
*write-all* [-sync] [-method <writemethod>]::
|
||||||
*alias* wa +
|
*alias* wa +
|
||||||
write all changed buffers that are associated with a file
|
write all changed buffers that are associated with a file
|
||||||
|
|
||||||
|
@ -82,12 +91,12 @@ of the file onto the filesystem
|
||||||
unsaved buffer remaining. If specified, the client exit status
|
unsaved buffer remaining. If specified, the client exit status
|
||||||
will be set to <exit status>
|
will be set to <exit status>
|
||||||
|
|
||||||
*write-quit[!]* [-sync] [<exit status>]::
|
*write-quit[!]* [-sync] [-method <writemethod>] [<exit status>]::
|
||||||
*alias* wq +
|
*alias* wq +
|
||||||
write current buffer and quit current client. If specified, the client
|
write current buffer and quit current client. If specified, the client
|
||||||
exit status will be set to <exit status>
|
exit status will be set to <exit status>
|
||||||
|
|
||||||
*write-all-quit* [-sync] [<exit status>]::
|
*write-all-quit* [-sync] [-method <writemethod>] [<exit status>]::
|
||||||
*alias* waq +
|
*alias* waq +
|
||||||
write all buffers and quit. If specified, the client exit status
|
write all buffers and quit. If specified, the client exit status
|
||||||
will be set to <exit status>
|
will be set to <exit status>
|
||||||
|
|
|
@ -23,7 +23,7 @@ define-command -params ..1 \
|
||||||
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-clang.XXXXXXXX)
|
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-clang.XXXXXXXX)
|
||||||
mkfifo ${dir}/fifo
|
mkfifo ${dir}/fifo
|
||||||
printf %s\\n "
|
printf %s\\n "
|
||||||
evaluate-commands -no-hooks write -sync -atomic ${dir}/buf
|
evaluate-commands -no-hooks write -sync -method replace ${dir}/buf
|
||||||
evaluate-commands -draft %{
|
evaluate-commands -draft %{
|
||||||
edit! -fifo ${dir}/fifo -debug *clang-output*
|
edit! -fifo ${dir}/fifo -debug *clang-output*
|
||||||
set-option buffer filetype make
|
set-option buffer filetype make
|
||||||
|
|
|
@ -456,12 +456,21 @@ const CommandDesc force_edit_cmd = {
|
||||||
const ParameterDesc write_params{
|
const ParameterDesc write_params{
|
||||||
{
|
{
|
||||||
{ "sync", { false, "force the synchronization of the file onto the filesystem" } },
|
{ "sync", { false, "force the synchronization of the file onto the filesystem" } },
|
||||||
{ "atomic", { false, "force the writemethod to replace" } },
|
{ "method", { true, "explicite writemethod (replace|overwrite)" } },
|
||||||
},
|
},
|
||||||
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
|
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
void do_write_buffer(Context& context, Optional<String> filename, WriteFlags flags, bool atomic = false)
|
auto parse_write_method(StringView str)
|
||||||
|
{
|
||||||
|
constexpr auto desc = enum_desc(Meta::Type<WriteMethod>{});
|
||||||
|
auto it = find_if(desc, [str](const EnumDesc<WriteMethod>& d) { return d.name == str; });
|
||||||
|
if (it == desc.end())
|
||||||
|
throw runtime_error(format("invalid writemethod '{}'", str));
|
||||||
|
return it->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_write_buffer(Context& context, Optional<String> filename, WriteFlags flags, Optional<WriteMethod> write_method = {})
|
||||||
{
|
{
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
const bool is_file = (bool)(buffer.flags() & Buffer::Flags::File);
|
const bool is_file = (bool)(buffer.flags() & Buffer::Flags::File);
|
||||||
|
@ -477,10 +486,10 @@ void do_write_buffer(Context& context, Optional<String> filename, WriteFlags fla
|
||||||
throw runtime_error("cannot overwrite the buffer when in readonly mode");
|
throw runtime_error("cannot overwrite the buffer when in readonly mode");
|
||||||
|
|
||||||
auto effective_filename = not filename ? buffer.name() : parse_filename(*filename);
|
auto effective_filename = not filename ? buffer.name() : parse_filename(*filename);
|
||||||
auto mode = atomic ? WriteMethod::Replace : context.options()["writemethod"].get<WriteMethod>();
|
auto method = write_method.value_or_compute([&] { return context.options()["writemethod"].get<WriteMethod>(); });
|
||||||
|
|
||||||
context.hooks().run_hook(Hook::BufWritePre, effective_filename, context);
|
context.hooks().run_hook(Hook::BufWritePre, effective_filename, context);
|
||||||
write_buffer_to_file(buffer, effective_filename, mode, flags);
|
write_buffer_to_file(buffer, effective_filename, method, flags);
|
||||||
context.hooks().run_hook(Hook::BufWritePost, effective_filename, context);
|
context.hooks().run_hook(Hook::BufWritePost, effective_filename, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +500,7 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
|
||||||
parser.positional_count() > 0 ? parser[0] : Optional<String>{},
|
parser.positional_count() > 0 ? parser[0] : Optional<String>{},
|
||||||
(parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None) |
|
(parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None) |
|
||||||
(force ? WriteFlags::Force : WriteFlags::None),
|
(force ? WriteFlags::Force : WriteFlags::None),
|
||||||
(bool)parser.get_switch("atomic"));
|
parser.get_switch("method").map(parse_write_method));
|
||||||
}
|
}
|
||||||
|
|
||||||
const CommandDesc write_cmd = {
|
const CommandDesc write_cmd = {
|
||||||
|
@ -518,7 +527,7 @@ const CommandDesc force_write_cmd = {
|
||||||
write_buffer<true>,
|
write_buffer<true>,
|
||||||
};
|
};
|
||||||
|
|
||||||
void write_all_buffers(const Context& context, bool sync = false, bool atomic = false)
|
void write_all_buffers(const Context& context, bool sync = false, Optional<WriteMethod> write_method = {})
|
||||||
{
|
{
|
||||||
// Copy buffer list because hooks might be creating/deleting buffers
|
// Copy buffer list because hooks might be creating/deleting buffers
|
||||||
Vector<SafePtr<Buffer>> buffers;
|
Vector<SafePtr<Buffer>> buffers;
|
||||||
|
@ -532,10 +541,10 @@ void write_all_buffers(const Context& context, bool sync = false, bool atomic =
|
||||||
buffer->is_modified())
|
buffer->is_modified())
|
||||||
and !(buffer->flags() & Buffer::Flags::ReadOnly))
|
and !(buffer->flags() & Buffer::Flags::ReadOnly))
|
||||||
{
|
{
|
||||||
auto mode = atomic ? WriteMethod::Replace : context.options()["writemethod"].get<WriteMethod>();
|
auto method = write_method.value_or_compute([&] { return context.options()["writemethod"].get<WriteMethod>(); });
|
||||||
auto flags = sync ? WriteFlags::Sync : WriteFlags::None;
|
auto flags = sync ? WriteFlags::Sync : WriteFlags::None;
|
||||||
buffer->run_hook_in_own_context(Hook::BufWritePre, buffer->name(), context.name());
|
buffer->run_hook_in_own_context(Hook::BufWritePre, buffer->name(), context.name());
|
||||||
write_buffer_to_file(*buffer, buffer->name(), mode, flags);
|
write_buffer_to_file(*buffer, buffer->name(), method, flags);
|
||||||
buffer->run_hook_in_own_context(Hook::BufWritePost, buffer->name(), context.name());
|
buffer->run_hook_in_own_context(Hook::BufWritePost, buffer->name(), context.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,7 +563,8 @@ const CommandDesc write_all_cmd = {
|
||||||
CommandCompleter{},
|
CommandCompleter{},
|
||||||
[](const ParametersParser& parser, Context& context, const ShellContext&){
|
[](const ParametersParser& parser, Context& context, const ShellContext&){
|
||||||
write_all_buffers(context,
|
write_all_buffers(context,
|
||||||
(bool)parser.get_switch("sync"), (bool)parser.get_switch("atomic"));
|
(bool)parser.get_switch("sync"),
|
||||||
|
parser.get_switch("method").map(parse_write_method));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -661,7 +671,9 @@ template<bool force>
|
||||||
void write_quit(const ParametersParser& parser, Context& context,
|
void write_quit(const ParametersParser& parser, Context& context,
|
||||||
const ShellContext& shell_context)
|
const ShellContext& shell_context)
|
||||||
{
|
{
|
||||||
do_write_buffer(context, {}, parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None);
|
do_write_buffer(context, {},
|
||||||
|
parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None,
|
||||||
|
parser.get_switch("method").map(parse_write_method));
|
||||||
quit<force>(parser, context, shell_context);
|
quit<force>(parser, context, shell_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,7 +712,9 @@ const CommandDesc write_all_quit_cmd = {
|
||||||
CommandCompleter{},
|
CommandCompleter{},
|
||||||
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
|
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
|
||||||
{
|
{
|
||||||
write_all_buffers(context, (bool)parser.get_switch("sync"));
|
write_all_buffers(context,
|
||||||
|
(bool)parser.get_switch("sync"),
|
||||||
|
parser.get_switch("method").map(parse_write_method));
|
||||||
quit<false>(parser, context, shell_context);
|
quit<false>(parser, context, shell_context);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct {
|
||||||
"» {+u}set-option -remove{} support\n"
|
"» {+u}set-option -remove{} support\n"
|
||||||
"» prompts auto select {+i}menu{} completions on space\n"
|
"» prompts auto select {+i}menu{} completions on space\n"
|
||||||
"» explicit completion support ({+b}<c-x>...{}) in prompts\n"
|
"» explicit completion support ({+b}<c-x>...{}) in prompts\n"
|
||||||
|
"» {+u}write -atomic{} was replaced with {+u}write -method <method>{}\n"
|
||||||
}, {
|
}, {
|
||||||
20200901,
|
20200901,
|
||||||
"» daemon mode does not fork anymore\n"
|
"» daemon mode does not fork anymore\n"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user