Support inserting a newline.

This commit is contained in:
Andreas Kling 2018-12-05 01:43:07 +01:00
parent efd5aae217
commit d2bb139c46
Notes: sideshowbarker 2024-07-19 16:08:34 +09:00
6 changed files with 50 additions and 13 deletions

View file

@ -94,7 +94,7 @@ private:
template<class T, class... Args> inline OwnPtr<T>
make(Args&&... args)
{
return OwnPtr<T>(new T(forward<Args>(args)...));
return OwnPtr<T>(new T(AK::forward<Args>(args)...));
}
template<typename T>

View file

@ -8,7 +8,7 @@ OwnPtr<Document> Document::create_from_file(const std::string& path)
FileReader reader(path);
while (reader.can_read()) {
auto line = reader.read_line();
document->m_lines.push_back(Line(line));
document->m_lines.push_back(make<Line>(line));
}
return document;
@ -17,16 +17,32 @@ OwnPtr<Document> Document::create_from_file(const std::string& path)
void Document::dump()
{
fprintf(stderr, "Document{%p}\n", this);
for (size_t i = 0; i < m_lines.size(); ++i) {
fprintf(stderr, "[%02zu] %s\n", i, m_lines[i].data().c_str());
for (size_t i = 0; i < line_count(); ++i) {
fprintf(stderr, "[%02zu] %s\n", i, line(i).data().c_str());
}
}
bool Document::backspace_at(Position position)
bool Document::backspace_at(Position)
{
return false;
}
bool Document::newline_at(Position position)
{
ASSERT(position.is_valid());
ASSERT(position.line() < line_count());
auto& line = this->line(position.line());
if (position.column() > line.length())
return false;
if (position.column() == line.length()) {
m_lines.insert(m_lines.begin() + position.line() + 1, make<Line>(""));
return true;
}
auto chop = line.truncate(position.column());
m_lines.insert(m_lines.begin() + position.line() + 1, make<Line>(chop));
return true;
}
bool Document::insert_at(Position position, const std::string& text)
{
static FILE* f = fopen("log", "a");
@ -38,7 +54,7 @@ bool Document::insert_at(Position position, const std::string& text)
ASSERT(position.line() < line_count());
if (position.line() >= line_count())
return false;
Line& line = m_lines[position.line()];
auto& line = this->line(position.line());
if (position.column() > line.length())
return false;
line.insert(position.column(), text);

View file

@ -11,17 +11,18 @@ public:
Document() { }
~Document() { }
const std::deque<Line>& lines() const { return m_lines; }
std::deque<Line>& lines() { return m_lines; }
Line& line(size_t index) { return *m_lines[index]; }
const Line& line(size_t index) const { return *m_lines[index]; }
size_t line_count() const { return m_lines.size(); }
static OwnPtr<Document> create_from_file(const std::string& path);
bool insert_at(Position, const std::string&);
bool newline_at(Position);
bool backspace_at(Position);
void dump();
private:
std::deque<Line> m_lines;
std::deque<OwnPtr<Line>> m_lines;
};

View file

@ -66,8 +66,8 @@ void Editor::redraw()
printw("%3d ", current_document_line);
attroff(ruler_attributes);
m_ruler_width = 4;
size_t line_length = m_document->lines()[current_document_line].data().size();
const char* line_data = m_document->lines()[current_document_line].data().c_str();
size_t line_length = m_document->line(current_document_line).data().size();
const char* line_data = m_document->line(current_document_line).data().c_str();
if (m_scroll_position.column() < line_length)
addnstr(line_data + m_scroll_position.column(), window_width - m_ruler_width);
}
@ -182,7 +182,7 @@ void Editor::move_down()
void Editor::coalesce_current_line()
{
m_document->lines()[m_cursor.line()].coalesce();
m_document->line(m_cursor.line()).coalesce();
}
void Editor::move_up()
@ -212,7 +212,7 @@ size_t Editor::max_line() const
size_t Editor::max_column() const
{
return m_document->lines()[m_cursor.line()].data().size();
return m_document->line(m_cursor.line()).data().size();
}
void Editor::update_scroll_position_if_needed()
@ -307,6 +307,11 @@ void Editor::insert_at_cursor(int ch)
bool Editor::insert_text_at_cursor(const std::string& text)
{
ASSERT(text.size() == 1);
if (text[0] == '\n') {
m_document->newline_at(m_cursor);
m_cursor.move_to(m_cursor.line() + 1, 0);
return true;
}
m_document->insert_at(m_cursor, text);
m_cursor.move_by(0, text.size());
return true;

View file

@ -41,6 +41,19 @@ void Line::prepend(const std::string& text)
m_chunks.push_front(Chunk(text));
}
std::string Line::truncate(size_t length)
{
coalesce();
auto remainder = data().substr(0, length);
auto chop = data().substr(length, data().length() - length);
m_chunks.clear();
m_chunks.push_back(Chunk{ remainder });
return chop;
}
void Line::insert(size_t index, const std::string& text)
{
if (index == 0) {

View file

@ -30,6 +30,8 @@ public:
void insert(size_t index, const std::string&);
std::string truncate(size_t length);
void coalesce();
private: