mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:47:45 +00:00
Support inserting a newline.
This commit is contained in:
parent
efd5aae217
commit
d2bb139c46
6 changed files with 50 additions and 13 deletions
|
@ -94,7 +94,7 @@ private:
|
||||||
template<class T, class... Args> inline OwnPtr<T>
|
template<class T, class... Args> inline OwnPtr<T>
|
||||||
make(Args&&... args)
|
make(Args&&... args)
|
||||||
{
|
{
|
||||||
return OwnPtr<T>(new T(forward<Args>(args)...));
|
return OwnPtr<T>(new T(AK::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -8,7 +8,7 @@ OwnPtr<Document> Document::create_from_file(const std::string& path)
|
||||||
FileReader reader(path);
|
FileReader reader(path);
|
||||||
while (reader.can_read()) {
|
while (reader.can_read()) {
|
||||||
auto line = reader.read_line();
|
auto line = reader.read_line();
|
||||||
document->m_lines.push_back(Line(line));
|
document->m_lines.push_back(make<Line>(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
|
@ -17,16 +17,32 @@ OwnPtr<Document> Document::create_from_file(const std::string& path)
|
||||||
void Document::dump()
|
void Document::dump()
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Document{%p}\n", this);
|
fprintf(stderr, "Document{%p}\n", this);
|
||||||
for (size_t i = 0; i < m_lines.size(); ++i) {
|
for (size_t i = 0; i < line_count(); ++i) {
|
||||||
fprintf(stderr, "[%02zu] %s\n", i, m_lines[i].data().c_str());
|
fprintf(stderr, "[%02zu] %s\n", i, line(i).data().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Document::backspace_at(Position position)
|
bool Document::backspace_at(Position)
|
||||||
{
|
{
|
||||||
return false;
|
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)
|
bool Document::insert_at(Position position, const std::string& text)
|
||||||
{
|
{
|
||||||
static FILE* f = fopen("log", "a");
|
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());
|
ASSERT(position.line() < line_count());
|
||||||
if (position.line() >= line_count())
|
if (position.line() >= line_count())
|
||||||
return false;
|
return false;
|
||||||
Line& line = m_lines[position.line()];
|
auto& line = this->line(position.line());
|
||||||
if (position.column() > line.length())
|
if (position.column() > line.length())
|
||||||
return false;
|
return false;
|
||||||
line.insert(position.column(), text);
|
line.insert(position.column(), text);
|
||||||
|
|
|
@ -11,17 +11,18 @@ public:
|
||||||
Document() { }
|
Document() { }
|
||||||
~Document() { }
|
~Document() { }
|
||||||
|
|
||||||
const std::deque<Line>& lines() const { return m_lines; }
|
Line& line(size_t index) { return *m_lines[index]; }
|
||||||
std::deque<Line>& lines() { return m_lines; }
|
const Line& line(size_t index) const { return *m_lines[index]; }
|
||||||
size_t line_count() const { return m_lines.size(); }
|
size_t line_count() const { return m_lines.size(); }
|
||||||
|
|
||||||
static OwnPtr<Document> create_from_file(const std::string& path);
|
static OwnPtr<Document> create_from_file(const std::string& path);
|
||||||
|
|
||||||
bool insert_at(Position, const std::string&);
|
bool insert_at(Position, const std::string&);
|
||||||
|
bool newline_at(Position);
|
||||||
bool backspace_at(Position);
|
bool backspace_at(Position);
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<Line> m_lines;
|
std::deque<OwnPtr<Line>> m_lines;
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,8 +66,8 @@ void Editor::redraw()
|
||||||
printw("%3d ", current_document_line);
|
printw("%3d ", current_document_line);
|
||||||
attroff(ruler_attributes);
|
attroff(ruler_attributes);
|
||||||
m_ruler_width = 4;
|
m_ruler_width = 4;
|
||||||
size_t line_length = m_document->lines()[current_document_line].data().size();
|
size_t line_length = m_document->line(current_document_line).data().size();
|
||||||
const char* line_data = m_document->lines()[current_document_line].data().c_str();
|
const char* line_data = m_document->line(current_document_line).data().c_str();
|
||||||
if (m_scroll_position.column() < line_length)
|
if (m_scroll_position.column() < line_length)
|
||||||
addnstr(line_data + m_scroll_position.column(), window_width - m_ruler_width);
|
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()
|
void Editor::coalesce_current_line()
|
||||||
{
|
{
|
||||||
m_document->lines()[m_cursor.line()].coalesce();
|
m_document->line(m_cursor.line()).coalesce();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::move_up()
|
void Editor::move_up()
|
||||||
|
@ -212,7 +212,7 @@ size_t Editor::max_line() const
|
||||||
|
|
||||||
size_t Editor::max_column() 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()
|
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)
|
bool Editor::insert_text_at_cursor(const std::string& text)
|
||||||
{
|
{
|
||||||
ASSERT(text.size() == 1);
|
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_document->insert_at(m_cursor, text);
|
||||||
m_cursor.move_by(0, text.size());
|
m_cursor.move_by(0, text.size());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -41,6 +41,19 @@ void Line::prepend(const std::string& text)
|
||||||
m_chunks.push_front(Chunk(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)
|
void Line::insert(size_t index, const std::string& text)
|
||||||
{
|
{
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
|
|
|
@ -30,6 +30,8 @@ public:
|
||||||
|
|
||||||
void insert(size_t index, const std::string&);
|
void insert(size_t index, const std::string&);
|
||||||
|
|
||||||
|
std::string truncate(size_t length);
|
||||||
|
|
||||||
void coalesce();
|
void coalesce();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue