2011-09-02 18:51:20 +02:00
|
|
|
#include "display_buffer.hh"
|
|
|
|
|
2011-09-29 11:10:27 +02:00
|
|
|
#include "assert.hh"
|
2012-04-05 04:00:34 +02:00
|
|
|
#include <algorithm>
|
2011-09-29 10:55:08 +02:00
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2012-03-08 22:23:29 +01:00
|
|
|
String DisplayAtom::content() const
|
2011-10-15 06:45:49 +02:00
|
|
|
{
|
|
|
|
if (m_replacement_text.empty())
|
|
|
|
return m_begin.buffer().string(m_begin, m_end);
|
|
|
|
else
|
|
|
|
return m_replacement_text;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Iterator>
|
|
|
|
static DisplayCoord advance_coord(const DisplayCoord& pos,
|
|
|
|
Iterator begin, Iterator end)
|
|
|
|
{
|
|
|
|
DisplayCoord res = pos;
|
|
|
|
while (begin != end)
|
|
|
|
{
|
|
|
|
if (*begin == '\n')
|
|
|
|
{
|
|
|
|
++res.line;
|
|
|
|
res.column = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++res.column;
|
|
|
|
++begin;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayCoord DisplayAtom::end_coord() const
|
|
|
|
{
|
|
|
|
if (m_replacement_text.empty())
|
|
|
|
return advance_coord(m_coord, m_begin, m_end);
|
|
|
|
else
|
|
|
|
return advance_coord(m_coord, m_replacement_text.begin(),
|
|
|
|
m_replacement_text.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
BufferIterator DisplayAtom::iterator_at(const DisplayCoord& coord) const
|
|
|
|
{
|
|
|
|
if (not m_replacement_text.empty() or coord <= m_coord)
|
|
|
|
return m_begin;
|
|
|
|
|
|
|
|
DisplayCoord pos = m_coord;
|
|
|
|
for (BufferIterator it = m_begin; it != m_end; ++it)
|
|
|
|
{
|
|
|
|
if (*it == '\n')
|
|
|
|
{
|
|
|
|
++pos.line;
|
|
|
|
pos.column = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++pos.column;
|
|
|
|
|
2011-11-16 22:03:32 +01:00
|
|
|
if (coord <= pos)
|
2011-10-15 06:45:49 +02:00
|
|
|
return it+1;
|
|
|
|
}
|
|
|
|
return m_end;
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayCoord DisplayAtom::line_and_column_at(const BufferIterator& iterator) const
|
|
|
|
{
|
|
|
|
assert(iterator >= m_begin and iterator < m_end);
|
|
|
|
|
|
|
|
if (not m_replacement_text.empty())
|
|
|
|
return m_coord;
|
|
|
|
|
|
|
|
return advance_coord(m_coord, m_begin, iterator);
|
|
|
|
}
|
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
DisplayBuffer::DisplayBuffer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-10-17 21:00:38 +02:00
|
|
|
DisplayBuffer::iterator DisplayBuffer::insert(iterator where, const DisplayAtom& atom)
|
|
|
|
{
|
|
|
|
iterator res = m_atoms.insert(where, atom);
|
|
|
|
check_invariant();
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayBuffer::iterator DisplayBuffer::atom_containing(const BufferIterator& where)
|
|
|
|
{
|
2011-10-23 22:26:30 +02:00
|
|
|
return atom_containing(where, m_atoms.begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayBuffer::iterator DisplayBuffer::atom_containing(const BufferIterator& where,
|
|
|
|
iterator start)
|
|
|
|
{
|
2012-04-05 04:00:34 +02:00
|
|
|
return std::upper_bound(start, end(), where,
|
|
|
|
[](const BufferIterator& where, const DisplayAtom& atom)
|
|
|
|
{ return where < atom.end(); });
|
2011-10-17 21:00:38 +02:00
|
|
|
}
|
|
|
|
|
2011-10-07 16:19:58 +02:00
|
|
|
DisplayBuffer::iterator DisplayBuffer::split(iterator atom, const BufferIterator& pos)
|
2011-09-29 10:55:08 +02:00
|
|
|
{
|
2011-10-15 06:45:49 +02:00
|
|
|
assert(pos > atom->begin());
|
|
|
|
assert(pos < atom->end());
|
2011-11-14 15:10:11 +01:00
|
|
|
|
|
|
|
BufferIterator end = atom->m_end;
|
|
|
|
atom->m_end = pos;
|
|
|
|
|
|
|
|
DisplayAtom new_atom(atom->end_coord(), pos, end,
|
2011-10-15 06:45:49 +02:00
|
|
|
atom->fg_color(), atom->bg_color(), atom->attribute());
|
2011-09-29 10:55:08 +02:00
|
|
|
|
2011-11-14 15:10:11 +01:00
|
|
|
iterator insert_pos = atom;
|
|
|
|
++insert_pos;
|
|
|
|
m_atoms.insert(insert_pos, std::move(new_atom));
|
2011-10-15 06:45:49 +02:00
|
|
|
check_invariant();
|
2011-11-14 15:10:11 +01:00
|
|
|
return atom;
|
2011-09-29 10:55:08 +02:00
|
|
|
}
|
|
|
|
|
2011-09-29 11:10:27 +02:00
|
|
|
void DisplayBuffer::check_invariant() const
|
|
|
|
{
|
2011-10-18 15:59:32 +02:00
|
|
|
const_iterator prev_it;
|
|
|
|
for (const_iterator it = begin(); it != end(); ++it)
|
2011-09-29 11:10:27 +02:00
|
|
|
{
|
2011-10-18 15:59:32 +02:00
|
|
|
assert(it->end() >= it->begin());
|
|
|
|
if (it != begin())
|
|
|
|
assert(prev_it->end() == it->begin());
|
|
|
|
prev_it = it;
|
2011-10-15 06:45:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayBuffer::replace_atom_content(iterator atom,
|
2012-03-08 22:23:29 +01:00
|
|
|
const String& replacement)
|
2011-10-15 06:45:49 +02:00
|
|
|
{
|
|
|
|
atom->m_replacement_text = replacement;
|
|
|
|
|
|
|
|
// update coordinates of subsequents atoms
|
|
|
|
DisplayCoord new_coord = atom->end_coord();
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
new_coord = atom->end_coord();
|
|
|
|
++atom;
|
|
|
|
|
|
|
|
if (atom == end() or new_coord == atom->m_coord)
|
|
|
|
break;
|
|
|
|
atom->m_coord = new_coord;
|
2011-09-29 11:10:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
}
|