Merge remote-tracking branch 'lenormf/command-force-write'
This commit is contained in:
commit
ab3a255d58
|
@ -676,8 +676,10 @@ command `q!` has to be used).
|
||||||
* `e[dit][!] <filename> [<line> [<column>]]`: open buffer on file, go to given
|
* `e[dit][!] <filename> [<line> [<column>]]`: open buffer on file, go to given
|
||||||
line and column. If file is already opened, just switch to this file.
|
line and column. If file is already opened, just switch to this file.
|
||||||
use edit! to force reloading.
|
use edit! to force reloading.
|
||||||
* `w[rite] [<filename>]`: write buffer to <filename> or use it's name if
|
* `w[rite][!] [<filename>]`: write buffer to <filename> or use it's name if
|
||||||
filename is not given.
|
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.
|
||||||
* `w[rite]a[ll]`: write all buffers that are associated to a file.
|
* `w[rite]a[ll]`: write all buffers that are associated to a file.
|
||||||
* `q[uit][!]`: exit Kakoune, use quit! to force quitting even if there is some
|
* `q[uit][!]`: exit Kakoune, use quit! to force quitting even if there is some
|
||||||
unsaved buffers remaining.
|
unsaved buffers remaining.
|
||||||
|
|
|
@ -24,8 +24,11 @@ command *q!* has to be used).
|
||||||
open buffer on file, go to given line and column. If file is already
|
open buffer on file, go to given line and column. If file is already
|
||||||
opened, just switch to this file. Use edit! to force reloading
|
opened, just switch to this file. Use edit! to force reloading
|
||||||
|
|
||||||
*w[rite]* [<filename>]::
|
*w[rite][!]* [<filename>]::
|
||||||
write buffer to <filename> or use it's name if filename is not given
|
write buffer to <filename> or use it's 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.
|
||||||
|
|
||||||
*w[rite]a[ll]*::
|
*w[rite]a[ll]*::
|
||||||
write all buffers that are associated to a file
|
write all buffers that are associated to a file
|
||||||
|
|
|
@ -309,6 +309,7 @@ const CommandDesc force_edit_cmd = {
|
||||||
edit<true>
|
edit<true>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<bool force = false>
|
||||||
void write_buffer(const ParametersParser& parser, Context& context, const ShellContext&)
|
void write_buffer(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||||
{
|
{
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
|
@ -326,7 +327,7 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
|
||||||
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);
|
write_buffer_to_file(buffer, filename, force);
|
||||||
context.hooks().run_hook("BufWritePost", filename, context);
|
context.hooks().run_hook("BufWritePost", filename, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +343,18 @@ const CommandDesc write_cmd = {
|
||||||
write_buffer,
|
write_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CommandDesc force_write_cmd = {
|
||||||
|
"write!",
|
||||||
|
"w!",
|
||||||
|
"write [filename]: write the current buffer to its file "
|
||||||
|
"or to [filename] if specified, even when the file is write protected",
|
||||||
|
single_optional_param,
|
||||||
|
CommandFlags::None,
|
||||||
|
CommandHelper{},
|
||||||
|
filename_completer,
|
||||||
|
write_buffer<true>,
|
||||||
|
};
|
||||||
|
|
||||||
void write_all_buffers(Context& context)
|
void write_all_buffers(Context& context)
|
||||||
{
|
{
|
||||||
// Copy buffer list because hooks might be creating/deleting buffers
|
// Copy buffer list because hooks might be creating/deleting buffers
|
||||||
|
@ -2102,6 +2115,7 @@ void register_commands()
|
||||||
register_command(edit_cmd);
|
register_command(edit_cmd);
|
||||||
register_command(force_edit_cmd);
|
register_command(force_edit_cmd);
|
||||||
register_command(write_cmd);
|
register_command(write_cmd);
|
||||||
|
register_command(force_write_cmd);
|
||||||
register_command(write_all_cmd);
|
register_command(write_all_cmd);
|
||||||
register_command(write_all_quit_cmd);
|
register_command(write_all_quit_cmd);
|
||||||
register_command(kill_cmd);
|
register_command(kill_cmd);
|
||||||
|
|
22
src/file.cc
22
src/file.cc
|
@ -278,9 +278,27 @@ void write_buffer_to_fd(Buffer& buffer, int fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_buffer_to_file(Buffer& buffer, StringView filename)
|
void write_buffer_to_file(Buffer& buffer, StringView filename, bool force)
|
||||||
{
|
{
|
||||||
int fd = open(filename.zstr(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
struct stat st;
|
||||||
|
auto zfilename = filename.zstr();
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
{
|
||||||
|
if (::stat(zfilename, &st) == 0)
|
||||||
|
{
|
||||||
|
if (::chmod(zfilename, st.st_mode | S_IWUSR) < 0)
|
||||||
|
throw runtime_error("couldn't change file permissions");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
force = false;
|
||||||
|
}
|
||||||
|
auto restore_mode = on_scope_end([&]{
|
||||||
|
if (force and ::chmod(zfilename, st.st_mode) < 0)
|
||||||
|
throw runtime_error("couldn't restore file permissions");
|
||||||
|
});
|
||||||
|
|
||||||
|
int fd = open(zfilename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
throw file_access_error(filename, strerror(errno));
|
throw file_access_error(filename, strerror(errno));
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct MappedFile
|
||||||
struct stat st {};
|
struct stat st {};
|
||||||
};
|
};
|
||||||
|
|
||||||
void write_buffer_to_file(Buffer& buffer, StringView filename);
|
void write_buffer_to_file(Buffer& buffer, StringView filename, bool force = false);
|
||||||
void write_buffer_to_fd(Buffer& buffer, int fd);
|
void write_buffer_to_fd(Buffer& buffer, int fd);
|
||||||
void write_buffer_to_backup_file(Buffer& buffer);
|
void write_buffer_to_backup_file(Buffer& buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user