summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Felice <jason.m.felice@gmail.com>2018-12-31 12:40:49 -0500
committerJason Felice <jason.m.felice@gmail.com>2020-01-01 19:47:29 -0500
commitb03b51d27ace58cc17eb8a3aec99fa20dd3209ab (patch)
treedc9fa1bcf2d259834f8f31cd4c3c8aac9b816892 /src
parent62b4780e07e152e037e29823bfd7d911b9767f2e (diff)
Add 'history' and 'uncommitted_modifications' expansions
Diffstat (limited to 'src')
-rw-r--r--src/buffer.cc18
-rw-r--r--src/buffer.hh42
-rw-r--r--src/buffer_utils.cc43
-rw-r--r--src/buffer_utils.hh5
-rw-r--r--src/main.cc8
5 files changed, 88 insertions, 28 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index f7eeee31..c2a04c2e 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -66,7 +66,7 @@ static void apply_options(OptionManager& options, const ParsedLines& parsed_line
}
Buffer::HistoryNode::HistoryNode(HistoryId parent)
- : parent{parent}, timepoint{Clock::now()}
+ : parent{parent}, committed{Clock::now()}
{}
Buffer::Buffer(String name, Flags flags, StringView data,
@@ -231,20 +231,10 @@ String Buffer::string(BufferCoord begin, BufferCoord end) const
return res;
}
-// A Modification holds a single atomic modification to Buffer
-struct Buffer::Modification
+Buffer::Modification Buffer::Modification::inverse() const
{
- enum Type { Insert, Erase };
-
- Type type;
- BufferCoord coord;
- StringDataPtr content;
-
- Modification inverse() const
- {
- return {type == Insert ? Erase : Insert, coord, content};
- }
-};
+ return {type == Insert ? Erase : Insert, coord, content};
+}
void Buffer::reload(StringView data, timespec fs_timestamp)
{
diff --git a/src/buffer.hh b/src/buffer.hh
index 0700acb9..73e5b370 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -230,14 +230,40 @@ public:
void on_unregistered();
void throw_if_read_only() const;
+
+ // A Modification holds a single atomic modification to Buffer
+ struct Modification
+ {
+ enum Type { Insert, Erase };
+
+ Type type;
+ BufferCoord coord;
+ StringDataPtr content;
+
+ Modification inverse() const;
+ };
+
+ using UndoGroup = Vector<Modification, MemoryDomain::BufferMeta>;
+
+ struct HistoryNode : UseMemoryDomain<MemoryDomain::BufferMeta>
+ {
+ HistoryNode(HistoryId parent);
+
+ HistoryId parent;
+ HistoryId redo_child = HistoryId::Invalid;
+ TimePoint committed;
+ UndoGroup undo_group;
+ };
+
+ const Vector<HistoryNode>& history() const { return m_history; }
+ const UndoGroup& current_undo_group() const { return m_current_undo_group; }
+
private:
void on_option_changed(const Option& option) override;
BufferRange do_insert(BufferCoord pos, StringView content);
BufferCoord do_erase(BufferCoord begin, BufferCoord end);
- struct Modification;
-
void apply_modification(const Modification& modification);
void revert_modification(const Modification& modification);
@@ -264,18 +290,6 @@ private:
String m_display_name;
Flags m_flags;
- using UndoGroup = Vector<Modification, MemoryDomain::BufferMeta>;
-
- struct HistoryNode : UseMemoryDomain<MemoryDomain::BufferMeta>
- {
- HistoryNode(HistoryId parent);
-
- HistoryId parent;
- HistoryId redo_child = HistoryId::Invalid;
- TimePoint timepoint;
- UndoGroup undo_group;
- };
-
Vector<HistoryNode> m_history;
HistoryId m_history_id = HistoryId::Invalid;
HistoryId m_last_save_history_id = HistoryId::Invalid;
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc
index 4b6c3763..1d3d350d 100644
--- a/src/buffer_utils.cc
+++ b/src/buffer_utils.cc
@@ -213,4 +213,47 @@ void write_to_debug_buffer(StringView str)
}
}
+InplaceString<23> to_string(Buffer::HistoryId id)
+{
+ if (id == Buffer::HistoryId::Invalid) {
+ InplaceString<23> res;
+ res.m_data[0] = '-';
+ res.m_length = 1;
+ return res;
+ } else {
+ return to_string(static_cast<size_t>(id));
+ }
+}
+
+String format_modification(const Buffer::Modification& modification, Quoting quoting)
+{
+ auto quote = quoter(quoting);
+ return quote(format("{}{}.{}|{}",
+ modification.type == Buffer::Modification::Type::Insert ? '+' : '-',
+ modification.coord.line, modification.coord.column,
+ modification.content->strview()));
+}
+
+String history_as_string(const Vector<Buffer::HistoryNode>& history, Quoting quoting)
+{
+ auto format_history_node = [&](const Buffer::HistoryNode& node) {
+ auto seconds = std::chrono::duration_cast<std::chrono::seconds>(node.committed.time_since_epoch());
+ return format("{} {} {}{}{}",
+ node.parent,
+ seconds.count(),
+ node.redo_child,
+ node.undo_group.empty() ? "" : " ",
+ undo_group_as_string(node.undo_group, quoting));
+ };
+ return join(history |transform(format_history_node), ' ', false);
+}
+
+String undo_group_as_string(const Buffer::UndoGroup& undo_group, Quoting quoting)
+{
+ auto modification_as_string = [&](const Buffer::Modification& modification) {
+ return format_modification(modification, quoting);
+ };
+ return join(undo_group |transform(modification_as_string), ' ', false);
+}
+
}
diff --git a/src/buffer_utils.hh b/src/buffer_utils.hh
index a3e43068..a7589864 100644
--- a/src/buffer_utils.hh
+++ b/src/buffer_utils.hh
@@ -84,6 +84,11 @@ void reload_file_buffer(Buffer& buffer);
void write_to_debug_buffer(StringView str);
+InplaceString<23> to_string(Buffer::HistoryId id);
+String format_modification(const Buffer::Modification& modification, Quoting quoting);
+String history_as_string(const Vector<Buffer::HistoryNode>& history, Quoting quoting);
+String undo_group_as_string(const Buffer::UndoGroup& undo_group, Quoting quoting);
+
}
#endif // buffer_utils_hh_INCLUDED
diff --git a/src/main.cc b/src/main.cc
index 84c88012..621b5350 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -309,6 +309,14 @@ static const EnvVarDesc builtin_env_vars[] = { {
return format("{} {} {} {}", setup.window_pos.line, setup.window_pos.column,
setup.window_range.line, setup.window_range.column);
}
+ }, {
+ "history", false,
+ [](StringView name, const Context& context, Quoting quoting) -> String
+ { return history_as_string(context.buffer().history(), quoting); }
+ }, {
+ "uncommitted_modifications", false,
+ [](StringView name, const Context& context, Quoting quoting) -> String
+ { return undo_group_as_string(context.buffer().current_undo_group(), quoting); }
}
};