From 097143ecf76e728000a3a89b66d7c3544d895f90 Mon Sep 17 00:00:00 2001 From: Michael Ochmann Date: Fri, 10 Mar 2017 09:59:08 +0100 Subject: [PATCH] added config file --- CMakeLists.txt | 2 +- src/Buffer.hpp | 9 ++++- src/Editor.cpp | 7 +++- src/Editor.hpp | 2 + src/Highlighter.cpp | 2 +- src/config/ConfigParser.cpp | 72 +++++++++++++++++++++++++++++++++ src/config/ConfigParser.hpp | 79 +++++++++++++++++++++++++++++++++++++ src/modes/Edit.cpp | 4 +- src/modes/Save.cpp | 1 + 9 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 src/config/ConfigParser.cpp create mode 100644 src/config/ConfigParser.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b8fb007..5143125 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 14) +set(CMAKE_CXX_STANDARD 17) include_directories(src) diff --git a/src/Buffer.hpp b/src/Buffer.hpp index 4c62957..73071ef 100644 --- a/src/Buffer.hpp +++ b/src/Buffer.hpp @@ -15,7 +15,8 @@ namespace groove { this->removeTabs(line.replace(tab, 1, " ")); } public: - Buffer() : lines(std::vector()) {} + bool changed; + Buffer() : lines(std::vector()), changed(false) {} std::vector& linebuffer() { return this->lines; } @@ -23,26 +24,32 @@ namespace groove { void insert(std::string str, unsigned long line) { this->lines.insert(this->lines.begin() + line, str); this->removeTabs(this->lines.at(line)); + this->changed = true; } void insert(std::string line) { this->removeTabs(line); this->lines.emplace_back(line); + this->changed = true; } void insert(unsigned long after) { this->lines.insert(this->lines.begin() + after + 1, ""); + this->changed = true; } void remove(unsigned long line) { this->lines.erase(this->lines.begin() + line); + this->changed = true; } void remove(unsigned long line, int car) { this->lines.at(line).erase(this->lines.at(line).begin() + car); + this->changed = true; } void deleteChar(unsigned long line, int car) { this->lines.at(line).erase(this->lines.at(line).begin() + car); + this->changed = true; } std::string& at(unsigned long line) { diff --git a/src/Editor.cpp b/src/Editor.cpp index 8bba891..fe9c50c 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -8,13 +8,16 @@ namespace groove { Editor::Editor(std::string filename) : x(0), y(0), buffer(std::make_unique()), mode_(Mode::EDIT), - filename(filename), offset(0), voffset(0), lineMode(LineMode::RELATIVE), - history(History()), inComment(false) { + filename(filename), offset(0), voffset(0), + history(History()), inComment(false), config(config::ConfigParser()) { 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)); this->modes.emplace(Mode::SAVE, std::make_unique(*this)); + this->lineMode = this->config.get("linenumbers") == "relative" ? LineMode::RELATIVE : + this->config.get("linenumbers") == "none" ? LineMode::NONE : LineMode::NUMBERS; + this->overlay = newwin(LINES * 0.9, COLS * 0.9, (LINES * 0.1f) / 2.0f, (COLS * 0.1f) / 2.0f); box(this->overlay, 0, 0); diff --git a/src/Editor.hpp b/src/Editor.hpp index bdbac95..22fcb13 100644 --- a/src/Editor.hpp +++ b/src/Editor.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace groove { @@ -48,6 +49,7 @@ namespace groove { std::string clipboard = ""; std::string filename; std::unordered_map> modes; + config::ConfigParser config; bool load(); bool save(); diff --git a/src/Highlighter.cpp b/src/Highlighter.cpp index 1e0c921..10b7304 100644 --- a/src/Highlighter.cpp +++ b/src/Highlighter.cpp @@ -7,7 +7,7 @@ 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)\\*?", ncurses::Colors::MAGENTA), + 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), diff --git a/src/config/ConfigParser.cpp b/src/config/ConfigParser.cpp new file mode 100644 index 0000000..0bec241 --- /dev/null +++ b/src/config/ConfigParser.cpp @@ -0,0 +1,72 @@ +#include +#include + +namespace groove { + namespace config { + + void ConfigValue::set(std::string &value) { + strVal = value; + boolVal = value == "true"; + try { + intVal = std::stoi(value); + } catch (std::invalid_argument) { + intVal = 0; + } + try { + floatVal = std::stof(value); + } catch (std::invalid_argument) { + floatVal = 0.0f; + } + } + + void ConfigParser::parse() { + std::ifstream file(this->filename.c_str()); + if(file.is_open()) { + while(!file.eof()) { + std::string line; + std::getline(file, line); + if (line == "" || line.at(0) == '#') + continue; + std::vector pair = std::explode(line,'='); + std::string key = pair.at(0); + std::string value = pair.at(1); + std::trim(key); + std::trim(value); + this->params.emplace(key, ConfigValue(value)); + } + } + else { + std::cerr << "Could not load config file." << std::endl; + } + } + + template<> + std::string ConfigParser::get(const std::string& key) { + if (this->params.find(key) == this->params.end()) + return ""; + return this->params.at(key).strVal; + } + + template<> + int ConfigParser::get(const std::string& key) { + if (this->params.find(key) == this->params.end()) + return 0; + return this->params.at(key).intVal; + } + + template<> + float ConfigParser::get(const std::string& key) { + if (this->params.find(key) == this->params.end()) + return 0.0f; + return this->params.at(key).floatVal; + } + + template<> + bool ConfigParser::get(const std::string& key) { + if (this->params.find(key) == this->params.end()) + return false; + return this->params.at(key).boolVal; + } + + } +} \ No newline at end of file diff --git a/src/config/ConfigParser.hpp b/src/config/ConfigParser.hpp new file mode 100644 index 0000000..deabe75 --- /dev/null +++ b/src/config/ConfigParser.hpp @@ -0,0 +1,79 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std { + static inline std::vector explode(const std::string &str, char delimiter) { + std::vector tokens; + std::stringstream inStream(str); + std::string tempString; + + while (std::getline(inStream, tempString, delimiter)) + tokens.push_back(tempString); + + return tokens; + } + + static inline void ltrim(std::string &string) { + string.erase(string.begin(), std::find_if(string.begin(), string.end(), [](auto c){return !std::isspace(c);})); + } + + static inline void rtrim(std::string &string) { + string.erase(std::find_if(string.rbegin(), string.rend(), [](auto c){return !std::isspace(c);}).base(), string.end()); + } + + static inline void trim(std::string &string) { + rtrim(string); + ltrim(string); + } +} + +namespace groove { + namespace config { + + struct ConfigValue { + std::string strVal; + int intVal; + float floatVal; + bool boolVal; + + ConfigValue(std::string &value) { + set(value); + } + + void set(std::string &value); + }; + + class ConfigParser { + private: + std::unordered_map params; + std::string filename; + + void parse(); + public: + ConfigParser() { + this->filename = getenv("HOME"); + this->filename += "/.grooverc"; + this->parse(); + } + + template + T get(const std::string& key) {} + + template + void set(std::string key, T value) { + std::string newValue = std::to_string(value); + this->params.at(key).set(newValue); + } + }; + + } +} \ No newline at end of file diff --git a/src/modes/Edit.cpp b/src/modes/Edit.cpp index 34e442b..e7b37ec 100644 --- a/src/modes/Edit.cpp +++ b/src/modes/Edit.cpp @@ -1,11 +1,11 @@ #include #include -#include namespace groove { namespace modes { void Edit::input(int c) { + this->status_ = this->editor.buffer->changed ? "*" : ""; if (this->editor.movement(c)) return; switch (c) { @@ -60,6 +60,8 @@ namespace groove { break; case 'd': { + if (this->editor.y >= this->editor.buffer->size() - 1) + break; long y = this->editor.y; std::string line = this->editor.buffer->at(y); this->editor.history.push( diff --git a/src/modes/Save.cpp b/src/modes/Save.cpp index b5d24bd..999ccf8 100644 --- a/src/modes/Save.cpp +++ b/src/modes/Save.cpp @@ -14,6 +14,7 @@ namespace groove { case 'y': if (!this->editor.save()) std::cerr << "Could not write to file: '" << this->editor.filename << "'\n"; + this->editor.buffer->changed = false; this->editor.mode_ = groove::Mode::EDIT; break; }