summaryrefslogtreecommitdiff
path: root/src/buffer.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-03-16 13:48:11 +0000
committerMaxime Coste <frrrwww@gmail.com>2016-03-16 13:48:11 +0000
commitde1433d30ade30c6768cefb085ff69ef7387fa2f (patch)
treece7161d346db680e96cb80ed22928810e45655c4 /src/buffer.cc
parentc5b24e2a8a783fda939c6576158e0d9d591d632b (diff)
Avoid the spurious newline insertion when replacing at end of buffer
Add a Buffer::replace method to handle the replacements properly Fixes #633
Diffstat (limited to 'src/buffer.cc')
-rw-r--r--src/buffer.cc24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index a28b81cb..ee250aba 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -343,8 +343,9 @@ ByteCoord Buffer::do_insert(ByteCoord pos, StringView content)
return pos;
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 = line_count();
+ pos = append_lines ? line_count() : end_coord();
const StringView prefix = at_end ?
StringView{} : m_lines[pos.line].substr(0, pos.column);
@@ -369,7 +370,7 @@ ByteCoord Buffer::do_insert(ByteCoord pos, StringView content)
auto line_it = m_lines.begin() + (int)pos.line;
auto new_lines_it = new_lines.begin();
- if (not at_end)
+ if (not append_lines)
*line_it++ = std::move(*new_lines_it++);
m_lines.insert(line_it,
@@ -473,6 +474,25 @@ BufferIterator Buffer::erase(BufferIterator begin, BufferIterator end)
return {*this, do_erase(begin.coord(), end.coord())};
}
+BufferIterator Buffer::replace(const BufferIterator& begin, const BufferIterator& end, StringView content)
+{
+ if (not (m_flags & Flags::NoUndo))
+ m_current_undo_group.emplace_back(Modification::Erase, begin.coord(),
+ intern(string(begin.coord(), end.coord())));
+ auto pos = do_erase(begin.coord(), end.coord());
+
+ StringDataPtr real_content;
+ if (is_end(pos) and content.back() != '\n')
+ real_content = intern(content + "\n");
+ else
+ real_content = intern(content);
+
+ auto coord = is_end(pos) ? ByteCoord{line_count()} : pos;
+ if (not (m_flags & Flags::NoUndo))
+ m_current_undo_group.emplace_back(Modification::Insert, coord, real_content);
+ return {*this, do_insert(pos, real_content->strview())};
+}
+
bool Buffer::is_modified() const
{
size_t history_cursor_index = m_history_cursor - m_history.begin();