Merge remote-tracking branch 'lenormf/reload-buffer-hash'

This commit is contained in:
Maxime Coste 2019-12-04 21:14:15 +11:00
commit 5c5d881c11
5 changed files with 39 additions and 16 deletions

View File

@ -78,7 +78,7 @@ Buffer::Buffer(String name, Flags flags, StringView data,
m_history{{HistoryId::Invalid}}, m_history{{HistoryId::Invalid}},
m_history_id{HistoryId::First}, m_history_id{HistoryId::First},
m_last_save_history_id{HistoryId::First}, m_last_save_history_id{HistoryId::First},
m_fs_timestamp{fs_timestamp.tv_sec, fs_timestamp.tv_nsec} m_fs_status{fs_timestamp, data.length(), hash_value(data)}
{ {
ParsedLines parsed_lines = parse_lines(data); ParsedLines parsed_lines = parse_lines(data);
@ -122,7 +122,7 @@ void Buffer::on_registered()
run_hook_in_own_context(Hook::BufNewFile, m_name); run_hook_in_own_context(Hook::BufNewFile, m_name);
else else
{ {
kak_assert(m_fs_timestamp != InvalidTime); kak_assert(m_fs_status.timestamp != InvalidTime);
run_hook_in_own_context(Hook::BufOpenFile, m_name); run_hook_in_own_context(Hook::BufOpenFile, m_name);
} }
} }
@ -308,7 +308,7 @@ void Buffer::reload(StringView data, timespec fs_timestamp)
apply_options(options(), parsed_lines); apply_options(options(), parsed_lines);
m_last_save_history_id = m_history_id; m_last_save_history_id = m_history_id;
m_fs_timestamp = fs_timestamp; m_fs_status = {fs_timestamp, data.length(), hash_value(data)};
} }
void Buffer::commit_undo_group() void Buffer::commit_undo_group()
@ -610,7 +610,7 @@ void Buffer::notify_saved()
m_flags &= ~Flags::New; m_flags &= ~Flags::New;
m_last_save_history_id = m_history_id; m_last_save_history_id = m_history_id;
m_fs_timestamp = get_fs_timestamp(m_name); m_fs_status.timestamp = get_fs_timestamp(m_name);
} }
BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const
@ -666,16 +666,16 @@ BufferCoord Buffer::char_prev(BufferCoord coord) const
return { coord.line, column }; return { coord.line, column };
} }
timespec Buffer::fs_timestamp() const void Buffer::set_fs_status(FsStatus status)
{ {
kak_assert(m_flags & Flags::File); kak_assert(m_flags & Flags::File);
return m_fs_timestamp; m_fs_status = std::move(status);
} }
void Buffer::set_fs_timestamp(timespec ts) const FsStatus& Buffer::fs_status() const
{ {
kak_assert(m_flags & Flags::File); kak_assert(m_flags & Flags::File);
m_fs_timestamp = ts; return m_fs_status;
} }
void Buffer::on_option_changed(const Option& option) void Buffer::on_option_changed(const Option& option)

View File

@ -5,6 +5,7 @@
#include "coord.hh" #include "coord.hh"
#include "constexpr_utils.hh" #include "constexpr_utils.hh"
#include "enum.hh" #include "enum.hh"
#include "file.hh"
#include "optional.hh" #include "optional.hh"
#include "safe_ptr.hh" #include "safe_ptr.hh"
#include "scope.hh" #include "scope.hh"
@ -142,9 +143,9 @@ public:
BufferCoord erase(BufferCoord begin, BufferCoord end); BufferCoord erase(BufferCoord begin, BufferCoord end);
BufferCoord replace(BufferCoord begin, BufferCoord end, StringView content); BufferCoord replace(BufferCoord begin, BufferCoord end, StringView content);
size_t timestamp() const; size_t timestamp() const;
timespec fs_timestamp() const; void set_fs_status(FsStatus);
void set_fs_timestamp(timespec ts); const FsStatus& fs_status() const;
void commit_undo_group(); void commit_undo_group();
bool undo(size_t count = 1); bool undo(size_t count = 1);
@ -285,7 +286,7 @@ private:
Vector<Change, MemoryDomain::BufferMeta> m_changes; Vector<Change, MemoryDomain::BufferMeta> m_changes;
timespec m_fs_timestamp; FsStatus m_fs_status;
// Values are just data holding by the buffer, they are not part of its // Values are just data holding by the buffer, they are not part of its
// observable state // observable state

View File

@ -287,7 +287,7 @@ void Client::reload_buffer()
{ {
context().print_status({ format("error while reloading buffer: '{}'", error.what()), context().print_status({ format("error while reloading buffer: '{}'", error.what()),
context().faces()["Error"] }); context().faces()["Error"] });
buffer.set_fs_timestamp(get_fs_timestamp(buffer.name())); buffer.set_fs_status(get_fs_status(buffer.name()));
} }
} }
@ -312,7 +312,7 @@ void Client::on_buffer_reload_key(Key key)
else if (key == 'n' or key == 'N' or key == Key::Escape) else if (key == 'n' or key == 'N' or key == Key::Escape)
{ {
// reread timestamp in case the file was modified again // reread timestamp in case the file was modified again
buffer.set_fs_timestamp(get_fs_timestamp(buffer.name())); buffer.set_fs_status(get_fs_status(buffer.name()));
print_status({ format("'{}' kept", buffer.display_name()), print_status({ format("'{}' kept", buffer.display_name()),
context().faces()["Information"] }); context().faces()["Information"] });
if (key == 'N') if (key == 'N')
@ -354,9 +354,16 @@ void Client::check_if_buffer_needs_reloading()
return; return;
const String& filename = buffer.name(); const String& filename = buffer.name();
timespec ts = get_fs_timestamp(filename); const timespec ts = get_fs_timestamp(filename);
if (ts == InvalidTime or ts == buffer.fs_timestamp()) const auto status = buffer.fs_status();
if (ts == InvalidTime or ts == status.timestamp)
return; return;
if (MappedFile fd{filename};
fd.st.st_size == status.file_size and hash_data(fd.data, fd.st.st_size) == status.hash)
return;
if (reload == Autoreload::Ask) if (reload == Autoreload::Ask)
{ {
StringView bufname = buffer.display_name(); StringView bufname = buffer.display_name();

View File

@ -609,6 +609,13 @@ timespec get_fs_timestamp(StringView filename)
return st.st_mtim; return st.st_mtim;
} }
FsStatus get_fs_status(StringView filename)
{
MappedFile fd{filename};
return {fd.st.st_mtim, fd.st.st_size, hash_data(fd.data, fd.st.st_size)};
}
String get_kak_binary_path() String get_kak_binary_path()
{ {
char buffer[2048]; char buffer[2048];

View File

@ -86,7 +86,15 @@ Vector<String> list_files(StringView directory);
void make_directory(StringView dir, mode_t mode); void make_directory(StringView dir, mode_t mode);
struct FsStatus
{
timespec timestamp;
ByteCount file_size;
size_t hash;
};
timespec get_fs_timestamp(StringView filename); timespec get_fs_timestamp(StringView filename);
FsStatus get_fs_status(StringView filename);
constexpr bool operator==(const timespec& lhs, const timespec& rhs) constexpr bool operator==(const timespec& lhs, const timespec& rhs)
{ {