summaryrefslogtreecommitdiff
path: root/src/context.cc
diff options
context:
space:
mode:
authorFrank LENORMAND <lenormf@gmail.com>2021-09-11 10:43:25 +0300
committerFrank LENORMAND <lenormf@gmail.com>2021-10-06 08:44:47 +0200
commita5dd8a7935ccdc3859749d7757c6a4005b7b6a98 (patch)
treea934311fc4a91e394f53077b8ba13d59d6770887 /src/context.cc
parent09f4ef0917e9174cc0d10a86b0272f5e5d655285 (diff)
src: Allow `ga` to skip removed buffers
This commit prevents `ga` from returning a “no last buffer” error when the previously displayed buffer was removed. Since the jumps list keeps track of the order in which buffers were displayed already, handling arbitrary `delete-buffer`s as well, cycle through it to implement `ga` instead of storing a pointer. Note that this commit doesn't take into account buffer flags that might exclude some buffers from being cycled over by commands. Fixes #1840
Diffstat (limited to 'src/context.cc')
-rw-r--r--src/context.cc32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/context.cc b/src/context.cc
index 07259c97..efa91938 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -172,12 +172,6 @@ void Context::change_buffer(Buffer& buffer)
if (has_buffer() and m_edition_level > 0)
this->buffer().commit_undo_group();
- if (has_buffer())
- {
- auto* current = &this->buffer();
- m_last_buffer = contains(BufferManager::instance(), current) ? current : nullptr;
- }
-
if (has_client())
{
client().info_hide();
@@ -197,8 +191,6 @@ void Context::change_buffer(Buffer& buffer)
void Context::forget_buffer(Buffer& buffer)
{
m_jump_list.forget_buffer(buffer);
- if (m_last_buffer.get() == &buffer)
- m_last_buffer = nullptr;
if (&this->buffer() != &buffer)
return;
@@ -206,7 +198,29 @@ void Context::forget_buffer(Buffer& buffer)
if (is_editing() && has_input_handler())
input_handler().reset_normal_mode();
- change_buffer(m_last_buffer ? *m_last_buffer : BufferManager::instance().get_first_buffer());
+ auto last_buffer = this->last_buffer();
+ change_buffer(last_buffer ? *last_buffer : BufferManager::instance().get_first_buffer());
+}
+
+Buffer* Context::last_buffer() const
+{
+ const auto jump_list = m_jump_list.get_as_list();
+ if (jump_list.empty())
+ return nullptr;
+
+ auto predicate = [this](const auto& sels) {
+ return &sels.buffer() != &this->buffer();
+ };
+
+ auto next_buffer = find_if(jump_list.subrange(m_jump_list.current_index()-1),
+ predicate);
+ if (next_buffer != jump_list.end())
+ return &next_buffer->buffer();
+
+ auto previous_buffer = find_if(jump_list.subrange(0, m_jump_list.current_index()) | reverse(),
+ predicate);
+
+ return previous_buffer != jump_list.rend() ? &previous_buffer->buffer() : nullptr;
}
SelectionList& Context::selections()