DisplayBuffer: use coords rather than iterators
This commit is contained in:
parent
97df6f2222
commit
d5b190369a
|
@ -159,17 +159,17 @@ LineCount Buffer::line_count() const
|
||||||
return LineCount(m_lines.size());
|
return LineCount(m_lines.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
String Buffer::string(const BufferIterator& begin, const BufferIterator& end) const
|
String Buffer::string(const BufferCoord& begin, const BufferCoord& end) const
|
||||||
{
|
{
|
||||||
String res;
|
String res;
|
||||||
for (LineCount line = begin.line(); line <= end.line(); ++line)
|
for (LineCount line = begin.line; line <= end.line; ++line)
|
||||||
{
|
{
|
||||||
ByteCount start = 0;
|
ByteCount start = 0;
|
||||||
if (line == begin.line())
|
if (line == begin.line)
|
||||||
start = begin.column();
|
start = begin.column;
|
||||||
ByteCount count = -1;
|
ByteCount count = -1;
|
||||||
if (line == end.line())
|
if (line == end.line)
|
||||||
count = end.column() - start;
|
count = end.column - start;
|
||||||
res += m_lines[line].content.substr(start, count);
|
res += m_lines[line].content.substr(start, count);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -120,8 +120,11 @@ public:
|
||||||
bool undo();
|
bool undo();
|
||||||
bool redo();
|
bool redo();
|
||||||
|
|
||||||
|
String string(const BufferCoord& begin,
|
||||||
|
const BufferCoord& end) const;
|
||||||
String string(const BufferIterator& begin,
|
String string(const BufferIterator& begin,
|
||||||
const BufferIterator& end) const;
|
const BufferIterator& end) const
|
||||||
|
{ return string(begin.coord(), end.coord()); }
|
||||||
|
|
||||||
ByteCount offset(const BufferCoord& c) const;
|
ByteCount offset(const BufferCoord& c) const;
|
||||||
ByteCount distance(const BufferCoord& begin, const BufferCoord& end) const;
|
ByteCount distance(const BufferCoord& begin, const BufferCoord& end) const;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
DisplayLine::iterator DisplayLine::split(iterator it, BufferIterator pos)
|
DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
|
||||||
{
|
{
|
||||||
kak_assert(it->content.type() == AtomContent::BufferRange);
|
kak_assert(it->content.type() == AtomContent::BufferRange);
|
||||||
kak_assert(it->content.begin() < pos);
|
kak_assert(it->content.begin() < pos);
|
||||||
|
@ -67,8 +67,8 @@ CharCount DisplayLine::length() const
|
||||||
|
|
||||||
void DisplayBuffer::compute_range()
|
void DisplayBuffer::compute_range()
|
||||||
{
|
{
|
||||||
m_range.first = BufferIterator();
|
m_range.first = {INT_MAX,INT_MAX};
|
||||||
m_range.second = BufferIterator();
|
m_range.second = {0,0};
|
||||||
for (auto& line : m_lines)
|
for (auto& line : m_lines)
|
||||||
{
|
{
|
||||||
for (auto& atom : line)
|
for (auto& atom : line)
|
||||||
|
@ -76,14 +76,13 @@ void DisplayBuffer::compute_range()
|
||||||
if (not atom.content.has_buffer_range())
|
if (not atom.content.has_buffer_range())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (not m_range.first.is_valid() or m_range.first > atom.content.begin())
|
if (m_range.first > atom.content.begin())
|
||||||
m_range.first = atom.content.begin();
|
m_range.first = atom.content.begin();
|
||||||
|
|
||||||
if (not m_range.second.is_valid() or m_range.second < atom.content.end())
|
if (m_range.second < atom.content.end())
|
||||||
m_range.second = atom.content.end();
|
m_range.second = atom.content.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kak_assert(m_range.first.is_valid() and m_range.second.is_valid());
|
|
||||||
kak_assert(m_range.first <= m_range.second);
|
kak_assert(m_range.first <= m_range.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ public:
|
||||||
CharCount length() const;
|
CharCount length() const;
|
||||||
|
|
||||||
// Split atom pointed by it at pos, returns an iterator to the first atom
|
// Split atom pointed by it at pos, returns an iterator to the first atom
|
||||||
iterator split(iterator it, BufferIterator pos);
|
iterator split(iterator it, BufferCoord pos);
|
||||||
|
|
||||||
iterator insert(iterator it, DisplayAtom atom) { return m_atoms.insert(it, std::move(atom)); }
|
iterator insert(iterator it, DisplayAtom atom) { return m_atoms.insert(it, std::move(atom)); }
|
||||||
void push_back(DisplayAtom atom) { m_atoms.push_back(std::move(atom)); }
|
void push_back(DisplayAtom atom) { m_atoms.push_back(std::move(atom)); }
|
||||||
|
@ -158,7 +158,7 @@ private:
|
||||||
AtomList m_atoms;
|
AtomList m_atoms;
|
||||||
};
|
};
|
||||||
|
|
||||||
using BufferRange = std::pair<BufferIterator, BufferIterator>;
|
using BufferRange = std::pair<BufferCoord, BufferCoord>;
|
||||||
|
|
||||||
class DisplayBuffer
|
class DisplayBuffer
|
||||||
{
|
{
|
||||||
|
@ -169,7 +169,7 @@ public:
|
||||||
LineList& lines() { return m_lines; }
|
LineList& lines() { return m_lines; }
|
||||||
const LineList& lines() const { return m_lines; }
|
const LineList& lines() const { return m_lines; }
|
||||||
|
|
||||||
// returns the smallest BufferIterator range which contains every DisplayAtoms
|
// returns the smallest BufferRange which contains every DisplayAtoms
|
||||||
const BufferRange& range() const { return m_range; }
|
const BufferRange& range() const { return m_range; }
|
||||||
void optimize();
|
void optimize();
|
||||||
void compute_range();
|
void compute_range();
|
||||||
|
|
|
@ -22,7 +22,7 @@ typedef boost::regex_iterator<BufferIterator> RegexIterator;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void highlight_range(DisplayBuffer& display_buffer,
|
void highlight_range(DisplayBuffer& display_buffer,
|
||||||
BufferIterator begin, BufferIterator end,
|
BufferCoord begin, BufferCoord end,
|
||||||
bool skip_replaced, T func)
|
bool skip_replaced, T func)
|
||||||
{
|
{
|
||||||
if (begin == end or end <= display_buffer.range().first
|
if (begin == end or end <= display_buffer.range().first
|
||||||
|
@ -31,7 +31,7 @@ void highlight_range(DisplayBuffer& display_buffer,
|
||||||
|
|
||||||
for (auto& line : display_buffer.lines())
|
for (auto& line : display_buffer.lines())
|
||||||
{
|
{
|
||||||
if (line.buffer_line() < begin.line() or end.line() < line.buffer_line())
|
if (line.buffer_line() < begin.line or end.line < line.buffer_line())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
||||||
|
@ -71,9 +71,9 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const Window&, DisplayBuffer& display_buffer)
|
void operator()(const Window& window, DisplayBuffer& display_buffer)
|
||||||
{
|
{
|
||||||
update_cache_ifn(display_buffer.range());
|
update_cache_ifn(window.buffer(), display_buffer.range());
|
||||||
for (auto& match : m_cache_matches)
|
for (auto& match : m_cache_matches)
|
||||||
{
|
{
|
||||||
for (size_t n = 0; n < match.size(); ++n)
|
for (size_t n = 0; n < match.size(); ++n)
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
if (col_it == m_colors.end())
|
if (col_it == m_colors.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
highlight_range(display_buffer, match[n].first, match[n].second, true,
|
highlight_range(display_buffer, match[n].first.coord(), match[n].second.coord(), true,
|
||||||
[&](DisplayAtom& atom) { atom.colors = *col_it->second; });
|
[&](DisplayAtom& atom) { atom.colors = *col_it->second; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,22 +96,20 @@ private:
|
||||||
Regex m_regex;
|
Regex m_regex;
|
||||||
ColorSpec m_colors;
|
ColorSpec m_colors;
|
||||||
|
|
||||||
void update_cache_ifn(const BufferRange& range)
|
void update_cache_ifn(const Buffer& buffer, const BufferRange& range)
|
||||||
{
|
{
|
||||||
const Buffer& buf = range.first.buffer();
|
if (buffer.timestamp() == m_cache_timestamp and
|
||||||
if (m_cache_range.first.is_valid() and
|
|
||||||
&m_cache_range.first.buffer() == &buf and
|
|
||||||
buf.timestamp() == m_cache_timestamp and
|
|
||||||
range.first >= m_cache_range.first and
|
range.first >= m_cache_range.first and
|
||||||
range.second <= m_cache_range.second)
|
range.second <= m_cache_range.second)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_cache_matches.clear();
|
m_cache_matches.clear();
|
||||||
m_cache_range.first = buf.iterator_at_line_begin(range.first.line() - 10);
|
m_cache_range.first = buffer.clamp({range.first.line - 10, 0});
|
||||||
m_cache_range.second = buf.iterator_at_line_end(range.second.line() + 10);
|
m_cache_range.second = buffer.clamp({range.second.line + 10, INT_MAX});
|
||||||
m_cache_timestamp = buf.timestamp();
|
m_cache_timestamp = buffer.timestamp();
|
||||||
|
|
||||||
RegexIterator re_it(m_cache_range.first, m_cache_range.second, m_regex);
|
RegexIterator re_it{buffer.iterator_at(m_cache_range.first),
|
||||||
|
buffer.iterator_at(m_cache_range.second), m_regex};
|
||||||
RegexIterator re_end;
|
RegexIterator re_end;
|
||||||
for (; re_it != re_end; ++re_it)
|
for (; re_it != re_end; ++re_it)
|
||||||
m_cache_matches.push_back(*re_it);
|
m_cache_matches.push_back(*re_it);
|
||||||
|
@ -217,6 +215,7 @@ HighlighterAndId highlight_regex_option_factory(const HighlighterParameters para
|
||||||
void expand_tabulations(const Window& window, DisplayBuffer& display_buffer)
|
void expand_tabulations(const Window& window, DisplayBuffer& display_buffer)
|
||||||
{
|
{
|
||||||
const int tabstop = window.options()["tabstop"].get<int>();
|
const int tabstop = window.options()["tabstop"].get<int>();
|
||||||
|
auto& buffer = window.buffer();
|
||||||
for (auto& line : display_buffer.lines())
|
for (auto& line : display_buffer.lines())
|
||||||
{
|
{
|
||||||
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
||||||
|
@ -224,19 +223,19 @@ void expand_tabulations(const Window& window, DisplayBuffer& display_buffer)
|
||||||
if (atom_it->content.type() != AtomContent::BufferRange)
|
if (atom_it->content.type() != AtomContent::BufferRange)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto begin = atom_it->content.begin();
|
auto begin = buffer.iterator_at(atom_it->content.begin());
|
||||||
auto end = atom_it->content.end();
|
auto end = buffer.iterator_at(atom_it->content.end());
|
||||||
for (BufferIterator it = begin; it != end; ++it)
|
for (BufferIterator it = begin; it != end; ++it)
|
||||||
{
|
{
|
||||||
if (*it == '\t')
|
if (*it == '\t')
|
||||||
{
|
{
|
||||||
if (it != begin)
|
if (it != begin)
|
||||||
atom_it = ++line.split(atom_it, it);
|
atom_it = ++line.split(atom_it, it.coord());
|
||||||
if (it+1 != end)
|
if (it+1 != end)
|
||||||
atom_it = line.split(atom_it, it+1);
|
atom_it = line.split(atom_it, (it+1).coord());
|
||||||
|
|
||||||
int column = 0;
|
int column = 0;
|
||||||
for (auto line_it = it.buffer().iterator_at_line_begin(it);
|
for (auto line_it = buffer.iterator_at_line_begin(it);
|
||||||
line_it != it; ++line_it)
|
line_it != it; ++line_it)
|
||||||
{
|
{
|
||||||
kak_assert(*line_it != '\n');
|
kak_assert(*line_it != '\n');
|
||||||
|
@ -292,17 +291,18 @@ void highlight_selections(const Window& window, DisplayBuffer& display_buffer)
|
||||||
if (not only_cursor)
|
if (not only_cursor)
|
||||||
{
|
{
|
||||||
ColorPair sel_colors = get_color(primary ? "PrimarySelection" : "SecondarySelection");
|
ColorPair sel_colors = get_color(primary ? "PrimarySelection" : "SecondarySelection");
|
||||||
highlight_range(display_buffer, begin, end, false,
|
highlight_range(display_buffer, begin.coord(), end.coord(), false,
|
||||||
[&](DisplayAtom& atom) { atom.colors = sel_colors; });
|
[&](DisplayAtom& atom) { atom.colors = sel_colors; });
|
||||||
}
|
}
|
||||||
ColorPair cur_colors = get_color(primary ? "PrimaryCursor" : "SecondaryCursor");
|
ColorPair cur_colors = get_color(primary ? "PrimaryCursor" : "SecondaryCursor");
|
||||||
highlight_range(display_buffer, sel.last(), utf8::next(sel.last()), false,
|
highlight_range(display_buffer, sel.last().coord(), utf8::next(sel.last()).coord(), false,
|
||||||
[&](DisplayAtom& atom) { atom.colors = cur_colors; });
|
[&](DisplayAtom& atom) { atom.colors = cur_colors; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_unprintable(const Window&, DisplayBuffer& display_buffer)
|
void expand_unprintable(const Window& window, DisplayBuffer& display_buffer)
|
||||||
{
|
{
|
||||||
|
auto& buffer = window.buffer();
|
||||||
for (auto& line : display_buffer.lines())
|
for (auto& line : display_buffer.lines())
|
||||||
{
|
{
|
||||||
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
||||||
|
@ -310,7 +310,8 @@ void expand_unprintable(const Window&, DisplayBuffer& display_buffer)
|
||||||
if (atom_it->content.type() == AtomContent::BufferRange)
|
if (atom_it->content.type() == AtomContent::BufferRange)
|
||||||
{
|
{
|
||||||
using Utf8It = utf8::utf8_iterator<BufferIterator, utf8::InvalidBytePolicy::Pass>;
|
using Utf8It = utf8::utf8_iterator<BufferIterator, utf8::InvalidBytePolicy::Pass>;
|
||||||
for (Utf8It it = atom_it->content.begin(), end = atom_it->content.end(); it != end; ++it)
|
for (Utf8It it = buffer.iterator_at(atom_it->content.begin()),
|
||||||
|
end = buffer.iterator_at(atom_it->content.end()); it != end; ++it)
|
||||||
{
|
{
|
||||||
Codepoint cp = *it;
|
Codepoint cp = *it;
|
||||||
if (cp != '\n' and not std::isprint((wchar_t)cp, std::locale()))
|
if (cp != '\n' and not std::isprint((wchar_t)cp, std::locale()))
|
||||||
|
@ -318,10 +319,10 @@ void expand_unprintable(const Window&, DisplayBuffer& display_buffer)
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "U+" << std::hex << cp;
|
oss << "U+" << std::hex << cp;
|
||||||
String str = oss.str();
|
String str = oss.str();
|
||||||
if (it.underlying_iterator() != atom_it->content.begin())
|
if (it.underlying_iterator().coord() != atom_it->content.begin())
|
||||||
atom_it = ++line.split(atom_it, it.underlying_iterator());
|
atom_it = ++line.split(atom_it, it.underlying_iterator().coord());
|
||||||
if ((it+1).underlying_iterator() != atom_it->content.end())
|
if ((it+1).underlying_iterator().coord() != atom_it->content.end())
|
||||||
atom_it = line.split(atom_it, (it+1).underlying_iterator());
|
atom_it = line.split(atom_it, (it+1).underlying_iterator().coord());
|
||||||
atom_it->content.replace(str);
|
atom_it->content.replace(str);
|
||||||
atom_it->colors = { Colors::Red, Colors::Black };
|
atom_it->colors = { Colors::Red, Colors::Black };
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -76,7 +76,7 @@ void Window::update_display_buffer()
|
||||||
BufferIterator end = utf8::advance(begin, line_end, (int)m_dimensions.column);
|
BufferIterator end = utf8::advance(begin, line_end, (int)m_dimensions.column);
|
||||||
|
|
||||||
lines.push_back(DisplayLine(buffer_line));
|
lines.push_back(DisplayLine(buffer_line));
|
||||||
lines.back().push_back(DisplayAtom(AtomContent(begin, end)));
|
lines.back().push_back(DisplayAtom(AtomContent(buffer(), begin.coord(), end.coord())));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_display_buffer.compute_range();
|
m_display_buffer.compute_range();
|
||||||
|
@ -131,7 +131,7 @@ void Window::scroll_to_keep_cursor_visible_ifn()
|
||||||
|
|
||||||
BufferIterator line_begin = buffer().iterator_at_line_begin(last);
|
BufferIterator line_begin = buffer().iterator_at_line_begin(last);
|
||||||
BufferIterator line_end = buffer().iterator_at_line_end(last);
|
BufferIterator line_end = buffer().iterator_at_line_end(last);
|
||||||
lines.back().push_back(DisplayAtom(AtomContent(line_begin, line_end)));
|
lines.back().push_back(DisplayAtom(AtomContent(buffer(), line_begin.coord(), line_end.coord())));
|
||||||
|
|
||||||
display_buffer.compute_range();
|
display_buffer.compute_range();
|
||||||
m_highlighters(*this, display_buffer);
|
m_highlighters(*this, display_buffer);
|
||||||
|
@ -145,10 +145,10 @@ void Window::scroll_to_keep_cursor_visible_ifn()
|
||||||
for (auto& atom : lines.back())
|
for (auto& atom : lines.back())
|
||||||
{
|
{
|
||||||
if (atom.content.has_buffer_range() and
|
if (atom.content.has_buffer_range() and
|
||||||
atom.content.begin() <= last and atom.content.end() > last)
|
atom.content.begin() <= last.coord() and atom.content.end() > last.coord())
|
||||||
{
|
{
|
||||||
if (atom.content.type() == AtomContent::BufferRange)
|
if (atom.content.type() == AtomContent::BufferRange)
|
||||||
column += utf8::distance(atom.content.begin(), last);
|
column += utf8::distance(buffer().iterator_at(atom.content.begin()), last);
|
||||||
else
|
else
|
||||||
column += atom.content.content().char_length();
|
column += atom.content.content().char_length();
|
||||||
|
|
||||||
|
@ -187,9 +187,9 @@ DisplayCoord Window::display_position(const BufferIterator& iterator)
|
||||||
{
|
{
|
||||||
auto& content = atom.content;
|
auto& content = atom.content;
|
||||||
if (content.has_buffer_range() and
|
if (content.has_buffer_range() and
|
||||||
iterator >= content.begin() and iterator < content.end())
|
iterator.coord() >= content.begin() and iterator.coord() < content.end())
|
||||||
{
|
{
|
||||||
res.column += utf8::distance(content.begin(), iterator);
|
res.column += utf8::distance(buffer().iterator_at(content.begin()), iterator);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
res.column += content.length();
|
res.column += content.length();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user