diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-12-05 01:43:07 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-12-05 01:43:07 +0100 |
commit | d2bb139c46178af18ac927e242f75d748c298cac (patch) | |
tree | 4fc7585d55a4155d9a1b6ee1e16a4a196174ebb6 | |
parent | efd5aae217d2ba46569f8a89b8c98dd350163bbc (diff) | |
download | serenity-d2bb139c46178af18ac927e242f75d748c298cac.zip |
Support inserting a newline.
-rw-r--r-- | AK/OwnPtr.h | 2 | ||||
-rw-r--r-- | Editor/Document.cpp | 26 | ||||
-rw-r--r-- | Editor/Document.h | 7 | ||||
-rw-r--r-- | Editor/Editor.cpp | 13 | ||||
-rw-r--r-- | Editor/Line.cpp | 13 | ||||
-rw-r--r-- | Editor/Line.h | 2 |
6 files changed, 50 insertions, 13 deletions
diff --git a/AK/OwnPtr.h b/AK/OwnPtr.h index c6b55cdb3a..63b6a4bfb4 100644 --- a/AK/OwnPtr.h +++ b/AK/OwnPtr.h @@ -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> diff --git a/Editor/Document.cpp b/Editor/Document.cpp index 26d3b24f54..e17be061ca 100644 --- a/Editor/Document.cpp +++ b/Editor/Document.cpp @@ -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); diff --git a/Editor/Document.h b/Editor/Document.h index 9243038180..ec67584516 100644 --- a/Editor/Document.h +++ b/Editor/Document.h @@ -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; }; diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 252fc48bd0..0d66d5f88e 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -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; diff --git a/Editor/Line.cpp b/Editor/Line.cpp index 3b9624a11c..fbd6721934 100644 --- a/Editor/Line.cpp +++ b/Editor/Line.cpp @@ -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) { diff --git a/Editor/Line.h b/Editor/Line.h index 8ad7337551..dc6a19f2ba 100644 --- a/Editor/Line.h +++ b/Editor/Line.h @@ -30,6 +30,8 @@ public: void insert(size_t index, const std::string&); + std::string truncate(size_t length); + void coalesce(); private: |