Extract jump list handling in a JumpList struct

This commit is contained in:
Maxime Coste 2015-12-23 01:56:54 +00:00
parent 9e664318af
commit 411e5a9486
4 changed files with 55 additions and 46 deletions

View File

@ -111,7 +111,7 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
{ {
for (auto& client : m_clients) for (auto& client : m_clients)
{ {
client->context().forget_jumps_to_buffer(buffer); client->context().jump_list().forget_buffer(buffer);
if (client->last_buffer() == &buffer) if (client->last_buffer() == &buffer)
client->set_last_buffer(nullptr); client->set_last_buffer(nullptr);

View File

@ -83,74 +83,73 @@ void Context::print_status(DisplayLine status) const
client().print_status(std::move(status)); client().print_status(std::move(status));
} }
void Context::push_jump() void JumpList::push(SelectionList jump)
{ {
const SelectionList& jump = selections(); if (m_current != m_jumps.end())
if (m_current_jump != m_jump_list.end()) m_jumps.erase(m_current+1, m_jumps.end());
m_jump_list.erase(m_current_jump+1, m_jump_list.end()); m_jumps.erase(std::remove(begin(m_jumps), end(m_jumps), jump),
m_jump_list.erase(std::remove(begin(m_jump_list), end(m_jump_list), jump), end(m_jumps));
end(m_jump_list)); m_jumps.push_back(jump);
m_jump_list.push_back(jump); m_current = m_jumps.end();
m_current_jump = m_jump_list.end();
} }
void Context::drop_jump() void JumpList::drop()
{ {
if (not m_jump_list.empty()) if (not m_jumps.empty())
m_jump_list.pop_back(); m_jumps.pop_back();
m_current_jump = m_jump_list.end(); m_current = m_jumps.end();
} }
const SelectionList& Context::jump_forward() const SelectionList& JumpList::forward()
{ {
if (m_current_jump != m_jump_list.end() and if (m_current != m_jumps.end() and
m_current_jump + 1 != m_jump_list.end()) m_current + 1 != m_jumps.end())
{ {
SelectionList& res = *++m_current_jump; SelectionList& res = *++m_current;
res.update(); res.update();
return res; return res;
} }
throw runtime_error("no next jump"); throw runtime_error("no next jump");
} }
const SelectionList& Context::jump_backward() const SelectionList& JumpList::backward(const SelectionList& current)
{ {
if (m_current_jump != m_jump_list.end() and if (m_current != m_jumps.end() and
*m_current_jump != selections()) *m_current != current)
{ {
push_jump(); push(current);
SelectionList& res = *--m_current_jump; SelectionList& res = *--m_current;
res.update(); res.update();
return res; return res;
} }
if (m_current_jump != m_jump_list.begin()) if (m_current != m_jumps.begin())
{ {
if (m_current_jump == m_jump_list.end()) if (m_current == m_jumps.end())
{ {
push_jump(); push(current);
--m_current_jump; --m_current;
if (m_current_jump == m_jump_list.begin()) if (m_current == m_jumps.begin())
throw runtime_error("no previous jump"); throw runtime_error("no previous jump");
} }
SelectionList& res = *--m_current_jump; SelectionList& res = *--m_current;
res.update(); res.update();
return res; return res;
} }
throw runtime_error("no previous jump"); throw runtime_error("no previous jump");
} }
void Context::forget_jumps_to_buffer(Buffer& buffer) void JumpList::forget_buffer(Buffer& buffer)
{ {
for (auto it = m_jump_list.begin(); it != m_jump_list.end();) for (auto it = m_jumps.begin(); it != m_jumps.end();)
{ {
if (&it->buffer() == &buffer) if (&it->buffer() == &buffer)
{ {
if (it < m_current_jump) if (it < m_current)
--m_current_jump; --m_current;
else if (it == m_current_jump) else if (it == m_current)
m_current_jump = m_jump_list.end()-1; m_current = m_jumps.end()-1;
it = m_jump_list.erase(it); it = m_jumps.erase(it);
} }
else else
++it; ++it;

View File

@ -50,6 +50,20 @@ private:
bool m_condition; bool m_condition;
}; };
struct JumpList
{
void push(SelectionList jump);
void drop();
const SelectionList& forward();
const SelectionList& backward(const SelectionList& current);
void forget_buffer(Buffer& buffer);
private:
using Contents = Vector<SelectionList, MemoryDomain::Selections>;
Contents m_jumps;
Contents::iterator m_current = m_jumps.begin();
};
// A Context is used to access non singleton objects for various services // A Context is used to access non singleton objects for various services
// in commands. // in commands.
// //
@ -113,12 +127,6 @@ public:
StringView main_sel_register_value(StringView reg) const; StringView main_sel_register_value(StringView reg) const;
void push_jump();
void drop_jump();
const SelectionList& jump_forward();
const SelectionList& jump_backward();
void forget_jumps_to_buffer(Buffer& buffer);
const String& name() const { return m_name; } const String& name() const { return m_name; }
void set_name(String name) { m_name = std::move(name); } void set_name(String name) { m_name = std::move(name); }
@ -136,6 +144,9 @@ public:
Flags flags() const { return m_flags; } Flags flags() const { return m_flags; }
JumpList& jump_list() { return m_jump_list; }
void push_jump() { m_jump_list.push(selections()); }
private: private:
void begin_edition(); void begin_edition();
void end_edition(); void end_edition();
@ -153,9 +164,7 @@ private:
String m_name; String m_name;
using JumpList = Vector<SelectionList>; JumpList m_jump_list;
JumpList m_jump_list;
JumpList::iterator m_current_jump = m_jump_list.begin();
NestedBool m_user_hooks_disabled; NestedBool m_user_hooks_disabled;
NestedBool m_keymaps_disabled; NestedBool m_keymaps_disabled;

View File

@ -1135,7 +1135,8 @@ template<Direction direction>
void jump(Context& context, NormalParams) void jump(Context& context, NormalParams)
{ {
auto jump = (direction == Forward) ? auto jump = (direction == Forward) ?
context.jump_forward() : context.jump_backward(); context.jump_list().forward() :
context.jump_list().backward(context.selections());
Buffer* oldbuf = &context.buffer(); Buffer* oldbuf = &context.buffer();
Buffer& buffer = const_cast<Buffer&>(jump.buffer()); Buffer& buffer = const_cast<Buffer&>(jump.buffer());
@ -1153,7 +1154,7 @@ void push_selections(Context& context, NormalParams)
void drop_jump(Context& context, NormalParams) void drop_jump(Context& context, NormalParams)
{ {
context.drop_jump(); context.jump_list().drop();
context.print_status({ "dropped last jump", get_face("Information") }); context.print_status({ "dropped last jump", get_face("Information") });
} }