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

View File

@ -1,7 +1,7 @@
#ifndef context_hh_INCLUDED
#define context_hh_INCLUDED
#include "dynamic_selection_list.hh"
#include "selection.hh"
#include <boost/optional.hpp>
@ -85,7 +85,7 @@ private:
safe_ptr<Client> m_client;
friend class Client;
boost::optional<DynamicSelectionList> m_selections;
boost::optional<SelectionList> m_selections;
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);
buffer.insert(buffer.iterator_at(selections[i].cursor()),
strings[index]);
selections.update();
}
}
@ -771,8 +772,12 @@ private:
{
auto str = codepoint_to_str(key);
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);
selections.update();
}
context().hooks().run_hook("InsertChar", str, context());
}
@ -829,6 +834,8 @@ private:
anchor = buffer.char_prev(anchor);
if (buffer.is_end(cursor))
cursor = buffer.char_prev(cursor);
selections.update();
sel.anchor() = anchor;
sel.cursor() = cursor;
}

View File

@ -185,13 +185,14 @@ void InsertCompleter::select(int offset)
if (m_current_candidate < 0)
m_current_candidate += m_matching_candidates.size();
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 suffix_len = std::max(0_byte, buffer.distance(cursor_pos, m_completions.end));
const auto buffer_len = buffer.byte_count();
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 pos = buffer.iterator_at(sel.cursor());
@ -200,6 +201,7 @@ void InsertCompleter::select(int offset)
{
pos = buffer.erase(pos - prefix_len, pos + suffix_len);
buffer.insert(pos, candidate);
const_cast<SelectionList&>(selections).update();
}
}
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);
pos = buffer.insert(pos, str);
selections.update();
if (mode == InsertMode::Replace and pos != buffer.end())
{
sel.anchor() = pos.coord();
@ -93,6 +94,7 @@ void insert(Buffer& buffer, SelectionList& selections, memoryview<String> string
auto pos = prepare_insert<mode>(buffer, sel);
const String& str = strings[std::min(i, strings.size()-1)];
pos = buffer.insert(pos, str);
selections.update();
if (mode == InsertMode::Replace and pos != buffer.end())
{
sel.anchor() = pos.coord();

View File

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