Add a -atomic switch to write and change clang.kak to take advantage

This commit is contained in:
Maxime Coste 2019-11-21 23:36:38 +11:00
parent 4d7ea276c4
commit 82e5346904
3 changed files with 27 additions and 19 deletions

View File

@ -52,13 +52,20 @@ of the file onto the filesystem
Otherwise, does nothing. Otherwise, does nothing.
*write[!]* [-sync] [<filename>]:: *write[!]* [-sync] [-atomic] [<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
changed to allow saving the buffer and restored afterwards when changed to allow saving the buffer and restored afterwards when
the write! command is used. the write! command is used.
*-sync*:::
Synchronise the filesystem after the write
*-stomic*:::
Force writing to a temoprary file then renaming to the target file
so that the modification appears automatically.
*write-all* [-sync]:: *write-all* [-sync]::
*alias* wa + *alias* wa +
write all changed buffers that are associated to a file write all changed buffers that are associated to a file

View File

@ -10,7 +10,6 @@ declare-option -docstring "options to pass to the `clang` shell command" \
declare-option -docstring "directory from which to invoke clang" \ declare-option -docstring "directory from which to invoke clang" \
str clang_directory str clang_directory
declare-option -hidden str clang_tmp_dir
declare-option -hidden completions clang_completions declare-option -hidden completions clang_completions
declare-option -hidden line-specs clang_flags declare-option -hidden line-specs clang_flags
declare-option -hidden line-specs clang_errors declare-option -hidden line-specs clang_errors
@ -22,24 +21,22 @@ The syntaxic errors detected during parsing are shown when auto-diagnostics are
evaluate-commands %sh{ evaluate-commands %sh{
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 "set-option buffer clang_tmp_dir ${dir}" printf %s\\n "
printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf" evaluate-commands -no-hooks write -sync -atomic ${dir}/buf
} evaluate-commands -draft %{
# end the previous %sh{} so that its output gets interpreted by kakoune
# before launching the following as a background task.
evaluate-commands %sh{
dir=${kak_opt_clang_tmp_dir}
printf %s\\n "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
set-option buffer make_current_error_line 0 set-option buffer make_current_error_line 0
hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } } hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } }
}" }"
# this runs in a detached shell, asynchronously, so that kakoune does # this runs in a detached shell, asynchronously, so that kakoune does
# not hang while clang is running. As completions references a cursor # not hang while clang is running. As completions references a cursor
# position and a buffer timestamp, only valid completions should be # position and a buffer timestamp, only valid completions should be
# displayed. # displayed.
(( ((
until [ -f ${dir}/buf ]; do :; done # wait for the buffer to be written
if [ -n "$kak_opt_clang_directory" ]; then if [ -n "$kak_opt_clang_directory" ]; then
cd "$kak_opt_clang_directory" cd "$kak_opt_clang_directory"
fi fi

View File

@ -461,11 +461,14 @@ 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" } },
},
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1 ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
}; };
void do_write_buffer(Context& context, Optional<String> filename, WriteFlags flags) void do_write_buffer(Context& context, Optional<String> filename, WriteFlags flags, bool atomic = false)
{ {
Buffer& buffer = context.buffer(); Buffer& buffer = context.buffer();
@ -479,7 +482,7 @@ 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 = context.options()["writemethod"].get<WriteMethod>(); auto mode = atomic ? WriteMethod::Replace : 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, mode, flags);
@ -492,7 +495,8 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
return do_write_buffer(context, return do_write_buffer(context,
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"));
} }
const CommandDesc write_cmd = { const CommandDesc write_cmd = {