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
This commit is contained in:
parent
09f4ef0917
commit
a5dd8a7935
|
@ -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()
|
||||
|
|
|
@ -35,6 +35,8 @@ struct JumpList
|
|||
|
||||
size_t current_index() const { return m_current; }
|
||||
|
||||
ConstArrayView<SelectionList> get_as_list() const { return m_jumps; }
|
||||
|
||||
private:
|
||||
using Contents = Vector<SelectionList, MemoryDomain::Selections>;
|
||||
Contents m_jumps;
|
||||
|
@ -135,7 +137,7 @@ public:
|
|||
|
||||
void repeat_last_select() { if (m_last_select) m_last_select(*this); }
|
||||
|
||||
Buffer* last_buffer() const { return m_last_buffer.get(); }
|
||||
Buffer* last_buffer() const;
|
||||
private:
|
||||
void begin_edition();
|
||||
void end_edition();
|
||||
|
@ -149,7 +151,6 @@ private:
|
|||
SafePtr<InputHandler> m_input_handler;
|
||||
SafePtr<Window> m_window;
|
||||
SafePtr<Client> m_client;
|
||||
SafePtr<Buffer> m_last_buffer;
|
||||
|
||||
Optional<SelectionList> m_selections;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user