Use InternedStrings for buffer contents

This commit is contained in:
Maxime Coste 2014-10-03 13:39:13 +01:00
parent fc53a80395
commit d4a84125ef
9 changed files with 40 additions and 40 deletions

View File

@ -273,31 +273,28 @@ ByteCoord Buffer::do_insert(ByteCoord pos, StringView content)
} }
else else
{ {
String prefix = m_lines[pos.line].substr(0, pos.column); StringView prefix = m_lines[pos.line].substr(0, pos.column);
String suffix = m_lines[pos.line].substr(pos.column); StringView suffix = m_lines[pos.line].substr(pos.column);
std::vector<String> new_lines; std::vector<InternedString> new_lines;
ByteCount start = 0; ByteCount start = 0;
for (ByteCount i = 0; i < content.length(); ++i) for (ByteCount i = 0; i < content.length(); ++i)
{ {
if (content[i] == '\n') if (content[i] == '\n')
{ {
String line_content = content.substr(start, i + 1 - start); StringView line_content = content.substr(start, i + 1 - start);
if (start == 0) if (start == 0)
{ new_lines.emplace_back(prefix + line_content);
line_content = prefix + line_content;
new_lines.push_back(std::move(line_content));
}
else else
new_lines.push_back(std::move(line_content)); new_lines.push_back(line_content);
start = i + 1; start = i + 1;
} }
} }
if (start == 0) if (start == 0)
new_lines.push_back(prefix + content + suffix); new_lines.emplace_back(prefix + content + suffix);
else if (start != content.length() or not suffix.empty()) else if (start != content.length() or not suffix.empty())
new_lines.push_back(content.substr(start) + suffix); new_lines.emplace_back(content.substr(start) + suffix);
LineCount last_line = pos.line + new_lines.size() - 1; LineCount last_line = pos.line + new_lines.size() - 1;
@ -327,7 +324,7 @@ ByteCoord Buffer::do_erase(ByteCoord begin, ByteCoord end)
if (new_line.length() != 0) if (new_line.length() != 0)
{ {
m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line); m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line);
m_lines[begin.line] = std::move(new_line); m_lines[begin.line] = InternedString(new_line);
next = begin; next = begin;
} }
else else
@ -368,21 +365,24 @@ void Buffer::apply_modification(const Modification& modification)
} }
} }
BufferIterator Buffer::insert(const BufferIterator& pos, String content) BufferIterator Buffer::insert(const BufferIterator& pos, StringView content)
{ {
kak_assert(is_valid(pos.coord())); kak_assert(is_valid(pos.coord()));
if (content.empty()) if (content.empty())
return pos; return pos;
InternedString real_content;
if (pos == end() and content.back() != '\n') if (pos == end() and content.back() != '\n')
content += '\n'; real_content = InternedString(content + "\n");
else
real_content = content;
// for undo and redo purpose it is better to use one past last line rather // for undo and redo purpose it is better to use one past last line rather
// than one past last char coord. // than one past last char coord.
auto coord = pos == end() ? ByteCoord{line_count()} : pos.coord(); auto coord = pos == end() ? ByteCoord{line_count()} : pos.coord();
if (not (m_flags & Flags::NoUndo)) if (not (m_flags & Flags::NoUndo))
m_current_undo_group.emplace_back(Modification::Insert, coord, content); m_current_undo_group.emplace_back(Modification::Insert, coord, real_content);
return {*this, do_insert(pos.coord(), content)}; return {*this, do_insert(pos.coord(), real_content)};
} }
BufferIterator Buffer::erase(BufferIterator begin, BufferIterator end) BufferIterator Buffer::erase(BufferIterator begin, BufferIterator end)
@ -396,7 +396,7 @@ BufferIterator Buffer::erase(BufferIterator begin, BufferIterator end)
if (not (m_flags & Flags::NoUndo)) if (not (m_flags & Flags::NoUndo))
m_current_undo_group.emplace_back(Modification::Erase, begin.coord(), m_current_undo_group.emplace_back(Modification::Erase, begin.coord(),
string(begin.coord(), end.coord())); InternedString(string(begin.coord(), end.coord())));
return {*this, do_erase(begin.coord(), end.coord())}; return {*this, do_erase(begin.coord(), end.coord())};
} }
@ -452,7 +452,7 @@ ByteCoord Buffer::char_next(ByteCoord coord) const
{ {
if (coord.column < m_lines[coord.line].length() - 1) if (coord.column < m_lines[coord.line].length() - 1)
{ {
auto& line = m_lines[coord.line]; auto line = m_lines[coord.line];
coord.column += utf8::codepoint_size(line[(int)coord.column]); coord.column += utf8::codepoint_size(line[(int)coord.column]);
// Handle invalid utf-8 // Handle invalid utf-8
if (coord.column >= line.length()) if (coord.column >= line.length())
@ -483,7 +483,7 @@ ByteCoord Buffer::char_prev(ByteCoord coord) const
} }
else else
{ {
auto& line = m_lines[coord.line]; auto line = m_lines[coord.line];
coord.column = (int)(utf8::character_start(line.begin() + (int)coord.column - 1, line.begin()) - line.begin()); coord.column = (int)(utf8::character_start(line.begin() + (int)coord.column - 1, line.begin()) - line.begin());
} }
return coord; return coord;

View File

@ -6,7 +6,7 @@
#include "option_manager.hh" #include "option_manager.hh"
#include "keymap_manager.hh" #include "keymap_manager.hh"
#include "safe_ptr.hh" #include "safe_ptr.hh"
#include "string.hh" #include "interned_string.hh"
#include "value.hh" #include "value.hh"
#include <vector> #include <vector>
@ -92,7 +92,7 @@ public:
bool set_name(String name); bool set_name(String name);
BufferIterator insert(const BufferIterator& pos, String content); BufferIterator insert(const BufferIterator& pos, StringView content);
BufferIterator erase(BufferIterator begin, BufferIterator end); BufferIterator erase(BufferIterator begin, BufferIterator end);
size_t timestamp() const; size_t timestamp() const;
@ -126,7 +126,7 @@ public:
BufferIterator end() const; BufferIterator end() const;
LineCount line_count() const; LineCount line_count() const;
const String& operator[](LineCount line) const const StringView& operator[](LineCount line) const
{ return m_lines[line]; } { return m_lines[line]; }
// returns an iterator at given coordinates. clamp line_and_column // returns an iterator at given coordinates. clamp line_and_column
@ -178,15 +178,15 @@ private:
void on_option_changed(const Option& option) override; void on_option_changed(const Option& option) override;
struct LineList : std::vector<String> struct LineList : std::vector<InternedString>
{ {
[[gnu::always_inline]] [[gnu::always_inline]]
String& operator[](LineCount line) InternedString& operator[](LineCount line)
{ return std::vector<String>::operator[]((int)line); } { return std::vector<InternedString>::operator[]((int)line); }
[[gnu::always_inline]] [[gnu::always_inline]]
const String& operator[](LineCount line) const const InternedString& operator[](LineCount line) const
{ return std::vector<String>::operator[]((int)line); } { return std::vector<InternedString>::operator[]((int)line); }
}; };
LineList m_lines; LineList m_lines;

View File

@ -11,7 +11,7 @@ namespace Kakoune
CharCount get_column(const Buffer& buffer, CharCount get_column(const Buffer& buffer,
CharCount tabstop, ByteCoord coord) CharCount tabstop, ByteCoord coord)
{ {
auto& line = buffer[coord.line]; auto line = buffer[coord.line];
auto col = 0_char; auto col = 0_char;
for (auto it = line.begin(); for (auto it = line.begin();
it != line.end() and coord.column > (int)(it - line.begin()); it != line.end() and coord.column > (int)(it - line.begin());

View File

@ -31,7 +31,7 @@ public:
{ {
case BufferRange: case BufferRange:
{ {
auto& line = (*m_buffer)[m_begin.line]; auto line = (*m_buffer)[m_begin.line];
if (m_begin.line == m_end.line) if (m_begin.line == m_end.line)
return line.substr(m_begin.column, m_end.column - m_begin.column); return line.substr(m_begin.column, m_end.column - m_begin.column);
else if (m_begin.line+1 == m_end.line and m_end.column == 0) else if (m_begin.line+1 == m_end.line and m_end.column == 0)

View File

@ -724,8 +724,8 @@ void find_matches(const Buffer& buffer, RegexMatchList& matches, const Regex& re
const size_t buf_timestamp = buffer.timestamp(); const size_t buf_timestamp = buffer.timestamp();
for (auto line = 0_line, end = buffer.line_count(); line < end; ++line) for (auto line = 0_line, end = buffer.line_count(); line < end; ++line)
{ {
auto& l = buffer[line]; auto l = buffer[line];
for (boost::regex_iterator<String::const_iterator> it{l.begin(), l.end(), regex}, end{}; it != end; ++it) for (boost::regex_iterator<const char*> it{l.begin(), l.end(), regex}, end{}; it != end; ++it)
{ {
ByteCount b = (int)((*it)[0].first - l.begin()); ByteCount b = (int)((*it)[0].first - l.begin());
ByteCount e = (int)((*it)[0].second - l.begin()); ByteCount e = (int)((*it)[0].second - l.begin());
@ -778,8 +778,8 @@ void update_matches(const Buffer& buffer, memoryview<LineModification> modifs,
line < modif.new_line + modif.num_added+1 and line < modif.new_line + modif.num_added+1 and
line < buffer.line_count(); ++line) line < buffer.line_count(); ++line)
{ {
auto& l = buffer[line]; auto l = buffer[line];
for (boost::regex_iterator<String::const_iterator> it{l.begin(), l.end(), regex}, end{}; it != end; ++it) for (boost::regex_iterator<const char*> it{l.begin(), l.end(), regex}, end{}; it != end; ++it)
{ {
ByteCount b = (int)((*it)[0].first - l.begin()); ByteCount b = (int)((*it)[0].first - l.begin());
ByteCount e = (int)((*it)[0].second - l.begin()); ByteCount e = (int)((*it)[0].second - l.begin());

View File

@ -39,7 +39,7 @@ public:
InternedString(const char* str) : StringView() { acquire_ifn(str); } InternedString(const char* str) : StringView() { acquire_ifn(str); }
InternedString(StringView str) : StringView() { acquire_ifn(str); } InternedString(StringView str) : StringView() { acquire_ifn(str); }
InternedString(const String& str) : StringView() { acquire_ifn(str); } //InternedString(const String& str) : StringView() { acquire_ifn(str); }
InternedString& operator=(const InternedString& str) InternedString& operator=(const InternedString& str)
{ {

View File

@ -804,7 +804,7 @@ void deindent(Context& context, int)
for (auto line = sel.min().line; line < sel.max().line+1; ++line) for (auto line = sel.min().line; line < sel.max().line+1; ++line)
{ {
CharCount width = 0; CharCount width = 0;
auto& content = buffer[line]; auto content = buffer[line];
for (auto column = 0_byte; column < content.length(); ++column) for (auto column = 0_byte; column < content.length(); ++column)
{ {
const char c = content[column]; const char c = content[column];
@ -1105,7 +1105,7 @@ void copy_indent(Context& context, int selection)
selection = context.selections().main_index() + 1; selection = context.selections().main_index() + 1;
auto ref_line = selections[selection-1].min().line; auto ref_line = selections[selection-1].min().line;
const String& line = buffer[ref_line]; auto line = buffer[ref_line];
auto it = line.begin(); auto it = line.begin();
while (it != line.end() and is_horizontal_blank(*it)) while (it != line.end() and is_horizontal_blank(*it))
++it; ++it;
@ -1117,7 +1117,7 @@ void copy_indent(Context& context, int selection)
if (l == ref_line) if (l == ref_line)
continue; continue;
auto& line = buffer[l]; auto line = buffer[l];
ByteCount i = 0; ByteCount i = 0;
while (i < line.length() and is_horizontal_blank(line[i])) while (i < line.length() and is_horizontal_blank(line[i]))
++i; ++i;

View File

@ -35,7 +35,7 @@ class Message
{ {
public: public:
Message(int sock) : m_socket(sock) {} Message(int sock) : m_socket(sock) {}
~Message() ~Message() noexcept(false)
{ {
if (m_stream.size() == 0) if (m_stream.size() == 0)
return; return;

View File

@ -410,8 +410,8 @@ namespace
inline void _avoid_eol(const Buffer& buffer, ByteCoord& coord) inline void _avoid_eol(const Buffer& buffer, ByteCoord& coord)
{ {
const auto column = coord.column; auto column = coord.column;
const auto& line = buffer[coord.line]; auto line = buffer[coord.line];
if (column != 0 and column == line.length() - 1) if (column != 0 and column == line.length() - 1)
coord.column = line.byte_count_to(line.char_length() - 2); coord.column = line.byte_count_to(line.char_length() - 2);
} }