diff --git a/CMakeLists.txt b/CMakeLists.txt index 5143125..b8fb007 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.7) project(groove C CXX) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 14) include_directories(src) diff --git a/main.cpp b/main.cpp index ad2d4b9..f90e65c 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,7 @@ #include #include #include +#include int main(int argc, char* argv[]) { std::unique_ptr editor; diff --git a/src/Buffer.hpp b/src/Buffer.hpp index 73071ef..309e214 100644 --- a/src/Buffer.hpp +++ b/src/Buffer.hpp @@ -3,12 +3,15 @@ #include #include #include +#include namespace groove { class Buffer { private: std::vector lines; + std::vector reverted; + std::stack> history; void removeTabs(std::string& line) { ulong tab = line.find("\t"); if(tab != line.npos) @@ -16,7 +19,7 @@ namespace groove { } public: bool changed; - Buffer() : lines(std::vector()), changed(false) {} + Buffer() : lines(std::vector()), reverted(std::vector()), changed(false) {} std::vector& linebuffer() { return this->lines; } @@ -56,6 +59,16 @@ namespace groove { return this->lines.at(line); } + void swap(std::vector buffer) { + this->history.push(this->lines); + this->lines = buffer; + } + + void revert() { + this->lines = this->history.top(); + this->history.pop(); + } + unsigned long size() { return this->lines.size(); } diff --git a/src/Editor.cpp b/src/Editor.cpp index 696e720..b4c1c28 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -9,6 +9,18 @@ namespace groove { buffer(std::make_unique()), mode_(Mode::EDIT), filename(filename), offset(0), voffset(0), history(History()), inComment(false) { + + std::string ending; + if (filename.find_last_of('.') != std::string::npos) + ending = std::string(filename.begin() + filename.find_last_of('.'), filename.end()); + else + ending = ""; + + if (ending == ".cpp" || ending == ".hpp" || ending == ".h" || ending == ".c") + groove::Highlighter::list = groove::Highlighter::Syntaxes.at(groove::Syntax::CPP); + else + groove::Highlighter::list = groove::Highlighter::Syntaxes.at(groove::Syntax::DEFAULT); + this->modes.emplace(Mode::INSERT, std::make_unique(*this)); this->modes.emplace(Mode::EDIT, std::make_unique(*this)); this->modes.emplace(Mode::QUIT, std::make_unique(*this)); diff --git a/src/Highlighter.cpp b/src/Highlighter.cpp index 10b7304..07a7ed5 100644 --- a/src/Highlighter.cpp +++ b/src/Highlighter.cpp @@ -3,20 +3,32 @@ #include namespace groove { - - std::vector> Highlighter::list = { - make_pair("([+-.<>,;=!:&*])", ncurses::Colors::CYAN), - make_pair("([\\{\\}\\[\\]\\(\\)])", ncurses::Colors::GREEN), - make_pair("(^|\\s)(while|if|try|catch|void|this|else|using|namespace|private|public|protected|friend|class|char|bool|unsigned|long|short|int|return)\\s+\\*?", ncurses::Colors::MAGENTA), - make_pair("([a-zA-Z_][a-zA-Z_0-9]+)::", ncurses::Colors::GREEN), - make_pair("::([a-zA-Z_][a-zA-Z_0-9]+)", ncurses::Colors::CYAN), - make_pair("\\.([a-zA-Z_][a-zA-Z_0-9]+)", ncurses::Colors::CYAN), - make_pair("([_a-zA-Z][a-zA-Z0-9_-]+)\\(", ncurses::Colors::CYAN), - make_pair("\\\".*\\\"", ncurses::Colors::ORANGE), - make_pair("/\\*.*\\*//*", ncurses::Colors::COMMENTS), - make_pair("(//.*)", ncurses::Colors::ORANGE) + std::unordered_map Highlighter::Syntaxes = { + std::make_pair(Syntax::CPP, + RulesList { + make_pair("([+-.<>,;=!:&*])", ncurses::Colors::CYAN), + make_pair("([\\{\\}\\[\\]\\(\\)])", ncurses::Colors::GREEN), + make_pair("(^|\\s)(while|if|try|catch|void|this|else|using|namespace|private|public|protected|friend|class|char|bool|unsigned|long|short|int|return):?(\\s+|$)\\*?", ncurses::Colors::MAGENTA), + make_pair("([a-zA-Z_][a-zA-Z_0-9]+)::", ncurses::Colors::GREEN), + make_pair("::([a-zA-Z_][a-zA-Z_0-9]+)", ncurses::Colors::CYAN), + make_pair("\\.([a-zA-Z_][a-zA-Z_0-9]+)", ncurses::Colors::CYAN), + make_pair("([_a-zA-Z][a-zA-Z0-9_-]+)\\(", ncurses::Colors::CYAN), + make_pair("\\\".*\\\"", ncurses::Colors::ORANGE), + make_pair("/\\*.*\\*//*", ncurses::Colors::COMMENTS), + make_pair("(//.*)", ncurses::Colors::ORANGE) + }), + std::make_pair(Syntax::DEFAULT, + RulesList { + make_pair("([.,;!\\*])", ncurses::Colors::MAGENTA), + make_pair("([\\{\\}\\[\\]\\(\\)])", ncurses::Colors::GREEN), + make_pair("\\\".*\\\"", ncurses::Colors::ORANGE), + make_pair("/\\*.*\\*//*", ncurses::Colors::COMMENTS), + }) }; + + RulesList Highlighter::list = RulesList(); + std::unordered_map> groove::Highlighter::get() { std::unordered_map> list; @@ -26,7 +38,7 @@ namespace groove { return list; } - for (auto& keyword : Highlighter::list) { + for (auto &keyword : Highlighter::list) { try { std::sregex_iterator next(this->line.begin(), this->line.end(), keyword.first); std::sregex_iterator end; @@ -37,7 +49,7 @@ namespace groove { } next++; } - } catch (std::regex_error& e) { + } catch (std::regex_error &e) { // Syntax error in the regular expression } } @@ -47,3 +59,5 @@ namespace groove { } } + + diff --git a/src/Highlighter.hpp b/src/Highlighter.hpp index a6308aa..d2aff1a 100644 --- a/src/Highlighter.hpp +++ b/src/Highlighter.hpp @@ -8,15 +8,23 @@ namespace groove { + typedef std::vector> RulesList; + inline std::pair make_pair(std::string regex, ncurses::Colors color) { return std::make_pair(std::regex(regex), color); }; + enum class Syntax { + DEFAULT, + CPP + }; + class Highlighter { private: std::string line; - static std::vector> list; public: + static std::unordered_map Syntaxes; + static RulesList list; Highlighter(std::string line) : line(line) {} std::unordered_map> get(); }; diff --git a/src/History.cpp b/src/History.cpp deleted file mode 100644 index 1f99d65..0000000 --- a/src/History.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by miko on 06.03.17. -// - -#include "History.hpp" diff --git a/src/History.hpp b/src/History.hpp index 802c75b..e979cf7 100644 --- a/src/History.hpp +++ b/src/History.hpp @@ -6,9 +6,11 @@ namespace groove { + typedef std::function lambda; + struct HistoryNode { - std::function undo, redo; - HistoryNode(std::function undo, std::function redo) : + lambda undo, redo; + HistoryNode(lambda undo, lambda redo) : undo(std::move(undo)), redo(std::move(redo)) {} }; diff --git a/src/modes/Edit.cpp b/src/modes/Edit.cpp index 1aa4101..d4df49d 100644 --- a/src/modes/Edit.cpp +++ b/src/modes/Edit.cpp @@ -14,7 +14,17 @@ namespace groove { this->editor.input(' '); break; case 'i': - this->editor.mode_ = groove::Mode::INSERT; + { + std::vector& oldBuffer = this->editor.buffer->linebuffer(); + this->editor.history.push(HistoryNode( + [this, oldBuffer](){ + this->editor.buffer->swap(oldBuffer); + }, [this](){ + this->editor.buffer->revert(); + }) + ); + this->editor.mode_ = groove::Mode::INSERT; + } break; case 'a': this->editor.x = static_cast(this->editor.buffer->at(this->editor.y).length());