diff --git a/main.cpp b/main.cpp index 71a702f..623e8a1 100644 --- a/main.cpp +++ b/main.cpp @@ -3,20 +3,22 @@ #include int main(int argc, char* argv[]) { - groove::Editor editor; + std::unique_ptr editor; + if (argc > 1) - editor = groove::Editor(argv[1]); + editor = std::make_unique(argv[1]); else - editor = groove::Editor(); + editor = std::make_unique(); + groove::ncurses::ncurses curses; curses.init(); curses.flush(); - while(editor.mode() != groove::Mode::QUIT) + while(editor->mode() != groove::Mode::QUIT) { - editor.render(); + editor->render(); int input = getch(); // Blocking until input - editor.input(input); + editor->input(input); } curses.quit(); diff --git a/src/Editor.cpp b/src/Editor.cpp index a76652f..c0ce8b2 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -6,9 +6,10 @@ namespace groove { - Editor::Editor(std::string filename) : x(0), y(0), buffer(std::make_unique()), - mode_(Mode::EDIT), filename(filename), offset(0) { - + Editor::Editor(std::string filename) : x(0), y(0), + buffer(std::make_unique()), mode_(Mode::EDIT), + filename(filename), offset(0) { + this->modes.emplace(Mode::INSERT, std::make_unique(*this)); if (!this->load()) { std::cerr << "Could not open file: '" << this->filename << "', creating it on save.\n"; this->buffer->insert(""); @@ -16,6 +17,11 @@ namespace groove { } bool Editor::load() { + if (this->filename == "") { + this->filename = "unbenannt"; + + return false; + } std::ifstream file(this->filename.c_str()); if(file.is_open()) { while(!file.eof()) { @@ -93,89 +99,7 @@ namespace groove { } break; case Mode::INSERT: - switch (car) { - case 27: - this->mode_ = Mode::EDIT; - break; - case KEY_ENTER: - case 10: - { - std::string appendix; - appendix = ""; - if (this->buffer->at(this->y).size() > this->x) { - appendix = this->buffer->at(this->y).substr(this->x, this->buffer->at(this->y).size()); - this->buffer->at(this->y) = this->buffer->at(this->y).substr(0, this->x); - } - this->buffer->insert(this->y); - this->y++; - this->buffer->linebuffer().at(this->y) += appendix; - this->x = 0; - this->scrollDown(); - } - break; - case KEY_BACKSPACE: - if (this->x - 1 >= 0) { - this->x--; - this->buffer->remove(this->y, this->x); - } - else { - if (this->buffer->at(this->y).size() > 0 && this->y > 0) { - int oldLength = static_cast(this->buffer->at(this->y - 1).size()); - this->buffer->at(this->y - 1) += this->buffer->at(this->y); - this->buffer->remove(this->y); - this->y--; - this->x = oldLength; - } - else { - if (this->y - 1 >= 0) { - this->buffer->remove(this->y); - this->y--; - this->x = static_cast(this->buffer->at(this->y).length()); - } - } - } - scrollUp(); - break; - case KEY_DC: - if (this->buffer->at(this->y).length() > this->x) - this->buffer->deleteChar(this->y, this->x); - else { - if (this->buffer->at(this->y).empty() && this->buffer->linebuffer().size() - 1 > this->y) - this->buffer->remove(this->y); - else if (this->buffer->linebuffer().size() - 1 > this->y) { - this->buffer->at(this->y) += this->buffer->at(this->y + 1); - this->buffer->remove(this->y + 1); - } - } - break; - case KEY_BTAB: - case KEY_CTAB: - case KEY_STAB: - case KEY_CATAB: - case 9: - this->buffer->at(this->y).insert(this->x, 4, ' '); - this->x += 4; - break; - default: - { - switch (car) { - case '{': - case '[': - this->buffer->at(this->y).insert(this->x, 1, car + 2); - break; - case '(': - this->buffer->at(this->y).insert(this->x, 1, car + 1); - break; - } - std::ofstream log("log"); - log << car << std::endl; - this->buffer->at(this->y).insert(this->x, 1, char(car)); - if (this->lastChar != 195 && this->lastChar != 182) - this->x++; - this->lastChar = char(car); - } - break; - } + this->modes.at(Mode::INSERT)->input(car); break; case Mode::QUIT: break; diff --git a/src/Editor.hpp b/src/Editor.hpp index 7c7cbff..fbe1c95 100644 --- a/src/Editor.hpp +++ b/src/Editor.hpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace groove { @@ -14,6 +16,8 @@ namespace groove { }; class Editor { + friend class modes::Mode; + friend class modes::Insert; private: int x, y; int offset; @@ -22,6 +26,7 @@ namespace groove { Mode mode_; std::string clipboard = ""; std::string filename; + std::unordered_map> modes; bool load(); bool save(); @@ -67,11 +72,7 @@ namespace groove { this->scrollDown(); } public: - Editor() : x(0), y(0), buffer(std::make_unique()), mode_(Mode::EDIT), filename("unbenannt"), - offset(0) { - this->buffer->insert(""); - } - Editor(std::string file); + Editor(std::string file = "ubenannt"); Mode mode() { return this->mode_; } diff --git a/src/modes/Insert.cpp b/src/modes/Insert.cpp new file mode 100644 index 0000000..a278330 --- /dev/null +++ b/src/modes/Insert.cpp @@ -0,0 +1,94 @@ +#include +#include +#include + +namespace groove { + namespace modes { + + void Insert::input(int c) { + switch (c) { + case 27: + this->editor.mode_ = groove::Mode::EDIT; + this->editor.x = 0; + this->editor.y = 0; + break; + case KEY_ENTER: + case 10: + { + std::string appendix; + appendix = ""; + if (this->editor.buffer->at(this->editor.y).size() > this->editor.x) { + appendix = this->editor.buffer->at(this->editor.y).substr(this->editor.x, this->editor.buffer->at(this->editor.y).size()); + this->editor.buffer->at(this->editor.y) = this->editor.buffer->at(this->editor.y).substr(0, this->editor.x); + } + this->editor.buffer->insert(this->editor.y); + this->editor.y++; + this->editor.buffer->linebuffer().at(this->editor.y) += appendix; + this->editor.x = 0; + this->editor.scrollDown(); + } + break; + case KEY_BACKSPACE: + if (this->editor.x - 1 >= 0) { + this->editor.x--; + this->editor.buffer->remove(this->editor.y, this->editor.x); + } + else { + if (this->editor.buffer->at(this->editor.y).size() > 0 && this->editor.y > 0) { + int oldLength = static_cast(this->editor.buffer->at(this->editor.y - 1).size()); + this->editor.buffer->at(this->editor.y - 1) += this->editor.buffer->at(this->editor.y); + this->editor.buffer->remove(this->editor.y); + this->editor.y--; + this->editor.x = oldLength; + } + else { + if (this->editor.y - 1 >= 0) { + this->editor.buffer->remove(this->editor.y); + this->editor.y--; + this->editor.x = static_cast(this->editor.buffer->at(this->editor.y).length()); + } + } + } + this->editor.scrollUp(); + break; + case KEY_DC: + if (this->editor.buffer->at(this->editor.y).length() > this->editor.x) + this->editor.buffer->deleteChar(this->editor.y, this->editor.x); + else { + if (this->editor.buffer->at(this->editor.y).empty() && this->editor.buffer->linebuffer().size() - 1 > this->editor.y) + this->editor.buffer->remove(this->editor.y); + else if (this->editor.buffer->linebuffer().size() - 1 > this->editor.y) { + this->editor.buffer->at(this->editor.y) += this->editor.buffer->at(this->editor.y + 1); + this->editor.buffer->remove(this->editor.y + 1); + } + } + break; + case KEY_BTAB: + case KEY_CTAB: + case KEY_STAB: + case KEY_CATAB: + case 9: + this->editor.buffer->at(this->editor.y).insert(this->editor.x, 4, ' '); + this->editor.x += 4; + break; + default: + { + switch (c) { + case '{': + case '[': + this->editor.buffer->at(this->editor.y).insert(this->editor.x, 1, c + 2); + break; + case '(': + this->editor.buffer->at(this->editor.y).insert(this->editor.x, 1, c + 1); + break; + } + this->editor.buffer->at(this->editor.y).insert(this->editor.x, 1, char(c)); + if (this->editor.lastChar != 195 && this->editor.lastChar != 182) + this->editor.x++; + this->editor.lastChar = char(c); + } + break; + } + } + } +} \ No newline at end of file diff --git a/src/modes/Insert.hpp b/src/modes/Insert.hpp new file mode 100644 index 0000000..5ac43f8 --- /dev/null +++ b/src/modes/Insert.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace groove { + namespace modes { + + class Insert : public Mode { + public: + using Mode::Mode; + std::string status() { + return this->status_; + } + void input(int c); + }; + + } +} \ No newline at end of file diff --git a/src/modes/Mode.cpp b/src/modes/Mode.cpp new file mode 100644 index 0000000..045eee8 --- /dev/null +++ b/src/modes/Mode.cpp @@ -0,0 +1,9 @@ +#include + +namespace groove { + namespace modes { + + Mode::~Mode() {} + + } +} \ No newline at end of file diff --git a/src/modes/Mode.hpp b/src/modes/Mode.hpp new file mode 100644 index 0000000..16a47f3 --- /dev/null +++ b/src/modes/Mode.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace groove { + class Editor; + + namespace modes { + + class Mode { + protected: + groove::Editor& editor; + std::string status_; + public: + Mode(groove::Editor& editor) : editor(editor) , status_("") {} + virtual ~Mode() = 0; + virtual std::string status() = 0; + virtual void input(int c) = 0; + }; + + } +} \ No newline at end of file