Use a plain SelectionList for Context, remove DynamicSelectionList

This commit is contained in:
Maxime Coste 2014-05-14 00:59:36 +01:00
parent db423e4a88
commit bf98b38afd
8 changed files with 27 additions and 74 deletions

View File

@ -21,7 +21,7 @@ Buffer& Context::buffer() const
{ {
if (not has_buffer()) if (not has_buffer())
throw runtime_error("no buffer in context"); throw runtime_error("no buffer in context");
return (*m_selections).registry(); return const_cast<Buffer&>((*m_selections).buffer());
} }
Window& Context::window() const Window& Context::window() const
@ -175,7 +175,7 @@ void Context::change_buffer(Buffer& buffer)
if (has_client()) if (has_client())
client().change_buffer(buffer); client().change_buffer(buffer);
else else
m_selections = DynamicSelectionList{ { buffer, Selection{} } }; m_selections = SelectionList{buffer, Selection{}};
if (has_input_handler()) if (has_input_handler())
input_handler().reset_normal_mode(); input_handler().reset_normal_mode();
} }
@ -184,14 +184,13 @@ SelectionList& Context::selections()
{ {
if (not m_selections) if (not m_selections)
throw runtime_error("no selections in context"); throw runtime_error("no selections in context");
(*m_selections).update();
return *m_selections; return *m_selections;
} }
const SelectionList& Context::selections() const const SelectionList& Context::selections() const
{ {
if (not m_selections) return const_cast<Context&>(*this).selections();
throw runtime_error("no selections in context");
return *m_selections;
} }
std::vector<String> Context::selections_content() const std::vector<String> Context::selections_content() const

View File

@ -1,7 +1,7 @@
#ifndef context_hh_INCLUDED #ifndef context_hh_INCLUDED
#define context_hh_INCLUDED #define context_hh_INCLUDED
#include "dynamic_selection_list.hh" #include "selection.hh"
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -85,7 +85,7 @@ private:
safe_ptr<Client> m_client; safe_ptr<Client> m_client;
friend class Client; friend class Client;
boost::optional<DynamicSelectionList> m_selections; boost::optional<SelectionList> m_selections;
String m_name; String m_name;

View File

@ -1,30 +0,0 @@
#include "dynamic_selection_list.hh"
namespace Kakoune
{
DynamicSelectionList::DynamicSelectionList(SelectionList selections)
: SelectionList(std::move(selections)),
BufferChangeListener_AutoRegister(const_cast<Buffer&>(buffer()))
{
check_invariant();
}
DynamicSelectionList& DynamicSelectionList::operator=(SelectionList selections)
{
SelectionList::operator=(std::move(selections));
check_invariant();
return *this;
}
void DynamicSelectionList::on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end, bool at_end)
{
update();
}
void DynamicSelectionList::on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end, bool at_end)
{
update();
}
}

View File

@ -1,30 +0,0 @@
#ifndef dynamic_selection_list_hh_INCLUDED
#define dynamic_selection_list_hh_INCLUDED
#include "selection.hh"
namespace Kakoune
{
class DynamicSelectionList : public SelectionList,
public BufferChangeListener_AutoRegister
{
public:
using iterator = SelectionList::iterator;
using const_iterator = SelectionList::const_iterator;
DynamicSelectionList(SelectionList selections);
DynamicSelectionList& operator=(SelectionList selections);
using SelectionList::buffer;
private:
void on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end, bool at_end) override;
void on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end, bool at_end) override;
};
}
#endif // dynamic_selection_list_hh_INCLUDED

View File

@ -764,6 +764,7 @@ private:
size_t index = std::min(i, strings.size()-1); size_t index = std::min(i, strings.size()-1);
buffer.insert(buffer.iterator_at(selections[i].cursor()), buffer.insert(buffer.iterator_at(selections[i].cursor()),
strings[index]); strings[index]);
selections.update();
} }
} }
@ -771,8 +772,12 @@ private:
{ {
auto str = codepoint_to_str(key); auto str = codepoint_to_str(key);
auto& buffer = context().buffer(); auto& buffer = context().buffer();
for (auto& sel : context().selections()) auto& selections = context().selections();
for (auto& sel : selections)
{
buffer.insert(buffer.iterator_at(sel.cursor()), str); buffer.insert(buffer.iterator_at(sel.cursor()), str);
selections.update();
}
context().hooks().run_hook("InsertChar", str, context()); context().hooks().run_hook("InsertChar", str, context());
} }
@ -829,6 +834,8 @@ private:
anchor = buffer.char_prev(anchor); anchor = buffer.char_prev(anchor);
if (buffer.is_end(cursor)) if (buffer.is_end(cursor))
cursor = buffer.char_prev(cursor); cursor = buffer.char_prev(cursor);
selections.update();
sel.anchor() = anchor; sel.anchor() = anchor;
sel.cursor() = cursor; sel.cursor() = cursor;
} }

View File

@ -185,13 +185,14 @@ void InsertCompleter::select(int offset)
if (m_current_candidate < 0) if (m_current_candidate < 0)
m_current_candidate += m_matching_candidates.size(); m_current_candidate += m_matching_candidates.size();
const String& candidate = m_matching_candidates[m_current_candidate]; const String& candidate = m_matching_candidates[m_current_candidate];
const auto& cursor_pos = m_context.selections().main().cursor(); auto& selections = m_context.selections();
const auto& cursor_pos = selections.main().cursor();
const auto prefix_len = buffer.distance(m_completions.begin, cursor_pos); const auto prefix_len = buffer.distance(m_completions.begin, cursor_pos);
const auto suffix_len = std::max(0_byte, buffer.distance(cursor_pos, m_completions.end)); const auto suffix_len = std::max(0_byte, buffer.distance(cursor_pos, m_completions.end));
const auto buffer_len = buffer.byte_count(); const auto buffer_len = buffer.byte_count();
auto ref = buffer.string(m_completions.begin, m_completions.end); auto ref = buffer.string(m_completions.begin, m_completions.end);
for (auto& sel : m_context.selections()) for (auto& sel : selections)
{ {
auto offset = buffer.offset(sel.cursor()); auto offset = buffer.offset(sel.cursor());
auto pos = buffer.iterator_at(sel.cursor()); auto pos = buffer.iterator_at(sel.cursor());
@ -200,6 +201,7 @@ void InsertCompleter::select(int offset)
{ {
pos = buffer.erase(pos - prefix_len, pos + suffix_len); pos = buffer.erase(pos - prefix_len, pos + suffix_len);
buffer.insert(pos, candidate); buffer.insert(pos, candidate);
const_cast<SelectionList&>(selections).update();
} }
} }
m_completions.end = cursor_pos; m_completions.end = cursor_pos;

View File

@ -70,6 +70,7 @@ void insert(Buffer& buffer, SelectionList& selections, const String& str)
{ {
auto pos = prepare_insert<mode>(buffer, sel); auto pos = prepare_insert<mode>(buffer, sel);
pos = buffer.insert(pos, str); pos = buffer.insert(pos, str);
selections.update();
if (mode == InsertMode::Replace and pos != buffer.end()) if (mode == InsertMode::Replace and pos != buffer.end())
{ {
sel.anchor() = pos.coord(); sel.anchor() = pos.coord();
@ -93,6 +94,7 @@ void insert(Buffer& buffer, SelectionList& selections, memoryview<String> string
auto pos = prepare_insert<mode>(buffer, sel); auto pos = prepare_insert<mode>(buffer, sel);
const String& str = strings[std::min(i, strings.size()-1)]; const String& str = strings[std::min(i, strings.size()-1)];
pos = buffer.insert(pos, str); pos = buffer.insert(pos, str);
selections.update();
if (mode == InsertMode::Replace and pos != buffer.end()) if (mode == InsertMode::Replace and pos != buffer.end())
{ {
sel.anchor() = pos.coord(); sel.anchor() = pos.coord();

View File

@ -134,6 +134,9 @@ void update_erase(std::vector<Selection>& sels, ByteCoord begin, ByteCoord end,
void SelectionList::update() void SelectionList::update()
{ {
if (m_timestamp == m_buffer->timestamp())
return;
for (auto& change : m_buffer->changes_since(m_timestamp)) for (auto& change : m_buffer->changes_since(m_timestamp))
{ {
if (change.type == Buffer::Change::Insert) if (change.type == Buffer::Change::Insert)
@ -141,9 +144,10 @@ void SelectionList::update()
else else
update_erase(m_selections, change.begin, change.end, change.at_end); update_erase(m_selections, change.begin, change.end, change.at_end);
} }
m_timestamp = m_buffer->timestamp();
check_invariant(); check_invariant();
m_timestamp = m_buffer->timestamp();
} }
void SelectionList::check_invariant() const void SelectionList::check_invariant() const
@ -152,12 +156,11 @@ void SelectionList::check_invariant() const
auto& buffer = this->buffer(); auto& buffer = this->buffer();
kak_assert(size() > 0); kak_assert(size() > 0);
kak_assert(m_main < size()); kak_assert(m_main < size());
for (size_t i = 0; i+1 < size(); ++ i)
kak_assert((*this)[i].min() <= (*this)[i+1].min());
for (size_t i = 0; i < size(); ++i) for (size_t i = 0; i < size(); ++i)
{ {
auto& sel = (*this)[i]; auto& sel = (*this)[i];
if (i+1 < size())
kak_assert((*this)[i].min() <= (*this)[i+1].min());
kak_assert(buffer.is_valid(sel.anchor())); kak_assert(buffer.is_valid(sel.anchor()));
kak_assert(buffer.is_valid(sel.cursor())); kak_assert(buffer.is_valid(sel.cursor()));
kak_assert(not buffer.is_end(sel.anchor())); kak_assert(not buffer.is_end(sel.anchor()));