Use InternedStrings for buffer contents
This commit is contained in:
parent
fc53a80395
commit
d4a84125ef
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user