From 2f88e7558102da52b110839870010a774f0f5aec Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 13 Jun 2015 17:24:36 +0200 Subject: [PATCH] Moved indenting to source.cc, added tab_size in config.json, some smaller bugfixes, Gsv::init is in juci.cc, right after Gtk::Application::create as in examples. Also some improvements to indenting. --- juci/config.cc | 3 ++ juci/config.json | 3 +- juci/notebook.cc | 77 +--------------------------- juci/notebook.h | 1 - juci/source.cc | 130 +++++++++++++++++++++++++++++++++++++++++------ juci/source.h | 10 ++-- juci/terminal.cc | 2 +- 7 files changed, 127 insertions(+), 99 deletions(-) diff --git a/juci/config.cc b/juci/config.cc index d316c02..c3cffb4 100644 --- a/juci/config.cc +++ b/juci/config.cc @@ -15,6 +15,9 @@ MainConfig::MainConfig() : void MainConfig::GenerateSource() { DEBUG("Fetching source cfg"); boost::property_tree::ptree source_json = cfg_.get_child("source"); + source_cfg_.tab_size=source_json.get("tab_size"); + for(unsigned c=0;cn", diff --git a/juci/notebook.cc b/juci/notebook.cc index 732aa54..3956502 100644 --- a/juci/notebook.cc +++ b/juci/notebook.cc @@ -1,7 +1,6 @@ #include #include "notebook.h" #include "logging.h" -#include Notebook::Model::Model() { cc_extension_ = ".cpp"; @@ -19,6 +18,7 @@ Notebook::Controller::Controller(Gtk::Window* window, Source::Config& source_cfg, Directories::Config& dir_cfg) : directories_(dir_cfg), + source_config_(source_cfg), index_(0, 1) { INFO("Create notebook"); window_ = window; @@ -26,7 +26,6 @@ Notebook::Controller::Controller(Gtk::Window* window, refClipboard_ = Gtk::Clipboard::get(); ispopup = false; view().pack1(directories_.widget(), true, true); - source_config_ = source_cfg; CreateKeybindings(keybindings); INFO("Notebook Controller Success"); } // Constructor @@ -187,77 +186,6 @@ bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button) { return false; } -bool Notebook::Controller::OnKeyPress(GdkEventKey* key) { - //Indent as in previous line, and indent left after if/else/etc - if(key->keyval==GDK_KEY_Return && key->state==0) { - Gtk::TextIter insert_it = Buffer(text_vec_.at(CurrentPage()))->get_insert()->get_iter(); - Gtk::TextIter line_it = Buffer(text_vec_.at(CurrentPage()))->get_iter_at_line(insert_it.get_line()); - std::string line(Buffer(text_vec_.at(CurrentPage()))->get_text(line_it, insert_it)); - std::smatch sm; - const std::regex bracket_regex("^( *).*\\{ *$"); - const std::regex no_bracket_statement_regex("^( *)(if|else|else if|try|catch|while)[^\\}]*$"); - const std::regex no_bracket_regex("^( *).*$"); - if(std::regex_match(line, sm, bracket_regex)) { - Buffer(text_vec_.at(CurrentPage()))->insert_at_cursor("\n"+sm[1].str()+" "); - } - else if(std::regex_match(line, sm, no_bracket_statement_regex)) { - Buffer(text_vec_.at(CurrentPage()))->insert_at_cursor("\n"+sm[1].str()+" "); - } - else if(std::regex_match(line, sm, no_bracket_regex)) { - Buffer(text_vec_.at(CurrentPage()))->insert_at_cursor("\n"+sm[1].str()); - } - CurrentTextView().scroll_to(Buffer(text_vec_.at(CurrentPage()))->get_insert()); - return true; - } - //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text. - if(key->keyval==GDK_KEY_Tab && key->state==0) { - Gtk::TextIter selection_start, selection_end; - Buffer(text_vec_.at(CurrentPage()))->get_selection_bounds(selection_start, selection_end); - int line_start=selection_start.get_line(); - int line_end=selection_end.get_line(); - for(int line=line_start;line<=line_end;line++) { - Gtk::TextIter line_it = Buffer(text_vec_.at(CurrentPage()))->get_iter_at_line(line); - Buffer(text_vec_.at(CurrentPage()))->insert(line_it, " "); - } - return true; - } - //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text. - else if((key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) && key->state==GDK_SHIFT_MASK) { - Gtk::TextIter selection_start, selection_end; - Buffer(text_vec_.at(CurrentPage()))->get_selection_bounds(selection_start, selection_end); - int line_start=selection_start.get_line(); - int line_end=selection_end.get_line(); - for(int line=line_start;line<=line_end;line++) { - Gtk::TextIter line_it = Buffer(text_vec_.at(CurrentPage()))->get_iter_at_line(line); - Gtk::TextIter line_plus_it=line_it; - line_plus_it++; - line_plus_it++; - std::string start(Buffer(text_vec_.at(CurrentPage()))->get_text(line_it, line_plus_it)); - if(start==" ") - Buffer(text_vec_.at(CurrentPage()))->erase(line_it, line_plus_it); - } - return true; - } - //Indent left when writing } on a new line - else if(key->keyval==GDK_KEY_braceright) { - Gtk::TextIter insert_it = Buffer(text_vec_.at(CurrentPage()))->get_insert()->get_iter(); - Gtk::TextIter line_it = Buffer(text_vec_.at(CurrentPage()))->get_iter_at_line(insert_it.get_line()); - Gtk::TextIter line_plus_it=line_it; - line_plus_it++; - line_plus_it++; - std::string start(Buffer(text_vec_.at(CurrentPage()))->get_text(line_it, line_plus_it)); - std::string line(Buffer(text_vec_.at(CurrentPage()))->get_text(line_it, insert_it)); - for(auto &c: line) { - if(c!=' ') - return false; - } - if(start==" ") - Buffer(text_vec_.at(CurrentPage()))->erase(line_it, line_plus_it); - return false; - } - return false; -} - bool Notebook::Controller::OnKeyRelease(GdkEventKey* key) { return GeneratePopup(key->keyval); } @@ -571,9 +499,6 @@ void Notebook::Controller::TextViewHandlers(Gtk::TextView& textview) { textview.signal_button_release_event(). connect(sigc::mem_fun(*this, &Notebook::Controller::OnMouseRelease), false); - textview.signal_key_press_event(). - connect(sigc::mem_fun(*this, &Notebook::Controller::OnKeyPress), false); - textview.signal_key_release_event(). connect(sigc::mem_fun(*this, &Notebook::Controller::OnKeyRelease), false); } diff --git a/juci/notebook.h b/juci/notebook.h index 5dae038..f1741ac 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -71,7 +71,6 @@ namespace Notebook { void Search(bool forward); Source::Config& source_config() { return source_config_; } bool OnMouseRelease(GdkEventButton* button); - bool OnKeyPress(GdkEventKey* key); bool OnKeyRelease(GdkEventKey* key); std::string OnSaveFileAs(); bool LegalExtension(std::string extension); diff --git a/juci/source.cc b/juci/source.cc index 38f0d03..095bdef 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -6,6 +6,7 @@ #include "notebook.h" #include "logging.h" #include +#include Source::Location:: Location(int line_number, int column_offset) : @@ -28,18 +29,26 @@ Range(const Source::Range &org) : //// View //// ////////////// Source::View::View() { - Gsv::init(); override_font(Pango::FontDescription("Monospace")); set_show_line_numbers(true); set_highlight_current_line(true); set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); } -string Source::View::GetLine(const Gtk::TextIter &begin) { - Gtk::TextIter end(begin); - while (!end.ends_line()) - end++; - return begin.get_text(end); +string Source::View::GetLine(size_t line_number) { + Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(line_number); + Gtk::TextIter line_end_it = line_it; + while(!line_end_it.ends_line()) + line_end_it++; + std::string line(get_source_buffer()->get_text(line_it, line_end_it)); + return line; +} + +string Source::View::GetLineBeforeInsert() { + Gtk::TextIter insert_it = get_source_buffer()->get_insert()->get_iter(); + Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(insert_it.get_line()); + std::string line(get_source_buffer()->get_text(line_it, insert_it)); + return line; } // Source::View::ApplyTheme() @@ -53,15 +62,6 @@ void Source::View::ApplyConfig(const Source::Config &config) { -// Source::View::Config::Config(Config &config) -// copy-constructor -Source::Config::Config(const Source::Config &original) { - SetTagTable(original.tagtable()); - SetTypeTable(original.typetable()); -} - -Source::Config::Config() {} - // Source::View::Config::tagtable() // returns a const refrence to the tagtable const std::unordered_map& Source::Config::tagtable() const { @@ -283,6 +283,7 @@ Source::Controller::Controller(const Source::Config &config, Notebook::Controller *notebook) : model_(config), notebook_(notebook) { INFO("Source Controller with childs constructed"); + view().signal_key_press_event().connect(sigc::mem_fun(*this, &Source::Controller::OnKeyPress), false); } // Source::Controller::view() @@ -391,6 +392,105 @@ void Source::Controller::OnOpenFile(const string &filepath) { }); } } + Glib::RefPtr Source::Controller::buffer() { return view().get_source_buffer(); } + +bool Source::Controller::OnKeyPress(GdkEventKey* key) { + const std::regex bracket_regex("^( *).*\\{ *$"); + const std::regex no_bracket_statement_regex("^( *)(if|else if|catch|while) *\\(.*[^;}] *$"); + const std::regex no_bracket_no_para_statement_regex("^( *)(else|try|do) *$"); + const std::regex spaces_regex("^( *).*$"); + + //Indent as in previous line, and indent right after if/else/etc + if(key->keyval==GDK_KEY_Return && key->state==0) { + string line(view().GetLineBeforeInsert()); + std::smatch sm; + if(std::regex_match(line, sm, bracket_regex)) { + buffer()->insert_at_cursor("\n"+sm[1].str()+model().config().tab); + } + else if(std::regex_match(line, sm, no_bracket_statement_regex)) { + buffer()->insert_at_cursor("\n"+sm[1].str()+model().config().tab); + } + else if(std::regex_match(line, sm, no_bracket_no_para_statement_regex)) { + buffer()->insert_at_cursor("\n"+sm[1].str()+model().config().tab); + } + else if(std::regex_match(line, sm, spaces_regex)) { + buffer()->insert_at_cursor("\n"+sm[1].str()); + } + view().scroll_to(buffer()->get_insert()); + return true; + } + //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text. + if(key->keyval==GDK_KEY_Tab && key->state==0) { + Gtk::TextIter selection_start, selection_end; + buffer()->get_selection_bounds(selection_start, selection_end); + int line_start=selection_start.get_line(); + int line_end=selection_end.get_line(); + for(int line=line_start;line<=line_end;line++) { + Gtk::TextIter line_it = buffer()->get_iter_at_line(line); + buffer()->insert(line_it, model().config().tab); + } + return true; + } + //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text. + else if((key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) && key->state==GDK_SHIFT_MASK) { + Gtk::TextIter selection_start, selection_end; + buffer()->get_selection_bounds(selection_start, selection_end); + int line_start=selection_start.get_line(); + int line_end=selection_end.get_line(); + + for(int line_nr=line_start;line_nr<=line_end;line_nr++) { + string line=view().GetLine(line_nr); + if(!(line.size()>=model().config().tab_size && line.substr(0, model().config().tab_size)==model().config().tab)) + return true; + } + + for(int line_nr=line_start;line_nr<=line_end;line_nr++) { + Gtk::TextIter line_it = buffer()->get_iter_at_line(line_nr); + Gtk::TextIter line_plus_it=line_it; + + for(unsigned c=0;cerase(line_it, line_plus_it); + } + return true; + } + //Indent left when writing } on a new line + else if(key->keyval==GDK_KEY_braceright) { + string line=view().GetLineBeforeInsert(); + if(line.size()>=model().config().tab_size) { + for(auto c: line) { + if(c!=' ') + return false; + } + Gtk::TextIter insert_it = buffer()->get_insert()->get_iter(); + Gtk::TextIter line_it = buffer()->get_iter_at_line(insert_it.get_line()); + Gtk::TextIter line_plus_it=line_it; + for(unsigned c=0;cerase(line_it, line_plus_it); + } + return false; + } + //"Smart" backspace key + else if(key->keyval==GDK_KEY_BackSpace) { + Gtk::TextIter insert_it=buffer()->get_insert()->get_iter(); + int line_nr=insert_it.get_line(); + if(line_nr>0) { + string line=view().GetLine(line_nr); + string previous_line=view().GetLine(line_nr-1); + smatch sm; + if(std::regex_match(previous_line, sm, spaces_regex)) { + if(line==sm[1]) { + Gtk::TextIter line_it = buffer()->get_iter_at_line(line_nr); + buffer()->erase(line_it, insert_it); + } + } + } + } + + return false; +} \ No newline at end of file diff --git a/juci/source.h b/juci/source.h index a864b96..d9f789e 100644 --- a/juci/source.h +++ b/juci/source.h @@ -17,8 +17,6 @@ namespace Notebook { namespace Source { class Config { public: - Config(const Config &original); - Config(); const std::unordered_map& tagtable() const; const std::unordered_map& typetable() const; std::vector& extensiontable(); @@ -30,6 +28,8 @@ namespace Source { void InsertType(const std::string &key, const std::string &value); void InsertExtension(const std::string &ext); std::vector extensiontable_; + unsigned tab_size; //TODO: Have to clean away all the simple setter and getter methods at some point. It creates too much unnecessary code + std::string tab; private: std::unordered_map tagtable_; std::unordered_map typetable_; @@ -70,9 +70,8 @@ namespace Source { const Config &config); void OnUpdateSyntax(const std::vector &locations, const Config &config); - - private: - std::string GetLine(const Gtk::TextIter &begin); + std::string GetLine(size_t line_number); + std::string GetLineBeforeInsert(); }; // class View class AutoCompleteChunk { @@ -159,6 +158,7 @@ namespace Source { void set_is_saved(bool isSaved) { is_saved_ = isSaved; } void set_is_changed(bool isChanged) { is_changed_ = isChanged; } void set_file_path(std::string path) { model().set_file_path(path); } + bool OnKeyPress(GdkEventKey* key); private: void OnLineEdit(); diff --git a/juci/terminal.cc b/juci/terminal.cc index 00c7004..83f8205 100644 --- a/juci/terminal.cc +++ b/juci/terminal.cc @@ -47,7 +47,7 @@ void Terminal::Controller::Compile(){ Terminal().get_buffer()->set_text(""); DEBUG("Terminal: Compile: running cmake command"); std::vector commands = config().compile_commands(); - for (auto it = 0; it < commands.size(); ++it) { + for (size_t it = 0; it < commands.size(); ++it) { ExecuteCommand(commands.at(it), "r"); }