diff --git a/doc/pages/commands.asciidoc b/doc/pages/commands.asciidoc index be1403e5..f9e239e4 100644 --- a/doc/pages/commands.asciidoc +++ b/doc/pages/commands.asciidoc @@ -52,13 +52,20 @@ of the file onto the filesystem Otherwise, does nothing. -*write[!]* [-sync] []:: +*write[!]* [-sync] [-atomic] []:: *alias* w + write buffer to 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. + *-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]:: *alias* wa + write all changed buffers that are associated to a file diff --git a/rc/tools/clang.kak b/rc/tools/clang.kak index 37f9e7ff..f5622ddf 100644 --- a/rc/tools/clang.kak +++ b/rc/tools/clang.kak @@ -10,7 +10,6 @@ declare-option -docstring "options to pass to the `clang` shell command" \ declare-option -docstring "directory from which to invoke clang" \ str clang_directory -declare-option -hidden str clang_tmp_dir declare-option -hidden completions clang_completions declare-option -hidden line-specs clang_flags 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{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-clang.XXXXXXXX) mkfifo ${dir}/fifo - printf %s\\n "set-option buffer clang_tmp_dir ${dir}" - printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf" - } - # 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* - set-option buffer filetype make - set-option buffer make_current_error_line 0 - hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } } - }" + printf %s\\n " + evaluate-commands -no-hooks write -sync -atomic ${dir}/buf + evaluate-commands -draft %{ + edit! -fifo ${dir}/fifo -debug *clang-output* + set-option buffer filetype make + set-option buffer make_current_error_line 0 + hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } } + }" + # this runs in a detached shell, asynchronously, so that kakoune does # not hang while clang is running. As completions references a cursor # position and a buffer timestamp, only valid completions should be # displayed. (( + until [ -f ${dir}/buf ]; do :; done # wait for the buffer to be written + if [ -n "$kak_opt_clang_directory" ]; then cd "$kak_opt_clang_directory" fi diff --git a/src/commands.cc b/src/commands.cc index 27531aec..dd105c69 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -461,11 +461,14 @@ const CommandDesc force_edit_cmd = { }; 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 }; -void do_write_buffer(Context& context, Optional filename, WriteFlags flags) +void do_write_buffer(Context& context, Optional filename, WriteFlags flags, bool atomic = false) { Buffer& buffer = context.buffer(); @@ -479,7 +482,7 @@ void do_write_buffer(Context& context, Optional filename, WriteFlags fla throw runtime_error("cannot overwrite the buffer when in readonly mode"); auto effective_filename = not filename ? buffer.name() : parse_filename(*filename); - auto mode = context.options()["writemethod"].get(); + auto mode = atomic ? WriteMethod::Replace : context.options()["writemethod"].get(); context.hooks().run_hook(Hook::BufWritePre, effective_filename, context); 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, parser.positional_count() > 0 ? parser[0] : Optional{}, (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 = {