diff options
| author | Frank LENORMAND <lenormf@gmail.com> | 2021-09-11 10:43:25 +0300 |
|---|---|---|
| committer | Frank LENORMAND <lenormf@gmail.com> | 2021-10-06 08:44:47 +0200 |
| commit | a5dd8a7935ccdc3859749d7757c6a4005b7b6a98 (patch) | |
| tree | a934311fc4a91e394f53077b8ba13d59d6770887 /src/context.cc | |
| parent | 09f4ef0917e9174cc0d10a86b0272f5e5d655285 (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.cc | 32 |
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() |
