summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-06-11 12:01:40 +0100
committerMaxime Coste <mawww@kakoune.org>2017-06-11 12:01:40 +0100
commit63a791d65118bf37606db36ee12287e890d528ea (patch)
tree3812cb83f684486484b7ab099d768e98e7fca982 /src
parentb4647a16dda162c78fd7628f1ebb7325e95ba38c (diff)
Fix the Buffer::end() madness
Until now, buffer had multiple recognized end coordinates, either { line_count, 0 } or { line_count - 1, line[line_count - 1].length }. Now the only correct end coord is { line_count, 0 }, removing the need for various special cases.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.cc49
-rw-r--r--src/buffer.hh5
-rw-r--r--src/buffer.inl.hh19
-rw-r--r--src/line_modification.cc15
-rw-r--r--src/selection.cc8
5 files changed, 30 insertions, 66 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index 1a92b8da..dc0dd93b 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -88,7 +88,7 @@ Buffer::Buffer(String name, Flags flags, StringView data,
#endif
static_cast<BufferLines&>(m_lines) = std::move(parsed_lines.lines);
- m_changes.push_back({ Change::Insert, true, {0,0}, line_count() });
+ m_changes.push_back({ Change::Insert, {0,0}, line_count() });
apply_options(options(), parsed_lines);
@@ -241,11 +241,11 @@ void Buffer::reload(StringView data, timespec fs_timestamp)
if (not record_undo)
{
- m_changes.push_back({ Change::Erase, true, {0,0}, line_count() });
+ m_changes.push_back({ Change::Erase, {0,0}, line_count() });
static_cast<BufferLines&>(m_lines) = std::move(parsed_lines.lines);
- m_changes.push_back({ Change::Insert, true, {0,0}, line_count() });
+ m_changes.push_back({ Change::Insert, {0,0}, line_count() });
}
else
{
@@ -268,7 +268,7 @@ void Buffer::reload(StringView data, timespec fs_timestamp)
Modification::Insert, cur_line + line,
parsed_lines.lines[(int)(d.posB + line)]);
- m_changes.push_back({ Change::Insert, it == m_lines.end(), cur_line, cur_line + d.len });
+ m_changes.push_back({ Change::Insert, cur_line, cur_line + d.len });
m_lines.insert(it, &parsed_lines.lines[d.posB], &parsed_lines.lines[d.posB + d.len]);
it = m_lines.begin() + (int)(cur_line + d.len);
}
@@ -282,7 +282,7 @@ void Buffer::reload(StringView data, timespec fs_timestamp)
m_lines.get_storage(cur_line + line));
it = m_lines.erase(it, it + d.len);
- m_changes.push_back({ Change::Erase, it == m_lines.end(), cur_line, cur_line + d.len });
+ m_changes.push_back({ Change::Erase, cur_line, cur_line + d.len });
}
}
}
@@ -453,8 +453,6 @@ BufferCoord Buffer::do_insert(BufferCoord pos, StringView content)
const bool at_end = is_end(pos);
const bool append_lines = at_end and (m_lines.empty() or byte_at(back_coord()) == '\n');
- if (at_end)
- pos = append_lines ? line_count() : end_coord();
const StringView prefix = append_lines ?
StringView{} : m_lines[pos.line].substr(0, pos.column);
@@ -490,7 +488,7 @@ BufferCoord Buffer::do_insert(BufferCoord pos, StringView content)
const auto end = at_end ? line_count()
: BufferCoord{ last_line, m_lines[last_line].length() - suffix.length() };
- m_changes.push_back({ Change::Insert, at_end, pos, end });
+ m_changes.push_back({ Change::Insert, pos, end });
return pos;
}
@@ -502,7 +500,7 @@ BufferCoord Buffer::do_erase(BufferCoord begin, BufferCoord end)
kak_assert(is_valid(begin));
kak_assert(is_valid(end));
StringView prefix = m_lines[begin.line].substr(0, begin.column);
- StringView suffix = m_lines[end.line].substr(end.column);
+ StringView suffix = end.line == line_count() ? StringView{} : m_lines[end.line].substr(end.column);
BufferCoord next;
if (not prefix.empty() or not suffix.empty())
@@ -514,11 +512,11 @@ BufferCoord Buffer::do_erase(BufferCoord begin, BufferCoord end)
}
else
{
- m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line + 1);
- next = is_end(begin) ? end_coord() : BufferCoord{begin.line, 0};
+ m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line);
+ next = begin.line;
}
- m_changes.push_back({ Change::Erase, is_end(begin), begin, end });
+ m_changes.push_back({ Change::Erase, begin, end });
return next;
}
@@ -584,24 +582,11 @@ BufferCoord Buffer::erase(BufferCoord begin, BufferCoord end)
BufferCoord Buffer::replace(BufferCoord begin, BufferCoord end, StringView content)
{
- if (not (m_flags & Flags::NoUndo))
- m_current_undo_group.emplace_back(Modification::Erase, begin,
- intern(string(begin, end)));
- auto pos = do_erase(begin, end);
+ if (is_end(end) and not content.empty() and content.back() == '\n')
+ content = content.substr(0, content.length() - 1);
- StringDataPtr real_content;
- if (is_end(pos) and content.back() != '\n')
- real_content = intern(content + "\n");
- else
- real_content = intern(content);
-
- bool last_char_is_eol = not (m_lines.empty() or
- m_lines.back().empty() or
- m_lines.back().back() != '\n');
- auto coord = is_end(pos) and last_char_is_eol ? line_count() : pos;
- if (not (m_flags & Flags::NoUndo))
- m_current_undo_group.emplace_back(Modification::Insert, coord, real_content);
- return do_insert(pos, real_content->strview());
+ auto pos = erase(begin, end);
+ return insert(pos, content);
}
bool Buffer::is_modified() const
@@ -662,8 +647,6 @@ BufferCoord Buffer::char_next(BufferCoord coord) const
coord.column = 0;
}
}
- else if (coord.line == m_lines.size() - 1)
- coord.column = m_lines.back().length();
else
{
++coord.line;
@@ -675,9 +658,7 @@ BufferCoord Buffer::char_next(BufferCoord coord) const
BufferCoord Buffer::char_prev(BufferCoord coord) const
{
kak_assert(is_valid(coord));
- if (is_end(coord))
- return {(int)m_lines.size()-1, m_lines.back().length() - 1};
- else if (coord.column == 0)
+ if (coord.column == 0)
{
if (coord.line > 0)
coord.column = m_lines[--coord.line].length() - 1;
diff --git a/src/buffer.hh b/src/buffer.hh
index d0fdffcb..d2679ba1 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -89,9 +89,9 @@ public:
private:
SafePtr<const Buffer> m_buffer;
- StringView m_line;
BufferCoord m_coord;
- LineCount m_last_line;
+ LineCount m_line_count;
+ StringView m_line;
};
using BufferLines = Vector<StringDataPtr, MemoryDomain::BufferContent>;
@@ -205,7 +205,6 @@ public:
{
enum Type : char { Insert, Erase };
Type type;
- bool at_end;
BufferCoord begin;
BufferCoord end;
};
diff --git a/src/buffer.inl.hh b/src/buffer.inl.hh
index 7d987c26..5904b9ff 100644
--- a/src/buffer.inl.hh
+++ b/src/buffer.inl.hh
@@ -17,8 +17,6 @@ inline BufferCoord Buffer::next(BufferCoord coord) const
{
if (coord.column < m_lines[coord.line].length() - 1)
++coord.column;
- else if (coord.line == m_lines.size() - 1)
- coord.column = m_lines.back().length();
else
{
++coord.line;
@@ -59,7 +57,6 @@ inline bool Buffer::is_valid(BufferCoord c) const
return false;
return (c.line < line_count() and c.column < m_lines[c.line].length()) or
- (c.line == line_count() - 1 and c.column == m_lines.back().length()) or
(c.line == line_count() and c.column == 0);
}
@@ -110,14 +107,13 @@ inline BufferCoord Buffer::back_coord() const
inline BufferCoord Buffer::end_coord() const
{
- return m_lines.empty() ?
- BufferCoord{0,0} : BufferCoord{ line_count() - 1, m_lines.back().length() };
+ return line_count();
}
inline BufferIterator::BufferIterator(const Buffer& buffer, BufferCoord coord) noexcept
- : m_buffer(&buffer), m_coord(coord),
- m_line((*m_buffer)[coord.line]),
- m_last_line(buffer.line_count()-1) {}
+ : m_buffer{&buffer}, m_coord{coord},
+ m_line_count{buffer.line_count()},
+ m_line{coord.line < buffer.line_count() ? (*m_buffer)[coord.line] : StringView{}} {}
inline bool BufferIterator::operator==(const BufferIterator& iterator) const noexcept
{
@@ -197,9 +193,10 @@ inline BufferIterator& BufferIterator::operator-=(ByteCount size)
inline BufferIterator& BufferIterator::operator++()
{
- if (++m_coord.column == m_line.length() and m_coord.line != m_last_line)
+ if (++m_coord.column == m_line.length())
{
- m_line = (*m_buffer)[++m_coord.line];
+ m_line = (++m_coord.line < m_line_count) ?
+ (*m_buffer)[m_coord.line] : StringView{};
m_coord.column = 0;
}
return *this;
@@ -207,7 +204,7 @@ inline BufferIterator& BufferIterator::operator++()
inline BufferIterator& BufferIterator::operator--()
{
- if (m_coord.column == 0 and m_coord.line > 0)
+ if (m_coord.column == 0)
{
m_line = (*m_buffer)[--m_coord.line];
m_coord.column = m_line.length() - 1;
diff --git a/src/line_modification.cc b/src/line_modification.cc
index 3d6617dd..df2b9cbc 100644
--- a/src/line_modification.cc
+++ b/src/line_modification.cc
@@ -10,22 +10,11 @@ static LineModification make_line_modif(const Buffer::Change& change)
{
LineCount num_added = 0, num_removed = 0;
if (change.type == Buffer::Change::Insert)
- {
num_added = change.end.line - change.begin.line;
- // inserted a new line at buffer end but end coord is on same line
- if (change.at_end and change.end.column != 0)
- ++num_added;
- }
else
- {
num_removed = change.end.line - change.begin.line;
- // removed last line, but end coord is on same line
- if (change.at_end and change.end.column != 0)
- ++num_removed;
- }
// modified a line
- if (not change.at_end and
- (change.begin.column != 0 or change.end.column != 0))
+ if ((change.begin.column != 0 or change.end.column != 0))
{
++num_removed;
++num_added;
@@ -116,7 +105,7 @@ UnitTest test_line_modifications{[]()
{
Buffer buffer("test", Buffer::Flags::None, "line 1\nline 2\n");
auto ts = buffer.timestamp();
- buffer.insert({1, 7}, "line 3");
+ buffer.insert({2, 0}, "line 3");
auto modifs = compute_line_modifications(buffer, ts);
kak_assert(modifs.size() == 1 and modifs[0] == LineModification{ 2, 2, 0, 1 });
diff --git a/src/selection.cc b/src/selection.cc
index 05095dfa..4724e896 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -448,17 +448,15 @@ void SelectionList::erase()
kak_assert(m_buffer->is_valid(sel.cursor()));
auto pos = Kakoune::erase(*m_buffer, sel);
- sel.anchor() = sel.cursor() = m_buffer->clamp(pos);
+ sel.anchor() = sel.cursor() = pos;
changes_tracker.update(*m_buffer, m_timestamp);
}
BufferCoord back_coord = m_buffer->back_coord();
for (auto& sel : m_selections)
{
- if (sel.anchor() > back_coord)
- sel.anchor() = back_coord;
- if (sel.cursor() > back_coord)
- sel.cursor() = back_coord;
+ auto pos = m_buffer->clamp(sel.cursor());
+ sel.anchor() = sel.cursor() = std::min(pos, back_coord);
}
m_buffer->check_invariant();