diff --git a/src/buffer.cc b/src/buffer.cc index 0685e5b3..02f076d0 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -18,7 +18,7 @@ namespace Kakoune { Buffer::Buffer(String name, Flags flags, BufferLines lines, - time_t fs_timestamp) + timespec fs_timestamp) : Scope(GlobalScope::instance()), m_name((flags & Flags::File) ? real_path(parse_filename(name)) : std::move(name)), m_display_name((flags & Flags::File) ? compact_path(m_name) : m_name), @@ -160,7 +160,7 @@ struct Buffer::Modification } }; -void Buffer::reload(BufferLines lines, time_t fs_timestamp) +void Buffer::reload(BufferLines lines, timespec fs_timestamp) { if (lines.empty()) lines.emplace_back(StringData::create("\n")); @@ -531,13 +531,13 @@ ByteCoord Buffer::char_prev(ByteCoord coord) const return coord; } -time_t Buffer::fs_timestamp() const +timespec Buffer::fs_timestamp() const { kak_assert(m_flags & Flags::File); return m_fs_timestamp; } -void Buffer::set_fs_timestamp(time_t ts) +void Buffer::set_fs_timestamp(timespec ts) { kak_assert(m_flags & Flags::File); m_fs_timestamp = ts; diff --git a/src/buffer.hh b/src/buffer.hh index ba5a62df..5342dd83 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -14,7 +14,7 @@ namespace Kakoune class Buffer; -constexpr time_t InvalidTime = 0; +constexpr timespec InvalidTime = { -1, -1 }; // A BufferIterator permits to iterate over the characters of a buffer class BufferIterator @@ -79,7 +79,7 @@ public: }; Buffer(String name, Flags flags, BufferLines lines = {}, - time_t fs_timestamp = InvalidTime); + timespec fs_timestamp = InvalidTime); Buffer(const Buffer&) = delete; Buffer& operator= (const Buffer&) = delete; ~Buffer(); @@ -93,8 +93,8 @@ public: BufferIterator erase(BufferIterator begin, BufferIterator end); size_t timestamp() const; - time_t fs_timestamp() const; - void set_fs_timestamp(time_t ts); + timespec fs_timestamp() const; + void set_fs_timestamp(timespec ts); void commit_undo_group(); bool undo(); @@ -152,7 +152,7 @@ public: void run_hook_in_own_context(StringView hook_name, StringView param); - void reload(BufferLines lines, time_t fs_timestamp = InvalidTime); + void reload(BufferLines lines, timespec fs_timestamp = InvalidTime); void check_invariant() const; @@ -213,7 +213,7 @@ private: Vector m_changes; - time_t m_fs_timestamp; + timespec m_fs_timestamp; // Values are just data holding by the buffer, they are not part of its // observable state diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index c6795fe1..0bebf5d6 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -47,7 +47,7 @@ ByteCount get_byte_to_column(const Buffer& buffer, CharCount tabstop, CharCoord } Buffer* create_buffer_from_data(StringView data, StringView name, - Buffer::Flags flags, time_t fs_timestamp) + Buffer::Flags flags, timespec fs_timestamp) { bool bom = false, crlf = false; @@ -98,7 +98,7 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll) if (buffer) { buffer->flags() |= Buffer::Flags::NoUndo; - buffer->reload({"\n"_ss}, 0); + buffer->reload({"\n"_ss}, InvalidTime); } else buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo); diff --git a/src/buffer_utils.hh b/src/buffer_utils.hh index 33609150..ab02451f 100644 --- a/src/buffer_utils.hh +++ b/src/buffer_utils.hh @@ -34,7 +34,7 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll = false); Buffer* create_buffer_from_data(StringView data, StringView name, Buffer::Flags flags, - time_t fs_timestamp = InvalidTime); + timespec fs_timestamp = InvalidTime); void write_to_debug_buffer(StringView str); diff --git a/src/client.cc b/src/client.cc index 9da589b5..da218b7c 100644 --- a/src/client.cc +++ b/src/client.cc @@ -246,7 +246,7 @@ void Client::check_if_buffer_needs_reloading() return; const String& filename = buffer.name(); - time_t ts = get_fs_timestamp(filename); + timespec ts = get_fs_timestamp(filename); if (ts == InvalidTime or ts == buffer.fs_timestamp()) return; if (reload == Ask) diff --git a/src/file.cc b/src/file.cc index 2e67f872..ad526a93 100644 --- a/src/file.cc +++ b/src/file.cc @@ -180,13 +180,13 @@ Buffer* create_buffer_from_file(StringView filename) throw file_access_error(real_filename, "is a directory"); if (S_ISFIFO(st.st_mode)) // Do not try to read fifos, use them as write only return create_buffer_from_data({}, real_filename, - Buffer::Flags::File, st.st_mtime); + Buffer::Flags::File, st.st_mtim); const char* data = (const char*)mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); auto unmap = on_scope_end([&]{ munmap((void*)data, st.st_size); }); return create_buffer_from_data({data, data + st.st_size}, real_filename, - Buffer::Flags::File, st.st_mtime); + Buffer::Flags::File, st.st_mtim); } static void write(int fd, StringView data) @@ -423,11 +423,11 @@ Vector complete_command(StringView prefix, ByteCount cursor_pos) return res; } - typedef decltype(stat::st_mtime) TimeSpec; + typedef decltype(stat::st_mtim) TimeSpec; struct CommandCache { - TimeSpec mtime = {}; + TimeSpec mtim = {}; Vector commands; }; static UnorderedMap command_cache; @@ -442,7 +442,7 @@ Vector complete_command(StringView prefix, ByteCount cursor_pos) continue; auto& cache = command_cache[dirname]; - if (memcmp(&cache.mtime, &st.st_mtime, sizeof(TimeSpec)) != 0) + if (memcmp(&cache.mtim, &st.st_mtim, sizeof(TimeSpec)) != 0) { auto filter = [&](const dirent& entry) { struct stat st; @@ -457,7 +457,7 @@ Vector complete_command(StringView prefix, ByteCount cursor_pos) }; cache.commands = list_files("", dirname, filter); - memcpy(&cache.mtime, &st.st_mtime, sizeof(TimeSpec)); + memcpy(&cache.mtim, &st.st_mtim, sizeof(TimeSpec)); } for (auto& cmd : cache.commands) { @@ -471,12 +471,12 @@ Vector complete_command(StringView prefix, ByteCount cursor_pos) return res; } -time_t get_fs_timestamp(StringView filename) +timespec get_fs_timestamp(StringView filename) { struct stat st; if (stat(filename.zstr(), &st) != 0) return InvalidTime; - return st.st_mtime; + return st.st_mtim; } String get_kak_binary_path() diff --git a/src/file.hh b/src/file.hh index ef51c2d8..6061d402 100644 --- a/src/file.hh +++ b/src/file.hh @@ -52,7 +52,17 @@ Vector list_files(StringView directory); void make_directory(StringView dir); -time_t get_fs_timestamp(StringView filename); +timespec get_fs_timestamp(StringView filename); + +constexpr bool operator==(const timespec& lhs, const timespec& rhs) +{ + return lhs.tv_sec == rhs.tv_sec and lhs.tv_nsec == rhs.tv_nsec; +} + +constexpr bool operator!=(const timespec& lhs, const timespec& rhs) +{ + return not (lhs == rhs); +} CandidateList complete_filename(StringView prefix, const Regex& ignore_regex, ByteCount cursor_pos = -1);