From 64ce7473ed20c2adc144d64a80b6300dfce38d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 17 Apr 2015 13:01:12 +0200 Subject: [PATCH 1/2] juci working auto complete --- juci/notebook.cc | 193 +++++++++++++++++++++++++++++------------------ juci/notebook.h | 25 +++--- juci/source.cc | 16 ++-- juci/source.h | 25 +++++- 4 files changed, 166 insertions(+), 93 deletions(-) diff --git a/juci/notebook.cc b/juci/notebook.cc index b5f437b..bf3ef2b 100644 --- a/juci/notebook.cc +++ b/juci/notebook.cc @@ -1,6 +1,5 @@ #include "notebook.h" #include -#include "clangmm.h" Notebook::Model::Model() { cc_extension_ = ".cc"; @@ -13,7 +12,8 @@ Notebook::View::View() { view_.set_position(120); } -Notebook::Controller::Controller(Gtk::Window& window, Keybindings::Controller& keybindings, +Notebook::Controller::Controller(Gtk::Window& window, + Keybindings::Controller& keybindings, Source::Config& source_cfg, Directories::Config& dir_cfg) : source_config_(source_cfg), @@ -23,8 +23,8 @@ Notebook::Controller::Controller(Gtk::Window& window, Keybindings::Controller& k refClipboard_ = Gtk::Clipboard::get(); ispopup = false; view().pack1(directories_.widget(), true, true); - CreateKeybindings(keybindings); -} // Constructor + CreateKeybindings(keybindings); + } // Constructor void Notebook::Controller::CreateKeybindings(Keybindings::Controller @@ -98,7 +98,7 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller [this]() { OnEditPaste(); }); - entry_.view_.entry().signal_activate(). + entry_.view_.entry().signal_activate(). connect( [this]() { if (is_new_file_) { @@ -131,54 +131,103 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller }); } -bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button){ - if(button->button == 1 && ispopup){ - popup_.response(Gtk::RESPONSE_DELETE_EVENT); - return true; +bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button) { + if (button->button == 1 && ispopup) { + popup_.response(Gtk::RESPONSE_DELETE_EVENT); + return true; } return false; } -bool Notebook::Controller::OnKeyRelease(GdkEventKey* key){ - if(key->keyval==46){ - return GeneratePopup(); - } - return false; +bool Notebook::Controller::OnKeyRelease(GdkEventKey* key) { + return GeneratePopup(key->keyval); } -bool Notebook::Controller::GeneratePopup(){ +bool Notebook::Controller::GeneratePopup(int key_id) { // Get function to fill popup with suggests item vector under is for testing - std::vector items; - Gtk::TextIter start = CurrentTextView().get_buffer()->get_insert()->get_iter(); - text_vec_.at(CurrentPage())->GetAutoCompleteSuggestions(start.get_line()+1, - start.get_line_offset()+2, - &items); - std::cout << items.size()<< std::endl; - + Gtk::TextIter beg = CurrentTextView().get_buffer()->get_insert()->get_iter(); + Gtk::TextIter end = CurrentTextView().get_buffer()->get_insert()->get_iter(); + Gtk::TextIter tmp = CurrentTextView().get_buffer()->get_insert()->get_iter(); + Gtk::TextIter tmp1 = CurrentTextView().get_buffer()->get_insert()->get_iter(); + Gtk::TextIter line = + CurrentTextView().get_buffer()->get_iter_at_line(tmp.get_line()); + if (end.backward_char() && end.backward_char()) { + bool illegal_chars = + end.backward_search("\"", Gtk::TEXT_SEARCH_VISIBLE_ONLY, tmp, tmp1, line) + || + end.backward_search("//", Gtk::TEXT_SEARCH_VISIBLE_ONLY, tmp, tmp1, line); + if (illegal_chars) { + return false; + } + std::string c = text_vec_[CurrentPage()]->buffer()->get_text(end, beg); + switch (key_id) { + case 46: + break; + case 58: + if (c != "::") return false; + break; + case 60: + if (c != "->") return false; + break; + case 62: + if (c != "->") return false; + break; + default: + return false; + } + } else { + return false; + } + std::vector acdata; + text_vec_.at(CurrentPage())-> + GetAutoCompleteSuggestions(beg.get_line()+1, + beg.get_line_offset()+2, + &acdata); + std::map items; + for (auto &data : acdata) { + std::stringstream ss; + std::string return_value; + for (auto &chunk : data.chunks_) { + switch (chunk.kind()) { + case clang::CompletionChunk_ResultType: + return_value = chunk.chunk(); + break; + case clang::CompletionChunk_Informative: + break; + default: + ss << chunk.chunk(); + break; + } + } + items[ss.str() + " --> " + return_value] = ss.str(); + } // Replace over with get suggestions from zalox! OVER IS JUST FOR TESTING - Gtk::ScrolledWindow popup_scroll_; - Gtk::ListViewText listview_(1,false,Gtk::SelectionMode::SELECTION_SINGLE); - + Gtk::ListViewText listview_(1, false, Gtk::SelectionMode::SELECTION_SINGLE); popup_scroll_.set_policy(Gtk::PolicyType::POLICY_NEVER, - Gtk::PolicyType::POLICY_NEVER); - listview_.set_enable_search(false); + Gtk::PolicyType::POLICY_NEVER); + listview_.set_enable_search(true); listview_.set_headers_visible(false); listview_.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); listview_.set_activate_on_single_click(true); - for (auto &i : items) listview_.append(i); - popup_scroll_.add(listview_); + if (items.empty()) { + items["No suggestions found..."] = ""; + } + for (auto &i : items) { + listview_.append(i.first); + } + popup_scroll_.add(listview_); popup_.get_vbox()->pack_start(popup_scroll_); popup_.set_transient_for(*window_); popup_.show_all(); int popup_x = popup_.get_width(); - int popup_y = items.size()*20; - PopupSetSize(popup_scroll_,popup_x,popup_y); - int x,y; - FindPopupPosition(CurrentTextView(),popup_x,popup_y,x,y); + int popup_y = items.size() * 20; + PopupSetSize(popup_scroll_, popup_x, popup_y); + int x, y; + FindPopupPosition(CurrentTextView(), popup_x, popup_y, x, y); popup_.move(x, y+15); - PopupSelectHandler(popup_, listview_); + PopupSelectHandler(popup_, listview_, &items); ispopup = true; popup_.run(); popup_.hide(); @@ -232,9 +281,7 @@ void Notebook::Controller::OnOpenFile(std::string path) { unsigned pos = path.find_last_of("/\\"); Notebook().append_page(*editor_vec_.back(), path.substr(pos+1)); Notebook().show_all_children(); - std::cout << "setting current page"<< std::endl; Notebook().set_current_page(Pages()-1); - std::cout << "current page set" << std::endl; Notebook().set_focus_child(text_vec_.back()->view()); OnBufferChange(); } @@ -431,37 +478,37 @@ Gtk::Notebook& Notebook::Controller::Notebook() { void Notebook::Controller::TextViewHandlers(Gtk::TextView& textview) { textview.get_buffer()->signal_changed().connect( - [this]() { - OnBufferChange(); - }); + [this]() { + OnBufferChange(); + }); textview.signal_button_release_event(). - connect(sigc::mem_fun(*this,&Notebook::Controller::OnMouseRelease),false); + connect(sigc::mem_fun(*this, &Notebook::Controller::OnMouseRelease), false); textview.signal_key_release_event(). - connect(sigc::mem_fun(*this,&Notebook::Controller::OnKeyRelease),false); - - + connect(sigc::mem_fun(*this, &Notebook::Controller::OnKeyRelease), false); } + void Notebook::Controller::PopupSelectHandler(Gtk::Dialog &popup, - Gtk::ListViewText &listview){ + Gtk::ListViewText &listview, + std::map + *items) { listview.signal_row_activated(). - connect([this, &listview, &popup](const Gtk::TreeModel::Path& path, - Gtk::TreeViewColumn*) { - std::string selected = - listview.get_text(listview.get_selected()[0]); - CurrentTextView().get_buffer()->insert_at_cursor(selected); - popup.response(Gtk::RESPONSE_DELETE_EVENT); - }); + connect([this, &listview, &popup, items](const Gtk::TreeModel::Path& path, + Gtk::TreeViewColumn*) { + std::string selected = items-> + at(listview.get_text(listview.get_selected()[0])); + CurrentTextView().get_buffer()->insert_at_cursor(selected); + popup.response(Gtk::RESPONSE_DELETE_EVENT); + }); } void Notebook::Controller::PopupSetSize(Gtk::ScrolledWindow &scroll, - int ¤t_x, - int ¤t_y) { + int ¤t_x, + int ¤t_y) { int textview_x = CurrentTextView().get_width(); int textview_y = 150; bool is_never_scroll_x = true; bool is_never_scroll_y = true; - std::cout << textview_x << std::endl; if (current_x > textview_x) { current_x = textview_x; is_never_scroll_x = false; @@ -470,36 +517,36 @@ void Notebook::Controller::PopupSetSize(Gtk::ScrolledWindow &scroll, current_y = textview_y; is_never_scroll_y = false; } - scroll.set_size_request(current_x,current_y); + scroll.set_size_request(current_x, current_y); if (!is_never_scroll_x && !is_never_scroll_y) { scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, - Gtk::PolicyType::POLICY_AUTOMATIC); + Gtk::PolicyType::POLICY_AUTOMATIC); } else if (!is_never_scroll_x && is_never_scroll_y) { scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, - Gtk::PolicyType::POLICY_NEVER); + Gtk::PolicyType::POLICY_NEVER); } else if (is_never_scroll_x && !is_never_scroll_y) { scroll.set_policy(Gtk::PolicyType::POLICY_NEVER, - Gtk::PolicyType::POLICY_AUTOMATIC); + Gtk::PolicyType::POLICY_AUTOMATIC); } } void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview, - int popup_x, - int popup_y, - int &x, - int &y){ + int popup_x, + int popup_y, + int &x, + int &y) { Gdk::Rectangle temp1, temp2; textview.get_cursor_locations( - CurrentTextView(). - get_buffer()->get_insert()-> - get_iter(), temp1,temp2); + CurrentTextView(). + get_buffer()->get_insert()-> + get_iter(), temp1, temp2); int textview_edge_x = 0; int textview_edge_y = 0; textview.buffer_to_window_coords( - Gtk::TextWindowType::TEXT_WINDOW_WIDGET, - temp1.get_x(), - temp1.get_y(), - x, y); + Gtk::TextWindowType::TEXT_WINDOW_WIDGET, + temp1.get_x(), + temp1.get_y(), + x, y); Glib::RefPtr gdkw = CurrentTextView().get_window(Gtk::TextWindowType::TEXT_WINDOW_WIDGET); gdkw->get_origin(textview_edge_x, textview_edge_y); @@ -508,17 +555,17 @@ void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview, y+=textview_edge_y; if ((textview_edge_x-x)*-1 > textview.get_width()-popup_x) { x -= popup_x; - if(x textview.get_height()-popup_y) { y -= (popup_y+14) + 15; - if(xget_text(); file.close(); } diff --git a/juci/notebook.h b/juci/notebook.h index 5eac6b0..ccab51b 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -8,6 +8,7 @@ #include "directories.h" #include #include +#include #include namespace Notebook { @@ -57,27 +58,31 @@ namespace Notebook { void OnCreatePage(); bool ScrollEventCallback(GdkEventScroll* scroll_event); int Pages(); - Directories::Controller& directories() { return directories_; } + Directories::Controller& directories() { return directories_; } Gtk::Paned& view(); - bool GeneratePopup(); + bool GeneratePopup(int key); void Search(bool forward); const Source::Config& source_config() { return source_config_; } bool OnMouseRelease(GdkEventButton* button); bool OnKeyRelease(GdkEventKey* key); + protected: void TextViewHandlers(Gtk::TextView& textview); void PopupSelectHandler(Gtk::Dialog &popup, - Gtk::ListViewText &listview); - private: + Gtk::ListViewText &listview, + std::map + *items); + + private: void CreateKeybindings(Keybindings::Controller& keybindings); void FindPopupPosition(Gtk::TextView& textview, - int popup_x, - int popup_y, - int &x, - int &y); + int popup_x, + int popup_y, + int &x, + int &y); void PopupSetSize(Gtk::ScrolledWindow& scroll, - int ¤t_x, - int ¤t_y); + int ¤t_x, + int ¤t_y); Glib::RefPtr m_refBuilder; Glib::RefPtr refActionGroup; Source::Config source_config_; diff --git a/juci/source.cc b/juci/source.cc index baec800..5210541 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -135,7 +135,8 @@ void Source::Controller::OnLineEdit() { } void Source::Controller:: GetAutoCompleteSuggestions(int line_number, int column, - std::vector *suggestions) { + std::vector + *suggestions) { parsing.lock(); model().GetAutoCompleteSuggestions(view().get_buffer() ->get_text().raw(), @@ -149,19 +150,20 @@ void Source::Model:: GetAutoCompleteSuggestions(const std::string& buffer, int line_number, int column, - std::vector *suggestions) { + std::vector + *suggestions) { clang::CodeCompleteResults results(&tu_, file_path(), buffer, line_number, column); for (int i = 0; i < results.size(); i++) { - std::stringstream ss; - const vector c = results.get(i).get_chunks(); - for (auto &stringchunk : c) { - ss << stringchunk.chunk(); + const vector chunks_ = results.get(i).get_chunks(); + std::vector chunks; + for (auto &chunk : chunks_) { + chunks.emplace_back(chunk); } - suggestions->emplace_back(ss.str()); + suggestions->emplace_back(chunks); } } diff --git a/juci/source.h b/juci/source.h index 8450807..cf8789a 100644 --- a/juci/source.h +++ b/juci/source.h @@ -74,6 +74,24 @@ namespace Source { string GetLine(const Gtk::TextIter &begin); }; // class View + class AutoCompleteChunk { + public: + explicit AutoCompleteChunk(const clang::CompletionChunk &chunk) : + chunk_(chunk.chunk()), kind_(chunk.kind()) { } + const std::string& chunk() const { return chunk_; } + const clang::CompletionChunkKind& kind() const { return kind_; } + private: + std::string chunk_; + enum clang::CompletionChunkKind kind_; + }; + + class AutoCompleteData { + public: + explicit AutoCompleteData(const std::vector &chunks) : + chunks_(chunks) { } + std::vector chunks_; + }; + class Model{ public: // constructor for Source::Model @@ -98,7 +116,8 @@ namespace Source { void GetAutoCompleteSuggestions(const std::string& buffer, int line_number, int column, - std::vector *suggestions); + std::vector + *suggestions); ~Model() { } int ReParse(const std::string &buffer); std::vector ExtractTokens(int, int); @@ -113,7 +132,6 @@ namespace Source { int token_kind); void HighlightCursor(clang::Token *token, std::vector *source_ranges); - std::vector get_compilation_commands(); }; @@ -127,7 +145,8 @@ namespace Source { void OnOpenFile(const string &filename); void GetAutoCompleteSuggestions(int line_number, int column, - std::vector *suggestions); + std::vector + *suggestions); Glib::RefPtr buffer(); private: From 5a41847518200383cf843b8cca1af827e9f20dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 Apr 2015 19:28:35 +0200 Subject: [PATCH 2/2] Moves the clang index to notebook for better parsing between edited files --- juci/api.h | 4 +-- juci/config.cc | 4 +-- juci/notebook.cc | 22 +++++++++----- juci/notebook.h | 4 +++ juci/source.cc | 46 ++++++++++++++++------------ juci/source.h | 79 ++++++++++++++++++++++++------------------------ 6 files changed, 89 insertions(+), 70 deletions(-) diff --git a/juci/api.h b/juci/api.h index eb17fc5..46f3f98 100644 --- a/juci/api.h +++ b/juci/api.h @@ -55,9 +55,9 @@ namespace libjuci { const std::string plugin_path, const std::string menu_keybinding); void AddMenuXml(const std::string plugin_name, - const string parent_menu); + const std::string parent_menu); void AddSubMenuXml(const std::string plugin_name, - const string parent_menu); + const std::string parent_menu); ////////////////////////////// //// Boost.Python methods //// ////////////////////////////// diff --git a/juci/config.cc b/juci/config.cc index 3e8a264..689fd19 100644 --- a/juci/config.cc +++ b/juci/config.cc @@ -17,16 +17,14 @@ void MainConfig::GenerateSource() { boost::property_tree::ptree colors_json = source_json.get_child("colors"); for ( auto &i : colors_json ) { source_cfg_.InsertTag(i.first, i.second.get_value()); - std::cout << "inserting tag, key: " << i.first << " value: " << i.second.get_value() << std::endl; } for ( auto &i : syntax_json ) { source_cfg_.InsertType(i.first, i.second.get_value()); - std::cout << "inserting type, key: " << i.first << " value: " << i.second.get_value() << std::endl; } } void MainConfig::GenerateKeybindings() { - string line; + std::string line; std::ifstream menu_xml("menu.xml"); if (menu_xml.is_open()) { while (getline(menu_xml, line)) { diff --git a/juci/notebook.cc b/juci/notebook.cc index bf3ef2b..c918d65 100644 --- a/juci/notebook.cc +++ b/juci/notebook.cc @@ -7,7 +7,7 @@ Notebook::Model::Model() { scrollvalue_ = 50; } -Notebook::View::View() { +Notebook::View::View() : notebook_() { view_.pack2(notebook_); view_.set_position(120); } @@ -17,7 +17,8 @@ Notebook::Controller::Controller(Gtk::Window& window, Source::Config& source_cfg, Directories::Config& dir_cfg) : source_config_(source_cfg), - directories_(dir_cfg) { + directories_(dir_cfg), + index_(0, 1) { window_ = &window; OnNewPage("juCi++"); refClipboard_ = Gtk::Clipboard::get(); @@ -26,7 +27,6 @@ Notebook::Controller::Controller(Gtk::Window& window, CreateKeybindings(keybindings); } // Constructor - void Notebook::Controller::CreateKeybindings(Keybindings::Controller &keybindings) { directories().m_TreeView.signal_row_activated() @@ -275,6 +275,14 @@ void Notebook::Controller::OnNewPage(std::string name) { Notebook().set_focus_child(text_vec_.at(Pages()-1)->view()); } +void Notebook::Controller:: +MapBuffers(std::map *buffers) { + for (auto &buffer : text_vec_) { + buffers->operator[](buffer->model().file_path()) = + buffer->buffer()->get_text().raw(); + } +} + void Notebook::Controller::OnOpenFile(std::string path) { OnCreatePage(); text_vec_.back()->OnOpenFile(path); @@ -287,8 +295,8 @@ void Notebook::Controller::OnOpenFile(std::string path) { } void Notebook::Controller::OnCreatePage() { - text_vec_.push_back(new Source::Controller(source_config())); - linenumbers_vec_.push_back(new Source::Controller(source_config())); + text_vec_.push_back(new Source::Controller(source_config(), this)); + linenumbers_vec_.push_back(new Source::Controller(source_config(), this)); scrolledline_vec_.push_back(new Gtk::ScrolledWindow()); scrolledtext_vec_.push_back(new Gtk::ScrolledWindow()); editor_vec_.push_back(new Gtk::HBox()); @@ -551,8 +559,8 @@ void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview, CurrentTextView().get_window(Gtk::TextWindowType::TEXT_WINDOW_WIDGET); gdkw->get_origin(textview_edge_x, textview_edge_y); - x+=textview_edge_x; - y+=textview_edge_y; + x += textview_edge_x; + y += textview_edge_y; if ((textview_edge_x-x)*-1 > textview.get_width()-popup_x) { x -= popup_x; if (x < textview_edge_x) x = textview_edge_x; diff --git a/juci/notebook.h b/juci/notebook.h index ccab51b..1d2f0aa 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -10,6 +10,7 @@ #include #include #include +#include "clangmm.h" namespace Notebook { class Model { @@ -57,6 +58,8 @@ namespace Notebook { void OnOpenFile(std::string filename); void OnCreatePage(); bool ScrollEventCallback(GdkEventScroll* scroll_event); + void MapBuffers(std::map *buffers); + clang::Index* index() { return &index_; } int Pages(); Directories::Controller& directories() { return directories_; } Gtk::Paned& view(); @@ -101,6 +104,7 @@ namespace Notebook { bool ispopup; Gtk::Dialog popup_; Gtk::Window* window_; + clang::Index index_; }; // class controller } // namespace Notebook #endif // JUCI_NOTEBOOK_H_ diff --git a/juci/source.cc b/juci/source.cc index 5210541..b8d8950 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -4,7 +4,7 @@ #include #include #include - +#include "notebook.h" #define log( var ) \ std::cout << "source.cc (" << __LINE__ << ") " << #var << std::endl @@ -102,16 +102,18 @@ Source::Model::Model(const Source::Config &config) : void Source::Model:: InitSyntaxHighlighting(const std::string &filepath, const std::string &project_path, - const std::string &text, + const std::map + &buffers, int start_offset, - int end_offset) { + int end_offset, + clang::Index *index) { set_file_path(filepath); set_project_path(project_path); std::vector arguments = get_compilation_commands(); - tu_ = clang::TranslationUnit(true, + tu_ = clang::TranslationUnit(index, filepath, arguments, - text); + buffers); } // Source::View::UpdateLine @@ -123,7 +125,7 @@ OnLineEdit(const std::vector &locations, // Source::Model::UpdateLine int Source::Model:: -ReParse(const std::string &buffer) { +ReParse(const std::map &buffer) { return tu_.ReparseTranslationUnit(file_path(), buffer); } @@ -138,8 +140,9 @@ GetAutoCompleteSuggestions(int line_number, std::vector *suggestions) { parsing.lock(); - model().GetAutoCompleteSuggestions(view().get_buffer() - ->get_text().raw(), + std::map buffers; + notebook_->MapBuffers(&buffers); + model().GetAutoCompleteSuggestions(buffers, line_number, column, suggestions); @@ -147,14 +150,14 @@ GetAutoCompleteSuggestions(int line_number, } void Source::Model:: -GetAutoCompleteSuggestions(const std::string& buffer, +GetAutoCompleteSuggestions(const std::map &buffers, int line_number, int column, std::vector *suggestions) { clang::CodeCompleteResults results(&tu_, file_path(), - buffer, + buffers, line_number, column); for (int i = 0; i < results.size(); i++) { @@ -263,9 +266,9 @@ HighlightToken(clang::Token *token, // Source::Controller::Controller() // Constructor for Controller -Source::Controller::Controller(const Source::Config &config) : - model_(config) { -} +Source::Controller::Controller(const Source::Config &config, + Notebook::Controller *notebook) : + model_(config), notebook_(notebook) { } // Source::Controller::view() // return shared_ptr to the view @@ -313,7 +316,7 @@ void Source::View::OnUpdateSyntax(const std::vector &ranges, Glib::RefPtr buffer = get_buffer(); buffer->remove_all_tags(buffer->begin(), buffer->end()); for (auto &range : ranges) { - string type = std::to_string(range.kind()); + std::string type = std::to_string(range.kind()); try { config.typetable().at(type); } catch (std::exception) { @@ -337,17 +340,20 @@ void Source::View::OnUpdateSyntax(const std::vector &ranges, void Source::Controller::OnOpenFile(const string &filepath) { sourcefile s(filepath); + std::map buffers; + notebook_->MapBuffers(&buffers); + buffers[filepath] = s.get_content(); buffer()->set_text(s.get_content()); int start_offset = buffer()->begin().get_offset(); int end_offset = buffer()->end().get_offset(); - if (check_extention(filepath)) { view().ApplyConfig(model().config()); model().InitSyntaxHighlighting(filepath, extract_file_path(filepath), - buffer()->get_text().raw(), + buffers, start_offset, - end_offset); + end_offset, + notebook_->index()); view().OnUpdateSyntax(model().ExtractTokens(start_offset, end_offset), model().config()); } @@ -358,7 +364,10 @@ void Source::Controller::OnOpenFile(const string &filepath) { if (parsing.try_lock()) { while (true) { const std::string raw = buffer()->get_text().raw(); - if (model().ReParse(raw) == 0 && + std::map buffers; + notebook_->MapBuffers(&buffers); + buffers[model().file_path()] = raw; + if (model().ReParse(buffers) == 0 && raw == buffer()->get_text().raw()) { syntax.lock(); go = true; @@ -373,7 +382,6 @@ void Source::Controller::OnOpenFile(const string &filepath) { } }); - buffer()->signal_begin_user_action().connect([this]() { if (go) { syntax.lock(); diff --git a/juci/source.h b/juci/source.h index cf8789a..3f03c58 100644 --- a/juci/source.h +++ b/juci/source.h @@ -3,31 +3,34 @@ #include #include #include -#include #include "gtkmm.h" #include "clangmm.h" #include #include +#include -using std::string; +namespace Notebook { + class Controller; +} namespace Source { - class Config { public: Config(const Config &original); Config(); - const std::unordered_map& tagtable() const; - const std::unordered_map& typetable() const; - void SetTagTable(const std::unordered_map &tagtable); - void InsertTag(const string &key, const string &value); - void SetTypeTable(const std::unordered_map &tagtable); - void InsertType(const string &key, const string &value); + const std::unordered_map& tagtable() const; + const std::unordered_map& typetable() const; + void SetTagTable(const std::unordered_map + &tagtable); + void InsertTag(const std::string &key, const std::string &value); + void SetTypeTable(const std::unordered_map + &tagtable); + void InsertType(const std::string &key, const std::string &value); private: - std::unordered_map tagtable_; - std::unordered_map typetable_; - string background_; + std::unordered_map tagtable_; + std::unordered_map typetable_; + std::string background_; }; // class Config class Location { @@ -48,13 +51,6 @@ namespace Source { const Location& start() const { return start_; } const Location& end() const { return end_; } int kind() const { return kind_; } - void to_stream() const { - std::cout << "range: [" << start_.line_number()-1; - std::cout << ", " << end_.line_number()-1 << "] "; - std::cout << "<" << start_.column_offset()-1; - std::cout << ", " << end_.column_offset()-1 << ">"; - std::cout << std::endl; - } private: Location start_; Location end_; @@ -71,7 +67,7 @@ namespace Source { const Config &config); private: - string GetLine(const Gtk::TextIter &begin); + std::string GetLine(const Gtk::TextIter &begin); }; // class View class AutoCompleteChunk { @@ -98,34 +94,37 @@ namespace Source { explicit Model(const Source::Config &config); // inits the syntax highligthing on file open void InitSyntaxHighlighting(const std::string &filepath, - const std::string &project_path, - const std::string &text, - int start_offset, - int end_offset); + const std::string &project_path, + const std::map + &buffers, + int start_offset, + int end_offset, + clang::Index *index); // sets the filepath for this mvc - void set_file_path(const string &file_path); + void set_file_path(const std::string &file_path); // sets the project path for this mvc - void set_project_path(const string &project_path); + void set_project_path(const std::string &project_path); // gets the file_path member - const string& file_path() const; + const std::string& file_path() const; // gets the project_path member - const string& project_path() const; + const std::string& project_path() const; // gets the config member const Config& config() const; - void GetAutoCompleteSuggestions(const std::string& buffer, - int line_number, - int column, - std::vector - *suggestions); - ~Model() { } - int ReParse(const std::string &buffer); + void GetAutoCompleteSuggestions(const std::map + &buffers, + int line_number, + int column, + std::vector + *suggestions); + ~Model() { } + int ReParse(const std::map &buffers); std::vector ExtractTokens(int, int); private: Config config_; - string file_path_; - string project_path_; + std::string file_path_; + std::string project_path_; clang::TranslationUnit tu_; void HighlightToken(clang::Token *token, std::vector *source_ranges, @@ -137,12 +136,13 @@ namespace Source { class Controller { public: - explicit Controller(const Source::Config &config); + Controller(const Source::Config &config, + Notebook::Controller *notebook); Controller(); View& view(); Model& model(); void OnNewEmptyFile(); - void OnOpenFile(const string &filename); + void OnOpenFile(const std::string &filename); void GetAutoCompleteSuggestions(int line_number, int column, std::vector @@ -159,6 +159,7 @@ namespace Source { protected: View view_; Model model_; + Notebook::Controller *notebook_; }; // class Controller } // namespace Source #endif // JUCI_SOURCE_H_