summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-02-17 10:19:54 +1100
committerMaxime Coste <mawww@kakoune.org>2019-02-17 11:21:26 +1100
commit1ad3b8730283ade32d64c43b45de5aca59930de0 (patch)
tree61168234753a9d7eefd9e78ed23304a41985c0e3 /src
parent924f30840bdde1b18602b3db8b63e2efb3517c21 (diff)
Collapse jumps based on current index change
The previous method, while likely more correct, could restore jump lists containing references to already removed buffers.
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc13
-rw-r--r--src/context.cc8
-rw-r--r--src/context.hh4
3 files changed, 16 insertions, 9 deletions
diff --git a/src/commands.cc b/src/commands.cc
index 5db90b5c..5f7e1530 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -1754,18 +1754,17 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d
else
{
const bool collapse_jumps = not (c.flags() & Context::Flags::Draft) and context.has_buffer();
- auto original_jump_list = collapse_jumps ? c.jump_list() : Optional<JumpList>{};
+ auto& jump_list = c.jump_list();
+ const size_t prev_index = jump_list.current_index();
auto jump = collapse_jumps ? c.selections() : Optional<SelectionList>{};
func(parser, c);
// If the jump list got mutated, collapse all jumps into a single one from original selections
- if (collapse_jumps and c.jump_list() != *original_jump_list)
- {
- original_jump_list->push(std::move(*jump));
- if (c.jump_list() != *original_jump_list)
- c.jump_list() = std::move(*original_jump_list);
- }
+ if (auto index = jump_list.current_index();
+ collapse_jumps and index > prev_index and
+ contains(BufferManager::instance(), &jump->buffer()))
+ jump_list.push(std::move(*jump), prev_index);
}
}
diff --git a/src/context.cc b/src/context.cc
index b3b82938..d97073d0 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -76,8 +76,14 @@ void Context::print_status(DisplayLine status) const
client().print_status(std::move(status));
}
-void JumpList::push(SelectionList jump)
+void JumpList::push(SelectionList jump, Optional<size_t> index)
{
+ if (index)
+ {
+ m_current = *index;
+ kak_assert(m_current <= m_jumps.size());
+ }
+
if (m_current != m_jumps.size())
m_jumps.erase(m_jumps.begin()+m_current+1, m_jumps.end());
m_jumps.erase(std::remove(begin(m_jumps), end(m_jumps), jump),
diff --git a/src/context.hh b/src/context.hh
index d8830b2e..b71e6547 100644
--- a/src/context.hh
+++ b/src/context.hh
@@ -21,7 +21,7 @@ class AliasRegistry;
struct JumpList
{
- void push(SelectionList jump);
+ void push(SelectionList jump, Optional<size_t> index = {});
const SelectionList& forward(Context& context, int count);
const SelectionList& backward(Context& context, int count);
void forget_buffer(Buffer& buffer);
@@ -33,6 +33,8 @@ struct JumpList
friend bool operator!=(const JumpList& lhs, const JumpList& rhs) { return not (lhs == rhs); }
+ size_t current_index() const { return m_current; }
+
private:
using Contents = Vector<SelectionList, MemoryDomain::Selections>;
Contents m_jumps;