Use a struct for BufferRange rather than std::pair

This commit is contained in:
Maxime Coste 2015-04-23 21:38:45 +01:00
parent 840e58e0b1
commit 045272ab8a
5 changed files with 87 additions and 75 deletions

View File

@ -13,11 +13,11 @@ StringView DisplayAtom::content() const
{ {
case BufferRange: case BufferRange:
{ {
auto line = (*m_buffer)[m_begin.line]; auto line = (*m_buffer)[m_range.begin.line];
if (m_begin.line == m_end.line) if (m_range.begin.line == m_range.end.line)
return line.substr(m_begin.column, m_end.column - m_begin.column); return line.substr(m_range.begin.column, m_range.end.column - m_range.begin.column);
else if (m_begin.line+1 == m_end.line and m_end.column == 0) else if (m_range.begin.line+1 == m_range.end.line and m_range.end.column == 0)
return line.substr(m_begin.column); return line.substr(m_range.begin.column);
break; break;
} }
case Text: case Text:
@ -33,8 +33,8 @@ CharCount DisplayAtom::length() const
switch (m_type) switch (m_type)
{ {
case BufferRange: case BufferRange:
return utf8::distance(m_buffer->iterator_at(m_begin), return utf8::distance(m_buffer->iterator_at(m_range.begin),
m_buffer->iterator_at(m_end)); m_buffer->iterator_at(m_range.end));
case Text: case Text:
case ReplacedBufferRange: case ReplacedBufferRange:
return m_text.char_length(); return m_text.char_length();
@ -46,8 +46,8 @@ CharCount DisplayAtom::length() const
void DisplayAtom::trim_begin(CharCount count) void DisplayAtom::trim_begin(CharCount count)
{ {
if (m_type == BufferRange) if (m_type == BufferRange)
m_begin = utf8::advance(m_buffer->iterator_at(m_begin), m_range.begin = utf8::advance(m_buffer->iterator_at(m_range.begin),
m_buffer->iterator_at(m_end), count).coord(); m_buffer->iterator_at(m_range.end), count).coord();
else else
m_text = m_text.substr(count).str(); m_text = m_text.substr(count).str();
check_invariant(); check_invariant();
@ -56,8 +56,8 @@ void DisplayAtom::trim_begin(CharCount count)
void DisplayAtom::trim_end(CharCount count) void DisplayAtom::trim_end(CharCount count)
{ {
if (m_type == BufferRange) if (m_type == BufferRange)
m_end = utf8::advance(m_buffer->iterator_at(m_end), m_range.end = utf8::advance(m_buffer->iterator_at(m_range.end),
m_buffer->iterator_at(m_begin), -count).coord(); m_buffer->iterator_at(m_range.begin), -count).coord();
else else
m_text = m_text.substr(0, m_text.char_length() - count).str(); m_text = m_text.substr(0, m_text.char_length() - count).str();
check_invariant(); check_invariant();
@ -68,8 +68,8 @@ void DisplayAtom::check_invariant() const
#ifdef KAK_DEBUG #ifdef KAK_DEBUG
if (has_buffer_range()) if (has_buffer_range())
{ {
kak_assert(m_buffer->is_valid(m_begin)); kak_assert(m_buffer->is_valid(m_range.begin));
kak_assert(m_buffer->is_valid(m_end)); kak_assert(m_buffer->is_valid(m_range.end));
} }
#endif #endif
} }
@ -87,8 +87,8 @@ DisplayLine::iterator DisplayLine::split(iterator it, ByteCoord pos)
kak_assert(it->end() > pos); kak_assert(it->end() > pos);
DisplayAtom atom = *it; DisplayAtom atom = *it;
atom.m_end = pos; atom.m_range.end = pos;
it->m_begin = pos; it->m_range.begin = pos;
atom.check_invariant(); atom.check_invariant();
it->check_invariant(); it->check_invariant();
return m_atoms.insert(it, std::move(atom)); return m_atoms.insert(it, std::move(atom));
@ -98,8 +98,8 @@ DisplayLine::iterator DisplayLine::insert(iterator it, DisplayAtom atom)
{ {
if (atom.has_buffer_range()) if (atom.has_buffer_range())
{ {
m_range.first = std::min(m_range.first, atom.begin()); m_range.begin = std::min(m_range.begin, atom.begin());
m_range.second = std::max(m_range.second, atom.end()); m_range.end = std::max(m_range.end, atom.end());
} }
return m_atoms.insert(it, std::move(atom)); return m_atoms.insert(it, std::move(atom));
} }
@ -108,8 +108,8 @@ void DisplayLine::push_back(DisplayAtom atom)
{ {
if (atom.has_buffer_range()) if (atom.has_buffer_range())
{ {
m_range.first = std::min(m_range.first, atom.begin()); m_range.begin = std::min(m_range.begin, atom.begin());
m_range.second = std::max(m_range.second, atom.end()); m_range.end = std::max(m_range.end, atom.end());
} }
m_atoms.push_back(std::move(atom)); m_atoms.push_back(std::move(atom));
} }
@ -142,7 +142,7 @@ void DisplayLine::optimize()
type == DisplayAtom::ReplacedBufferRange) and type == DisplayAtom::ReplacedBufferRange) and
next_atom.begin() == atom.end()) next_atom.begin() == atom.end())
{ {
atom.m_end = next_atom.end(); atom.m_range.end = next_atom.end();
if (type == DisplayAtom::ReplacedBufferRange) if (type == DisplayAtom::ReplacedBufferRange)
atom.m_text += next_atom.m_text; atom.m_text += next_atom.m_text;
merged = true; merged = true;
@ -211,12 +211,12 @@ void DisplayLine::compute_range()
{ {
if (not atom.has_buffer_range()) if (not atom.has_buffer_range())
continue; continue;
m_range.first = std::min(m_range.first, atom.begin()); m_range.begin = std::min(m_range.begin, atom.begin());
m_range.second = std::max(m_range.second, atom.end()); m_range.end = std::max(m_range.end, atom.end());
} }
if (m_range == init_range) if (m_range == init_range)
m_range = { { 0, 0 }, { 0, 0 } }; m_range = { { 0, 0 }, { 0, 0 } };
kak_assert(m_range.first <= m_range.second); kak_assert(m_range.begin <= m_range.end);
} }
void DisplayBuffer::compute_range() void DisplayBuffer::compute_range()
@ -224,12 +224,12 @@ void DisplayBuffer::compute_range()
m_range = init_range; m_range = init_range;
for (auto& line : m_lines) for (auto& line : m_lines)
{ {
m_range.first = std::min(line.range().first, m_range.first); m_range.begin = std::min(line.range().begin, m_range.begin);
m_range.second = std::max(line.range().second, m_range.second); m_range.end = std::max(line.range().end, m_range.end);
} }
if (m_range == init_range) if (m_range == init_range)
m_range = { { 0, 0 }, { 0, 0 } }; m_range = { { 0, 0 }, { 0, 0 } };
kak_assert(m_range.first <= m_range.second); kak_assert(m_range.begin <= m_range.end);
} }
void DisplayBuffer::optimize() void DisplayBuffer::optimize()

View File

@ -2,6 +2,7 @@
#define display_buffer_hh_INCLUDED #define display_buffer_hh_INCLUDED
#include "face.hh" #include "face.hh"
#include "hash.hh"
#include "coord.hh" #include "coord.hh"
#include "string.hh" #include "string.hh"
#include "vector.hh" #include "vector.hh"
@ -10,6 +11,18 @@ namespace Kakoune
{ {
class Buffer; class Buffer;
struct BufferRange{ ByteCoord begin, end; };
inline bool operator==(const BufferRange& lhs, const BufferRange& rhs)
{
return lhs.begin == rhs.begin and lhs.end == rhs.end;
}
inline
size_t hash_value(const BufferRange& range)
{
return hash_values(range.begin, range.end);
}
struct DisplayAtom : public UseMemoryDomain<MemoryDomain::Display> struct DisplayAtom : public UseMemoryDomain<MemoryDomain::Display>
{ {
@ -17,7 +30,7 @@ public:
enum Type { BufferRange, ReplacedBufferRange, Text }; enum Type { BufferRange, ReplacedBufferRange, Text };
DisplayAtom(const Buffer& buffer, ByteCoord begin, ByteCoord end) DisplayAtom(const Buffer& buffer, ByteCoord begin, ByteCoord end)
: m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end) : m_type(BufferRange), m_buffer(&buffer), m_range{begin, end}
{ check_invariant(); } { check_invariant(); }
DisplayAtom(String str, Face face = Face{}) DisplayAtom(String str, Face face = Face{})
@ -30,13 +43,13 @@ public:
const ByteCoord& begin() const const ByteCoord& begin() const
{ {
kak_assert(has_buffer_range()); kak_assert(has_buffer_range());
return m_begin; return m_range.begin;
} }
const ByteCoord& end() const const ByteCoord& end() const
{ {
kak_assert(has_buffer_range()); kak_assert(has_buffer_range());
return m_end; return m_range.end;
} }
void replace(String text) void replace(String text)
@ -62,7 +75,8 @@ public:
bool operator==(const DisplayAtom& other) const bool operator==(const DisplayAtom& other) const
{ {
return face == other.face and content() == other.content(); return face == other.face and type() == other.type() and
content() == other.content();
} }
public: public:
@ -74,12 +88,10 @@ private:
Type m_type; Type m_type;
const Buffer* m_buffer = nullptr; const Buffer* m_buffer = nullptr;
ByteCoord m_begin; Kakoune::BufferRange m_range;
ByteCoord m_end;
String m_text; String m_text;
}; };
using BufferRange = std::pair<ByteCoord, ByteCoord>;
using AtomList = Vector<DisplayAtom>; using AtomList = Vector<DisplayAtom>;
class DisplayLine : public UseMemoryDomain<MemoryDomain::Display> class DisplayLine : public UseMemoryDomain<MemoryDomain::Display>

View File

@ -3,6 +3,7 @@
#include "coord.hh" #include "coord.hh"
#include "completion.hh" #include "completion.hh"
#include "display_buffer.hh"
#include "exception.hh" #include "exception.hh"
#include "id_map.hh" #include "id_map.hh"
#include "array_view.hh" #include "array_view.hh"
@ -14,7 +15,6 @@
namespace Kakoune namespace Kakoune
{ {
class DisplayBuffer;
class Context; class Context;
enum class HighlightFlags enum class HighlightFlags
@ -32,7 +32,7 @@ struct Highlighter;
using HighlighterAndId = std::pair<String, std::unique_ptr<Highlighter>>; using HighlighterAndId = std::pair<String, std::unique_ptr<Highlighter>>;
using BufferRange = std::pair<ByteCoord, ByteCoord>; struct BufferRange;
struct Highlighter struct Highlighter
{ {

View File

@ -26,14 +26,14 @@ void highlight_range(DisplayBuffer& display_buffer,
ByteCoord begin, ByteCoord end, ByteCoord begin, ByteCoord 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().begin
or begin >= display_buffer.range().second) or begin >= display_buffer.range().end)
return; return;
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
auto& range = line.range(); auto& range = line.range();
if (range.second <= begin or end < range.first) if (range.end <= begin or end < range.begin)
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)
@ -82,7 +82,7 @@ void apply_highlighter(const Context& context,
{ {
auto& line = *line_it; auto& line = *line_it;
auto& range = line.range(); auto& range = line.range();
if (range.second <= begin or end <= range.first) if (range.end <= begin or end <= range.begin)
continue; continue;
if (region_lines.empty()) if (region_lines.empty())
@ -90,7 +90,7 @@ void apply_highlighter(const Context& context,
region_lines.emplace_back(); region_lines.emplace_back();
insert_pos.emplace_back(); insert_pos.emplace_back();
if (range.first < begin or range.second > end) if (range.begin < begin or range.end > end)
{ {
size_t beg_idx = 0; size_t beg_idx = 0;
size_t end_idx = line.atoms().size(); size_t end_idx = line.atoms().size();
@ -174,7 +174,7 @@ static HighlighterAndId create_fill_highlighter(HighlighterParameters params)
auto func = [=](const Context& context, HighlightFlags flags, auto func = [=](const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer, BufferRange range) DisplayBuffer& display_buffer, BufferRange range)
{ {
highlight_range(display_buffer, range.first, range.second, true, highlight_range(display_buffer, range.begin, range.end, true,
apply_face(get_face(facespec))); apply_face(get_face(facespec)));
}; };
return {"fill_" + facespec, make_simple_highlighter(std::move(func))}; return {"fill_" + facespec, make_simple_highlighter(std::move(func))};
@ -198,8 +198,8 @@ private:
static bool overlaps(const BufferRange& lhs, const BufferRange& rhs) static bool overlaps(const BufferRange& lhs, const BufferRange& rhs)
{ {
return lhs.first < rhs.first ? lhs.second > rhs.first return lhs.begin < rhs.begin ? lhs.end > rhs.begin
: rhs.second > lhs.first; : rhs.end > lhs.begin;
} }
using FacesSpec = Vector<std::pair<size_t, String>, MemoryDomain::Highlight>; using FacesSpec = Vector<std::pair<size_t, String>, MemoryDomain::Highlight>;
@ -234,7 +234,7 @@ public:
continue; continue;
highlight_range(display_buffer, highlight_range(display_buffer,
matches[m].first, matches[m].second, matches[m].begin, matches[m].end,
true, apply_face(face)); true, apply_face(face));
} }
} }
@ -315,15 +315,15 @@ private:
{ {
kak_assert(matches.size() % m_faces.size() == 0); kak_assert(matches.size() % m_faces.size() == 0);
using RegexIt = RegexIterator<BufferIterator>; using RegexIt = RegexIterator<BufferIterator>;
RegexIt re_it{buffer.iterator_at(range.first), RegexIt re_it{buffer.iterator_at(range.begin),
buffer.iterator_at(range.second), m_regex}; buffer.iterator_at(range.end), m_regex};
RegexIt re_end; RegexIt re_end;
for (; re_it != re_end; ++re_it) for (; re_it != re_end; ++re_it)
{ {
for (size_t i = 0; i < m_faces.size(); ++i) for (size_t i = 0; i < m_faces.size(); ++i)
{ {
auto& sub = (*re_it)[m_faces[i].first]; auto& sub = (*re_it)[m_faces[i].first];
matches.emplace_back(sub.first.coord(), sub.second.coord()); matches.push_back({sub.first.coord(), sub.second.coord()});
} }
} }
} }
@ -342,14 +342,14 @@ private:
cache.m_regex_version = m_regex_version; cache.m_regex_version = m_regex_version;
} }
const LineCount line_offset = 3; const LineCount line_offset = 3;
BufferRange range{std::max<ByteCoord>(buffer_range.first, display_range.first.line - line_offset), BufferRange range{std::max<ByteCoord>(buffer_range.begin, display_range.begin.line - line_offset),
std::min<ByteCoord>(buffer_range.second, display_range.second.line + line_offset)}; std::min<ByteCoord>(buffer_range.end, display_range.end.line + line_offset)};
auto it = std::upper_bound(matches.begin(), matches.end(), range, auto it = std::upper_bound(matches.begin(), matches.end(), range,
[](const BufferRange& lhs, const Cache::RangeAndMatches& rhs) [](const BufferRange& lhs, const Cache::RangeAndMatches& rhs)
{ return lhs.first < rhs.first.second; }); { return lhs.begin < rhs.first.end; });
if (it == matches.end() or it->first.first > range.second) if (it == matches.end() or it->first.begin > range.end)
{ {
it = matches.insert(it, Cache::RangeAndMatches{range, {}}); it = matches.insert(it, Cache::RangeAndMatches{range, {}});
add_matches(buffer, it->second, range); add_matches(buffer, it->second, range);
@ -370,17 +370,17 @@ private:
// Thanks to the ensure_first_face_is_capture_0 method, we know // Thanks to the ensure_first_face_is_capture_0 method, we know
// these point to the first/last matches capture 0. // these point to the first/last matches capture 0.
auto first_end = matches.begin()->second; auto first_end = matches.begin()->end;
auto last_begin = (matches.end() - m_faces.size())->first; auto last_begin = (matches.end() - m_faces.size())->begin;
bool remove_last = true; bool remove_last = true;
// add regex matches from new begin to old first match end // add regex matches from new begin to old first match end
if (range.first < old_range.first) if (range.begin < old_range.begin)
{ {
old_range.first = range.first; old_range.begin = range.begin;
MatchList new_matches; MatchList new_matches;
add_matches(buffer, new_matches, {range.first, first_end}); add_matches(buffer, new_matches, {range.begin, first_end});
matches.erase(matches.begin(), matches.begin() + m_faces.size()); matches.erase(matches.begin(), matches.begin() + m_faces.size());
// first matches was last matches as well, so // first matches was last matches as well, so
@ -393,12 +393,12 @@ private:
std::inserter(matches, matches.begin())); std::inserter(matches, matches.begin()));
} }
// add regex matches from old last match begin to new end // add regex matches from old last match begin to new end
if (old_range.second < range.second) if (old_range.end < range.end)
{ {
old_range.second = range.second; old_range.end = range.end;
if (remove_last) if (remove_last)
matches.erase(matches.end() - m_faces.size(), matches.end()); matches.erase(matches.end() - m_faces.size(), matches.end());
add_matches(buffer, matches, {last_begin, range.second}); add_matches(buffer, matches, {last_begin, range.end});
} }
} }
return it->second; return it->second;
@ -613,7 +613,7 @@ void show_line_numbers(const Context& context, HighlightFlags flags,
int main_selection = (int)context.selections().main().cursor().line + 1; int main_selection = (int)context.selections().main().cursor().line + 1;
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
const int current_line = (int)line.range().first.line + 1; const int current_line = (int)line.range().begin.line + 1;
const bool is_cursor_line = main_selection == current_line; const bool is_cursor_line = main_selection == current_line;
const int line_to_format = (relative and not is_cursor_line) ? const int line_to_format = (relative and not is_cursor_line) ?
current_line - main_selection : current_line; current_line - main_selection : current_line;
@ -659,7 +659,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
for (auto& sel : context.selections()) for (auto& sel : context.selections())
{ {
auto pos = sel.cursor(); auto pos = sel.cursor();
if (pos < range.first or pos >= range.second) if (pos < range.begin or pos >= range.end)
continue; continue;
auto c = buffer.byte_at(pos); auto c = buffer.byte_at(pos);
for (auto& pair : matching_chars) for (auto& pair : matching_chars)
@ -668,7 +668,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
if (c == pair.first) if (c == pair.first)
{ {
for (auto it = buffer.iterator_at(pos)+1, for (auto it = buffer.iterator_at(pos)+1,
end = buffer.iterator_at(range.second); it != end; ++it) end = buffer.iterator_at(range.end); it != end; ++it)
{ {
char c = *it; char c = *it;
if (c == pair.first) if (c == pair.first)
@ -681,10 +681,10 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
} }
} }
} }
else if (c == pair.second and pos > range.first) else if (c == pair.second and pos > range.begin)
{ {
for (auto it = buffer.iterator_at(pos)-1, for (auto it = buffer.iterator_at(pos)-1,
end = buffer.iterator_at(range.first); true; --it) end = buffer.iterator_at(range.begin); true; --it)
{ {
char c = *it; char c = *it;
if (c == pair.second) if (c == pair.second)
@ -793,7 +793,7 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params)
const String empty{' ', width}; const String empty{' ', width};
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
int line_num = (int)line.range().first.line + 1; int line_num = (int)line.range().begin.line + 1;
auto it = find_if(lines, auto it = find_if(lines,
[&](const LineAndFlag& l) [&](const LineAndFlag& l)
{ return std::get<0>(l) == line_num; }); { return std::get<0>(l) == line_num; });
@ -1022,9 +1022,9 @@ public:
const auto& buffer = context.buffer(); const auto& buffer = context.buffer();
auto& regions = get_regions_for_range(buffer, range); auto& regions = get_regions_for_range(buffer, range);
auto begin = std::lower_bound(regions.begin(), regions.end(), display_range.first, auto begin = std::lower_bound(regions.begin(), regions.end(), display_range.begin,
[](const Region& r, ByteCoord c) { return r.end < c; }); [](const Region& r, ByteCoord c) { return r.end < c; });
auto end = std::lower_bound(begin, regions.end(), display_range.second, auto end = std::lower_bound(begin, regions.end(), display_range.end,
[](const Region& r, ByteCoord c) { return r.begin < c; }); [](const Region& r, ByteCoord c) { return r.begin < c; });
auto correct = [&](ByteCoord c) -> ByteCoord { auto correct = [&](ByteCoord c) -> ByteCoord {
if (not buffer.is_end(c) and buffer[c.line].length() == c.column) if (not buffer.is_end(c) and buffer[c.line].length() == c.column)
@ -1052,9 +1052,9 @@ public:
it->second); it->second);
last_begin = begin->end; last_begin = begin->end;
} }
if (apply_default and last_begin < display_range.second) if (apply_default and last_begin < display_range.end)
apply_highlighter(context, flags, display_buffer, apply_highlighter(context, flags, display_buffer,
correct(last_begin), range.second, correct(last_begin), range.end,
default_group_it->second); default_group_it->second);
} }
@ -1192,7 +1192,7 @@ private:
RegionList& regions = cache.regions[range]; RegionList& regions = cache.regions[range];
for (auto begin = find_next_begin(cache, range.first), for (auto begin = find_next_begin(cache, range.begin),
end = RegionAndMatch{ 0, cache.matches[0].begin_matches.end() }; end = RegionAndMatch{ 0, cache.matches[0].begin_matches.end() };
begin != end; ) begin != end; )
{ {
@ -1201,10 +1201,10 @@ private:
auto beg_it = begin.second; auto beg_it = begin.second;
auto end_it = matches.find_matching_end(beg_it->end_coord()); auto end_it = matches.find_matching_end(beg_it->end_coord());
if (end_it == matches.end_matches.end() or end_it->end_coord() >= range.second) if (end_it == matches.end_matches.end() or end_it->end_coord() >= range.end)
{ {
regions.push_back({ {beg_it->line, beg_it->begin}, regions.push_back({ {beg_it->line, beg_it->begin},
range.second, range.end,
named_region.first }); named_region.first });
break; break;
} }

View File

@ -224,13 +224,13 @@ ByteCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
if (atom.has_buffer_range() and column < len) if (atom.has_buffer_range() and column < len)
{ {
if (atom.type() == DisplayAtom::BufferRange) if (atom.type() == DisplayAtom::BufferRange)
return utf8::advance(buffer.iterator_at(atom.begin()), buffer.iterator_at(range.second), return utf8::advance(buffer.iterator_at(atom.begin()), buffer.iterator_at(range.end),
std::max(0_char, column)).coord(); std::max(0_char, column)).coord();
return atom.begin(); return atom.begin();
} }
column -= len; column -= len;
} }
return buffer.clamp(buffer.prev(range.second)); return buffer.clamp(buffer.prev(range.end));
} }
} }
@ -240,7 +240,7 @@ CharCoord Window::display_position(ByteCoord coord) const
for (auto& line : m_display_buffer.lines()) for (auto& line : m_display_buffer.lines())
{ {
auto& range = line.range(); auto& range = line.range();
if (range.first <= coord and coord < range.second) if (range.begin <= coord and coord < range.end)
return {l, find_display_column(line, buffer(), coord)}; return {l, find_display_column(line, buffer(), coord)};
++l; ++l;
} }