summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-12-05 01:43:07 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-12-05 01:43:07 +0100
commitd2bb139c46178af18ac927e242f75d748c298cac (patch)
tree4fc7585d55a4155d9a1b6ee1e16a4a196174ebb6
parentefd5aae217d2ba46569f8a89b8c98dd350163bbc (diff)
downloadserenity-d2bb139c46178af18ac927e242f75d748c298cac.zip
Support inserting a newline.
-rw-r--r--AK/OwnPtr.h2
-rw-r--r--Editor/Document.cpp26
-rw-r--r--Editor/Document.h7
-rw-r--r--Editor/Editor.cpp13
-rw-r--r--Editor/Line.cpp13
-rw-r--r--Editor/Line.h2
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: