Merge remote-tracking branch 'lenormf/synchronized-write'

This commit is contained in:
Maxime Coste 2018-07-04 19:46:40 +10:00
commit 86616c207d
8 changed files with 54 additions and 29 deletions

View File

@ -12,7 +12,7 @@ define-command lint -docstring 'Parse the current buffer with a linter' %{
%sh{ %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-lint.XXXXXXXX) dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-lint.XXXXXXXX)
mkfifo "$dir"/fifo mkfifo "$dir"/fifo
printf '%s\n' "evaluate-commands -no-hooks write $dir/buf" printf '%s\n' "evaluate-commands -no-hooks write -sync $dir/buf"
printf '%s\n' "evaluate-commands -draft %{ printf '%s\n' "evaluate-commands -draft %{
edit! -fifo $dir/fifo -debug *lint-output* edit! -fifo $dir/fifo -debug *lint-output*

View File

@ -12,7 +12,7 @@ Formats of language supported:
try %{ add-highlighter window ranges 'spell_regions' } try %{ add-highlighter window ranges 'spell_regions' }
%sh{ %sh{
file=$(mktemp -d "${TMPDIR:-/tmp}"/kak-spell.XXXXXXXX)/buffer file=$(mktemp -d "${TMPDIR:-/tmp}"/kak-spell.XXXXXXXX)/buffer
printf 'eval -no-hooks write %s\n' "${file}" printf 'eval -no-hooks write -sync %s\n' "${file}"
printf 'set-option buffer spell_tmp_file %s\n' "${file}" printf 'set-option buffer spell_tmp_file %s\n' "${file}"
} }
%sh{ %sh{

View File

@ -6,7 +6,7 @@ define-command format -docstring "Format the contents of the current buffer" %{
if [ -n "${kak_opt_formatcmd}" ]; then if [ -n "${kak_opt_formatcmd}" ]; then
path_file_tmp=$(mktemp "${TMPDIR:-/tmp}"/kak-formatter-XXXXXX) path_file_tmp=$(mktemp "${TMPDIR:-/tmp}"/kak-formatter-XXXXXX)
printf %s\\n " printf %s\\n "
write \"${path_file_tmp}\" write -sync \"${path_file_tmp}\"
%sh{ %sh{
readonly path_file_out=\$(mktemp \"${TMPDIR:-/tmp}\"/kak-formatter-XXXXXX) readonly path_file_out=\$(mktemp \"${TMPDIR:-/tmp}\"/kak-formatter-XXXXXX)

View File

@ -14,7 +14,7 @@ The syntaxic errors detected during parsing are shown when auto-diagnostics are
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 "set-option buffer clang_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf" printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf"
} }
# end the previous %sh{} so that its output gets interpreted by kakoune # end the previous %sh{} so that its output gets interpreted by kakoune
# before launching the following as a background task. # before launching the following as a background task.

View File

@ -8,7 +8,7 @@ define-command jedi-complete -docstring "Complete the current selection" %{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-jedi.XXXXXXXX) dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-jedi.XXXXXXXX)
mkfifo ${dir}/fifo mkfifo ${dir}/fifo
printf %s\\n "set-option buffer jedi_tmp_dir ${dir}" printf %s\\n "set-option buffer jedi_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf" printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf"
} }
%sh{ %sh{
dir=${kak_opt_jedi_tmp_dir} dir=${kak_opt_jedi_tmp_dir}

View File

@ -326,20 +326,25 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
and (parser.positional_count() == 0 or real_path(parser[0]) == buffer.name())) and (parser.positional_count() == 0 or real_path(parser[0]) == buffer.name()))
throw runtime_error("cannot overwrite the buffer when in readonly mode"); throw runtime_error("cannot overwrite the buffer when in readonly mode");
const bool sync_file = (bool)parser.get_switch("sync");
auto filename = parser.positional_count() == 0 ? auto filename = parser.positional_count() == 0 ?
buffer.name() : parse_filename(parser[0]); buffer.name() : parse_filename(parser[0]);
context.hooks().run_hook("BufWritePre", filename, context); context.hooks().run_hook("BufWritePre", filename, context);
write_buffer_to_file(buffer, filename, force); write_buffer_to_file(buffer, filename, force, sync_file);
context.hooks().run_hook("BufWritePost", filename, context); context.hooks().run_hook("BufWritePost", filename, context);
} }
const CommandDesc write_cmd = { const CommandDesc write_cmd = {
"write", "write",
"w", "w",
"write [filename]: write the current buffer to its file " "write [-sync] [filename]: write the current buffer to its file "
"or to [filename] if specified", "or to [filename] if specified; the underlying file can be"
single_optional_param, "synchronized with the filesystem with the -sync switch",
ParameterDesc{
{ { "sync", { false, "force the synchronization of the file onto the filesystem" } } },
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
},
CommandFlags::None, CommandFlags::None,
CommandHelper{}, CommandHelper{},
filename_completer, filename_completer,
@ -349,16 +354,20 @@ const CommandDesc write_cmd = {
const CommandDesc force_write_cmd = { const CommandDesc force_write_cmd = {
"write!", "write!",
"w!", "w!",
"write [filename]: write the current buffer to its file " "write [-sync] [filename]: write the current buffer to its file "
"or to [filename] if specified, even when the file is write protected", "or to [filename] if specified, even when the file is write protected;"
single_optional_param, "the underlying file can be synchronized with the filesystem with the -sync switch",
ParameterDesc{
{ { "sync", { false, "force the synchronization of the file onto the filesystem" } } },
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
},
CommandFlags::None, CommandFlags::None,
CommandHelper{}, CommandHelper{},
filename_completer, filename_completer,
write_buffer<true>, write_buffer<true>,
}; };
void write_all_buffers(Context& context) void write_all_buffers(Context& context, bool sync = false)
{ {
// 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;
@ -373,7 +382,7 @@ void write_all_buffers(Context& context)
and !(buffer->flags() & Buffer::Flags::ReadOnly)) and !(buffer->flags() & Buffer::Flags::ReadOnly))
{ {
buffer->run_hook_in_own_context("BufWritePre", buffer->name(), context.name()); buffer->run_hook_in_own_context("BufWritePre", buffer->name(), context.name());
write_buffer_to_file(*buffer, buffer->name()); write_buffer_to_file(*buffer, buffer->name(), sync);
buffer->run_hook_in_own_context("BufWritePost", buffer->name(), context.name()); buffer->run_hook_in_own_context("BufWritePost", buffer->name(), context.name());
} }
} }
@ -382,12 +391,18 @@ void write_all_buffers(Context& context)
const CommandDesc write_all_cmd = { const CommandDesc write_all_cmd = {
"write-all", "write-all",
"wa", "wa",
"write all buffers that are associated to a file", "write-all [-sync]: write all buffers that are associated to a file;"
no_params, "all open files can be synchronized with the filesystem with the -sync switch",
ParameterDesc{
{ { "sync", { false, "force the synchronization of the file onto the filesystem" } } },
ParameterDesc::Flags::None, 0, 0
},
CommandFlags::None, CommandFlags::None,
CommandHelper{}, CommandHelper{},
CommandCompleter{}, CommandCompleter{},
[](const ParametersParser&, Context& context, const ShellContext&){ write_all_buffers(context); } [](const ParametersParser& parser, Context& context, const ShellContext&){
write_all_buffers(context, (bool)parser.get_switch("sync"));
}
}; };
static void ensure_all_buffers_are_saved() static void ensure_all_buffers_are_saved()
@ -486,9 +501,12 @@ void write_quit(const ParametersParser& parser, Context& context,
const CommandDesc write_quit_cmd = { const CommandDesc write_quit_cmd = {
"write-quit", "write-quit",
"wq", "wq",
"write current buffer and quit current client. An optional integer " "write-quit [-sync] [exit_code]: write current buffer and quit current client. An optional integer parameter can set the client exit status;"
"parameter can set the client exit status", "all open files can be synchronized with the filesystem with the -sync switch",
{ {}, ParameterDesc::Flags::SwitchesAsPositional, 0, 1 }, ParameterDesc{
{ { "sync", { false, "force the synchronization of the file onto the filesystem" } } },
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
},
CommandFlags::None, CommandFlags::None,
CommandHelper{}, CommandHelper{},
CommandCompleter{}, CommandCompleter{},
@ -510,15 +528,19 @@ const CommandDesc force_write_quit_cmd = {
const CommandDesc write_all_quit_cmd = { const CommandDesc write_all_quit_cmd = {
"write-all-quit", "write-all-quit",
"waq", "waq",
"write all buffers associated to a file and quit current client. An " "write-all-quit [-sync] [exit_code]: write all buffers associated to a file and quit current client."
"optional integer parameter can set the client exit status", "An optional integer parameter can set the client exit status;"
{ {}, ParameterDesc::Flags::SwitchesAsPositional, 0, 1 }, "all open files can be synchronized with the filesystem with the -sync switch",
ParameterDesc{
{ { "sync", { false, "force the synchronization of the file onto the filesystem" } } },
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 0
},
CommandFlags::None, CommandFlags::None,
CommandHelper{}, CommandHelper{},
CommandCompleter{}, CommandCompleter{},
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context) [](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
{ {
write_all_buffers(context); write_all_buffers(context, (bool)parser.get_switch("sync"));
quit<false>(parser, context, shell_context); quit<false>(parser, context, shell_context);
} }
}; };

View File

@ -257,7 +257,7 @@ void write(int fd, StringView data)
} }
} }
void write_buffer_to_fd(Buffer& buffer, int fd) void write_buffer_to_fd(Buffer& buffer, int fd, bool sync)
{ {
auto eolformat = buffer.options()["eolformat"].get<EolFormat>(); auto eolformat = buffer.options()["eolformat"].get<EolFormat>();
StringView eoldata; StringView eoldata;
@ -278,9 +278,12 @@ void write_buffer_to_fd(Buffer& buffer, int fd)
write(fd, linedata.substr(0, linedata.length()-1)); write(fd, linedata.substr(0, linedata.length()-1));
write(fd, eoldata); write(fd, eoldata);
} }
if (sync)
::fsync(fd);
} }
void write_buffer_to_file(Buffer& buffer, StringView filename, bool force) void write_buffer_to_file(Buffer& buffer, StringView filename, bool force, bool sync)
{ {
struct stat st; struct stat st;
auto zfilename = filename.zstr(); auto zfilename = filename.zstr();
@ -306,7 +309,7 @@ void write_buffer_to_file(Buffer& buffer, StringView filename, bool force)
{ {
auto close_fd = on_scope_end([fd]{ close(fd); }); auto close_fd = on_scope_end([fd]{ close(fd); });
write_buffer_to_fd(buffer, fd); write_buffer_to_fd(buffer, fd, sync);
} }
if ((buffer.flags() & Buffer::Flags::File) and if ((buffer.flags() & Buffer::Flags::File) and

View File

@ -51,8 +51,8 @@ struct MappedFile
struct stat st {}; struct stat st {};
}; };
void write_buffer_to_file(Buffer& buffer, StringView filename, bool force = false); void write_buffer_to_file(Buffer& buffer, StringView filename, bool force = false, bool sync = false);
void write_buffer_to_fd(Buffer& buffer, int fd); void write_buffer_to_fd(Buffer& buffer, int fd, bool sync = false);
void write_buffer_to_backup_file(Buffer& buffer); void write_buffer_to_backup_file(Buffer& buffer);
String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths); String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths);