Merge branch 'undo-tree'
This commit is contained in:
commit
8c05d9e146
208
src/buffer.cc
208
src/buffer.cc
|
@ -59,15 +59,19 @@ static void apply_options(OptionManager& options, const ParsedLines& parsed_line
|
|||
options.get_local_option("BOM").set(parsed_lines.bom);
|
||||
}
|
||||
|
||||
Buffer::HistoryNode::HistoryNode(size_t id, HistoryNode* parent)
|
||||
: id{id}, parent(parent), timepoint{Clock::now()}
|
||||
{}
|
||||
|
||||
Buffer::Buffer(String name, Flags flags, StringView data,
|
||||
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),
|
||||
m_flags(flags | Flags::NoUndo),
|
||||
m_history(), m_history_cursor(m_history.begin()),
|
||||
m_last_save_undo_index(0),
|
||||
m_fs_timestamp(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},
|
||||
m_flags{flags | Flags::NoUndo},
|
||||
m_history{m_next_history_id++, nullptr}, m_history_cursor{&m_history},
|
||||
m_last_save_history_cursor{&m_history},
|
||||
m_fs_timestamp{fs_timestamp}
|
||||
{
|
||||
ParsedLines parsed_lines = parse_lines(data);
|
||||
|
||||
|
@ -285,7 +289,7 @@ void Buffer::reload(StringView data, timespec fs_timestamp)
|
|||
|
||||
apply_options(options(), parsed_lines);
|
||||
|
||||
m_last_save_undo_index = m_history_cursor - m_history.begin();
|
||||
m_last_save_history_cursor = m_history_cursor;
|
||||
m_fs_timestamp = fs_timestamp;
|
||||
}
|
||||
|
||||
|
@ -297,44 +301,135 @@ void Buffer::commit_undo_group()
|
|||
if (m_current_undo_group.empty())
|
||||
return;
|
||||
|
||||
m_history.erase(m_history_cursor, m_history.end());
|
||||
|
||||
m_history.push_back(std::move(m_current_undo_group));
|
||||
auto* node = new HistoryNode{m_next_history_id++, m_history_cursor.get()};
|
||||
node->undo_group = std::move(m_current_undo_group);
|
||||
m_current_undo_group.clear();
|
||||
m_history_cursor = m_history.end();
|
||||
|
||||
if (m_history.size() < m_last_save_undo_index)
|
||||
m_last_save_undo_index = -1;
|
||||
m_history_cursor->childs.emplace_back(node);
|
||||
m_history_cursor->redo_child = node;
|
||||
m_history_cursor = node;
|
||||
}
|
||||
|
||||
bool Buffer::undo()
|
||||
bool Buffer::undo(size_t count) noexcept
|
||||
{
|
||||
commit_undo_group();
|
||||
|
||||
if (m_history_cursor == m_history.begin())
|
||||
if (not m_history_cursor->parent)
|
||||
return false;
|
||||
|
||||
--m_history_cursor;
|
||||
while (count-- and m_history_cursor->parent)
|
||||
{
|
||||
for (const Modification& modification : m_history_cursor->undo_group | reverse())
|
||||
apply_modification(modification.inverse());
|
||||
|
||||
m_history_cursor = m_history_cursor->parent;
|
||||
}
|
||||
|
||||
for (const Modification& modification : *m_history_cursor | reverse())
|
||||
apply_modification(modification.inverse());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::redo()
|
||||
bool Buffer::redo(size_t count) noexcept
|
||||
{
|
||||
if (m_history_cursor == m_history.end())
|
||||
if (not m_history_cursor->redo_child)
|
||||
return false;
|
||||
|
||||
kak_assert(m_current_undo_group.empty());
|
||||
|
||||
for (const Modification& modification : *m_history_cursor)
|
||||
apply_modification(modification);
|
||||
while (count-- and m_history_cursor->redo_child)
|
||||
{
|
||||
m_history_cursor = m_history_cursor->redo_child.get();
|
||||
|
||||
++m_history_cursor;
|
||||
for (const Modification& modification : m_history_cursor->undo_group)
|
||||
apply_modification(modification);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Buffer::move_to(HistoryNode* history_node) noexcept
|
||||
{
|
||||
commit_undo_group();
|
||||
|
||||
auto find_lowest_common_parent = [](HistoryNode* a, HistoryNode* b) {
|
||||
auto depth_of = [](HistoryNode* node) {
|
||||
size_t depth = 0;
|
||||
for (; node->parent; node = node->parent.get())
|
||||
++depth;
|
||||
return depth;
|
||||
};
|
||||
auto depthA = depth_of(a), depthB = depth_of(b);
|
||||
|
||||
for (; depthA > depthB; --depthA)
|
||||
a = a->parent.get();
|
||||
for (; depthB > depthA; --depthB)
|
||||
b = b->parent.get();
|
||||
|
||||
while (a != b)
|
||||
{
|
||||
a = a->parent.get();
|
||||
b = b->parent.get();
|
||||
}
|
||||
|
||||
kak_assert(a == b and a != nullptr);
|
||||
return a;
|
||||
};
|
||||
|
||||
auto parent = find_lowest_common_parent(m_history_cursor.get(), history_node);
|
||||
|
||||
// undo up to common parent
|
||||
for (auto it = m_history_cursor.get(); it != parent; it = it->parent.get())
|
||||
{
|
||||
for (const Modification& modification : it->undo_group | reverse())
|
||||
apply_modification(modification.inverse());
|
||||
}
|
||||
|
||||
static void (*apply_from_parent)(Buffer&, HistoryNode*, HistoryNode*) =
|
||||
[](Buffer& buffer, HistoryNode* parent, HistoryNode* node) {
|
||||
if (node == parent)
|
||||
return;
|
||||
|
||||
apply_from_parent(buffer, parent, node->parent.get());
|
||||
|
||||
node->parent->redo_child = node;
|
||||
|
||||
for (const Modification& modification : node->undo_group)
|
||||
buffer.apply_modification(modification);
|
||||
};
|
||||
|
||||
apply_from_parent(*this, parent, history_node);
|
||||
m_history_cursor = history_node;
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
Buffer::HistoryNode* Buffer::find_history_node(HistoryNode* node, const Func& func)
|
||||
{
|
||||
if (func(node))
|
||||
return node;
|
||||
|
||||
for (auto&& child : node->childs)
|
||||
{
|
||||
if (auto res = find_history_node(child.get(), func))
|
||||
return res;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Buffer::move_to(size_t history_id) noexcept
|
||||
{
|
||||
HistoryNode* target_node = find_history_node(&m_history, [history_id](HistoryNode* node) { return node->id == history_id; });
|
||||
|
||||
if (not target_node)
|
||||
return false;
|
||||
|
||||
move_to(target_node);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Buffer::current_history_id() const noexcept
|
||||
{
|
||||
return m_history_cursor->id;
|
||||
}
|
||||
|
||||
void Buffer::check_invariant() const
|
||||
{
|
||||
#ifdef KAK_DEBUG
|
||||
|
@ -505,8 +600,7 @@ ByteCoord Buffer::replace(ByteCoord begin, ByteCoord end, StringView content)
|
|||
|
||||
bool Buffer::is_modified() const
|
||||
{
|
||||
size_t history_cursor_index = m_history_cursor - m_history.begin();
|
||||
return m_last_save_undo_index != history_cursor_index
|
||||
return m_history_cursor != m_last_save_history_cursor
|
||||
or not m_current_undo_group.empty();
|
||||
}
|
||||
|
||||
|
@ -516,9 +610,7 @@ void Buffer::notify_saved()
|
|||
commit_undo_group();
|
||||
|
||||
m_flags &= ~Flags::New;
|
||||
size_t history_cursor_index = m_history_cursor - m_history.begin();
|
||||
if (m_last_save_undo_index != history_cursor_index)
|
||||
m_last_save_undo_index = history_cursor_index;
|
||||
m_last_save_history_cursor = m_history_cursor;
|
||||
m_fs_timestamp = get_fs_timestamp(m_name);
|
||||
}
|
||||
|
||||
|
@ -625,9 +717,9 @@ void Buffer::run_hook_in_own_context(StringView hook_name, StringView param)
|
|||
|
||||
ByteCoord Buffer::last_modification_coord() const
|
||||
{
|
||||
if (m_history.empty())
|
||||
if (m_history_cursor.get() == &m_history)
|
||||
return {};
|
||||
return m_history.back().back().coord;
|
||||
return m_history_cursor->undo_group.back().coord;
|
||||
}
|
||||
|
||||
String Buffer::debug_description() const
|
||||
|
@ -636,10 +728,14 @@ String Buffer::debug_description() const
|
|||
for (auto& line : m_lines)
|
||||
content_size += (int)line->strview().length();
|
||||
|
||||
size_t additional_size = 0;
|
||||
for (auto& undo_group : m_history)
|
||||
additional_size += undo_group.size() * sizeof(Modification);
|
||||
additional_size += m_changes.size() * sizeof(Change);
|
||||
static size_t (*count_mem)(const HistoryNode&) = [](const HistoryNode& node) {
|
||||
size_t size = node.undo_group.size() * sizeof(Modification);
|
||||
for (auto& child : node.childs)
|
||||
size += count_mem(*child);
|
||||
return size;
|
||||
};
|
||||
const size_t additional_size = count_mem(m_history) +
|
||||
m_changes.size() * sizeof(Change);
|
||||
|
||||
return format("{}\nFlags: {}{}{}{}\nUsed mem: content={} additional={}\n",
|
||||
display_name(),
|
||||
|
@ -731,21 +827,43 @@ UnitTest test_buffer{[]()
|
|||
UnitTest test_undo{[]()
|
||||
{
|
||||
Buffer buffer("test", Buffer::Flags::None, "allo ?\nmais que fais la police\n hein ?\n youpi\n");
|
||||
auto pos = buffer.insert(buffer.end_coord(), "kanaky\n");
|
||||
buffer.erase(pos, buffer.end_coord());
|
||||
buffer.insert(2_line, "tchou\n");
|
||||
buffer.insert(2_line, "mutch\n");
|
||||
buffer.erase({2, 1}, {2, 5});
|
||||
buffer.replace(2_line, buffer.end_coord(), "youpi");
|
||||
auto pos = buffer.insert(buffer.end_coord(), "kanaky\n"); // change 1
|
||||
buffer.commit_undo_group();
|
||||
buffer.erase(pos, buffer.end_coord()); // change 2
|
||||
buffer.commit_undo_group();
|
||||
buffer.insert(2_line, "tchou\n"); // change 3
|
||||
buffer.commit_undo_group();
|
||||
buffer.undo();
|
||||
buffer.redo();
|
||||
buffer.insert(2_line, "mutch\n"); // change 4
|
||||
buffer.commit_undo_group();
|
||||
buffer.erase({2, 1}, {2, 5}); // change 5
|
||||
buffer.commit_undo_group();
|
||||
buffer.undo(2);
|
||||
buffer.redo(2);
|
||||
buffer.undo();
|
||||
buffer.replace(2_line, buffer.end_coord(), "foo"); // change 6
|
||||
buffer.commit_undo_group();
|
||||
|
||||
kak_assert((int)buffer.line_count() == 4);
|
||||
kak_assert((int)buffer.line_count() == 3);
|
||||
kak_assert(buffer[0_line] == "allo ?\n");
|
||||
kak_assert(buffer[1_line] == "mais que fais la police\n");
|
||||
kak_assert(buffer[2_line] == " hein ?\n");
|
||||
kak_assert(buffer[3_line] == " youpi\n");
|
||||
kak_assert(buffer[2_line] == "foo\n");
|
||||
|
||||
buffer.move_to(3);
|
||||
kak_assert((int)buffer.line_count() == 5);
|
||||
kak_assert(buffer[0_line] == "allo ?\n");
|
||||
kak_assert(buffer[1_line] == "mais que fais la police\n");
|
||||
kak_assert(buffer[2_line] == "tchou\n");
|
||||
kak_assert(buffer[3_line] == " hein ?\n");
|
||||
kak_assert(buffer[4_line] == " youpi\n");
|
||||
|
||||
buffer.move_to(4);
|
||||
kak_assert((int)buffer.line_count() == 5);
|
||||
kak_assert(buffer[0_line] == "allo ?\n");
|
||||
kak_assert(buffer[1_line] == "mais que fais la police\n");
|
||||
kak_assert(buffer[2_line] == "mutch\n");
|
||||
kak_assert(buffer[3_line] == " hein ?\n");
|
||||
kak_assert(buffer[4_line] == " youpi\n");
|
||||
}};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef buffer_hh_INCLUDED
|
||||
#define buffer_hh_INCLUDED
|
||||
|
||||
#include "clock.hh"
|
||||
#include "coord.hh"
|
||||
#include "flags.hh"
|
||||
#include "safe_ptr.hh"
|
||||
|
@ -131,8 +132,10 @@ public:
|
|||
void set_fs_timestamp(timespec ts);
|
||||
|
||||
void commit_undo_group();
|
||||
bool undo();
|
||||
bool redo();
|
||||
bool undo(size_t count = 1) noexcept;
|
||||
bool redo(size_t count = 1) noexcept;
|
||||
bool move_to(size_t history_id) noexcept;
|
||||
size_t current_history_id() const noexcept;
|
||||
|
||||
String string(ByteCoord begin, ByteCoord end) const;
|
||||
|
||||
|
@ -241,13 +244,28 @@ private:
|
|||
Flags m_flags;
|
||||
|
||||
using UndoGroup = Vector<Modification, MemoryDomain::BufferMeta>;
|
||||
using History = Vector<UndoGroup, MemoryDomain::BufferMeta>;
|
||||
|
||||
History m_history;
|
||||
History::iterator m_history_cursor;
|
||||
UndoGroup m_current_undo_group;
|
||||
struct HistoryNode : SafeCountable, UseMemoryDomain<MemoryDomain::BufferMeta>
|
||||
{
|
||||
HistoryNode(size_t id, HistoryNode* parent);
|
||||
|
||||
size_t m_last_save_undo_index;
|
||||
size_t id;
|
||||
SafePtr<HistoryNode> parent;
|
||||
UndoGroup undo_group;
|
||||
Vector<std::unique_ptr<HistoryNode>, MemoryDomain::BufferMeta> childs;
|
||||
SafePtr<HistoryNode> redo_child;
|
||||
TimePoint timepoint;
|
||||
};
|
||||
|
||||
size_t m_next_history_id = 0;
|
||||
HistoryNode m_history;
|
||||
SafePtr<HistoryNode> m_history_cursor;
|
||||
SafePtr<HistoryNode> m_last_save_history_cursor;
|
||||
UndoGroup m_current_undo_group;
|
||||
|
||||
void move_to(HistoryNode* history_node) noexcept;
|
||||
|
||||
template<typename Func> HistoryNode* find_history_node(HistoryNode* node, const Func& func);
|
||||
|
||||
Vector<Change, MemoryDomain::BufferMeta> m_changes;
|
||||
|
||||
|
|
14
src/clock.hh
Normal file
14
src/clock.hh
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef clock_hh_INCLUDED
|
||||
#define clock_hh_INCLUDED
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = Clock::time_point;
|
||||
|
||||
}
|
||||
|
||||
#endif // clock_hh_INCLUDED
|
|
@ -1,11 +1,11 @@
|
|||
#ifndef event_manager_hh_INCLUDED
|
||||
#define event_manager_hh_INCLUDED
|
||||
|
||||
#include "clock.hh"
|
||||
#include "utils.hh"
|
||||
#include "flags.hh"
|
||||
#include "vector.hh"
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
|
||||
#include <sys/select.h>
|
||||
|
@ -41,9 +41,6 @@ private:
|
|||
Callback m_callback;
|
||||
};
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = Clock::time_point;
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "hook_manager.hh"
|
||||
|
||||
#include "clock.hh"
|
||||
#include "containers.hh"
|
||||
#include "context.hh"
|
||||
#include "buffer_utils.hh"
|
||||
|
@ -7,8 +8,6 @@
|
|||
#include "face_registry.hh"
|
||||
#include "regex.hh"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
@ -61,9 +60,6 @@ void HookManager::run_hook(StringView hook_name,
|
|||
m_running_hooks.emplace_back(hook_name, param);
|
||||
auto pop_running_hook = on_scope_end([this]{ m_running_hooks.pop_back(); });
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = Clock::time_point;
|
||||
|
||||
const DebugFlags debug_flags = context.options()["debug"].get<DebugFlags>();
|
||||
const bool profile = debug_flags & DebugFlags::Profile;
|
||||
auto start_time = profile ? Clock::now() : TimePoint{};
|
||||
|
|
|
@ -1414,40 +1414,59 @@ void restore_selections(Context& context, NormalParams params)
|
|||
context.print_status({format("Restored selections from register '{}'", reg), get_face("Information")});
|
||||
}
|
||||
|
||||
void undo(Context& context, NormalParams)
|
||||
void undo(Context& context, NormalParams params)
|
||||
{
|
||||
Buffer& buffer = context.buffer();
|
||||
size_t timestamp = buffer.timestamp();
|
||||
bool res = buffer.undo();
|
||||
if (res)
|
||||
if (buffer.undo(std::max(1, params.count)))
|
||||
{
|
||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||
if (not ranges.empty())
|
||||
context.selections_write_only() = std::move(ranges);
|
||||
context.selections().avoid_eol();
|
||||
}
|
||||
else if (not res)
|
||||
else
|
||||
context.print_status({ "nothing left to undo", get_face("Information") });
|
||||
}
|
||||
|
||||
void redo(Context& context, NormalParams)
|
||||
void redo(Context& context, NormalParams params)
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
Buffer& buffer = context.buffer();
|
||||
size_t timestamp = buffer.timestamp();
|
||||
bool res = buffer.redo();
|
||||
if (res)
|
||||
if (buffer.redo(std::max(1, params.count)))
|
||||
{
|
||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||
if (not ranges.empty())
|
||||
context.selections_write_only() = std::move(ranges);
|
||||
context.selections().avoid_eol();
|
||||
}
|
||||
|
||||
else if (not res)
|
||||
else
|
||||
context.print_status({ "nothing left to redo", get_face("Information") });
|
||||
}
|
||||
|
||||
template<Direction direction>
|
||||
void move_in_history(Context& context, NormalParams params)
|
||||
{
|
||||
Buffer& buffer = context.buffer();
|
||||
size_t timestamp = buffer.timestamp();
|
||||
const int count = std::max(1, params.count);
|
||||
const int history_id = (int)buffer.current_history_id() +
|
||||
(direction == Direction::Forward ? count : -count);
|
||||
if (buffer.move_to((size_t)history_id))
|
||||
{
|
||||
auto ranges = compute_modified_ranges(buffer, timestamp);
|
||||
if (not ranges.empty())
|
||||
context.selections_write_only() = std::move(ranges);
|
||||
context.selections().avoid_eol();
|
||||
|
||||
context.print_status({ format("moved to change #{}", history_id),
|
||||
get_face("Information") });
|
||||
}
|
||||
else
|
||||
context.print_status({ format("no such change: #{}", history_id),
|
||||
get_face("Information") });
|
||||
}
|
||||
|
||||
void exec_user_mappings(Context& context, NormalParams params)
|
||||
{
|
||||
on_next_key_with_autoinfo(context, KeymapMode::None,
|
||||
|
@ -1682,6 +1701,8 @@ static NormalCmdDesc cmds[] =
|
|||
|
||||
{ 'u', "undo", undo },
|
||||
{ 'U', "redo", redo },
|
||||
{ alt('u'), "move backward in history", move_in_history<Direction::Backward> },
|
||||
{ alt('U'), "move forward in history", move_in_history<Direction::Forward> },
|
||||
|
||||
{ alt('i'), "select inner object", select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd | ObjectFlags::Inner> },
|
||||
{ alt('a'), "select whole object", select_object<ObjectFlags::ToBegin | ObjectFlags::ToEnd> },
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#include "shell_manager.hh"
|
||||
|
||||
#include "clock.hh"
|
||||
#include "context.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "file.hh"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <cstring>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
@ -115,18 +114,16 @@ std::pair<String, int> ShellManager::eval(
|
|||
StringView cmdline, const Context& context, StringView input,
|
||||
Flags flags, const ShellContext& shell_context)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
const DebugFlags debug_flags = context.options()["debug"].get<DebugFlags>();
|
||||
const bool profile = debug_flags & DebugFlags::Profile;
|
||||
if (debug_flags & DebugFlags::Shell)
|
||||
write_to_debug_buffer(format("shell:\n{}\n----\n", cmdline));
|
||||
|
||||
auto start_time = profile ? steady_clock::now() : steady_clock::time_point{};
|
||||
auto start_time = profile ? Clock::now() : Clock::time_point{};
|
||||
|
||||
auto kak_env = generate_env(cmdline, context, shell_context);
|
||||
|
||||
auto spawn_time = profile ? steady_clock::now() : steady_clock::time_point{};
|
||||
auto spawn_time = profile ? Clock::now() : Clock::time_point{};
|
||||
|
||||
Pipe child_stdin{not input.empty()}, child_stdout, child_stderr;
|
||||
pid_t pid = spawn_shell(cmdline, shell_context.params, kak_env,
|
||||
|
@ -153,7 +150,7 @@ std::pair<String, int> ShellManager::eval(
|
|||
write(child_stdin.write_fd(), input);
|
||||
child_stdin.close_write_fd();
|
||||
|
||||
auto wait_time = profile ? steady_clock::now() : steady_clock::time_point{};
|
||||
auto wait_time = profile ? Clock::now() : Clock::time_point{};
|
||||
|
||||
struct PipeReader : FDWatcher
|
||||
{
|
||||
|
@ -203,7 +200,8 @@ std::pair<String, int> ShellManager::eval(
|
|||
|
||||
if (profile)
|
||||
{
|
||||
auto end_time = steady_clock::now();
|
||||
using namespace std::chrono;
|
||||
auto end_time = Clock::now();
|
||||
auto full = duration_cast<milliseconds>(end_time - start_time);
|
||||
auto spawn = duration_cast<milliseconds>(wait_time - spawn_time);
|
||||
auto wait = duration_cast<milliseconds>(end_time - wait_time);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "window.hh"
|
||||
|
||||
#include "assert.hh"
|
||||
#include "clock.hh"
|
||||
#include "context.hh"
|
||||
#include "highlighter.hh"
|
||||
#include "hook_manager.hh"
|
||||
|
@ -9,7 +10,6 @@
|
|||
#include "buffer_utils.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -109,12 +109,10 @@ bool Window::needs_redraw(const Context& context) const
|
|||
|
||||
const DisplayBuffer& Window::update_display_buffer(const Context& context)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
const bool profile = context.options()["debug"].get<DebugFlags>() &
|
||||
DebugFlags::Profile;
|
||||
|
||||
auto start_time = profile ? steady_clock::now() : steady_clock::time_point{};
|
||||
auto start_time = profile ? Clock::now() : Clock::time_point{};
|
||||
|
||||
DisplayBuffer::LineList& lines = m_display_buffer.lines();
|
||||
lines.clear();
|
||||
|
@ -147,7 +145,8 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
|
|||
|
||||
if (profile and not (buffer().flags() & Buffer::Flags::Debug))
|
||||
{
|
||||
auto duration = duration_cast<milliseconds>(steady_clock::now() - start_time);
|
||||
using namespace std::chrono;
|
||||
auto duration = duration_cast<milliseconds>(Clock::now() - start_time);
|
||||
write_to_debug_buffer(format("window display update for '{}' took {} ms",
|
||||
buffer().display_name(), (size_t)duration.count()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user