From 4a3a1ddfd9d27ac4a6325bd287092413c9907ed4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 12 Jul 2015 21:45:48 +0200 Subject: [PATCH 1/4] Autocomplete optimization and fix for completion after parentheses. --- juci/source.cc | 31 ++++++++++++++++++++++--------- juci/source.h | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/juci/source.cc b/juci/source.cc index 2c1d7e6..f90ae44 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -588,7 +588,7 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this) { return; std::string line=" "+get_line_before_insert(); if((std::count(line.begin(), line.end(), '\"')%2)!=1 && line.find("//")==std::string::npos) { - const std::regex in_specified_namespace("^(.*[a-zA-Z0-9_])(->|\\.|::)([a-zA-Z0-9_]*)$"); + const std::regex in_specified_namespace("^(.*[a-zA-Z0-9_\\)])(->|\\.|::)([a-zA-Z0-9_]*)$"); const std::regex within_namespace("^(.*)([^a-zA-Z0-9_]+)([a-zA-Z0-9_]{3,})$"); std::smatch sm; if(std::regex_match(line, sm, in_specified_namespace)) { @@ -672,9 +672,10 @@ void Source::ClangViewAutocomplete::autocomplete() { default: ss << chunk.chunk; break; } } - if (ss.str().length() > 0) { // if length is 0 the result is empty - if(prefix.size()==0 || ss.str().find(prefix)==0) { - auto pair=std::pair(ss.str(), data.brief_comments); + auto ss_str=ss.str(); + if (ss_str.length() > 0) { // if length is 0 the result is empty + if(ss_str.size()>=prefix.size() && ss_str.compare(0, prefix.size(), prefix)==0) { + auto pair=std::pair(ss_str, data.brief_comments); rows[ss.str() + " --> " + return_value] = pair; } } @@ -699,9 +700,10 @@ void Source::ClangViewAutocomplete::autocomplete() { column_nr--; } buffer+="\n"; - std::thread autocomplete_thread([this, ac_data, line_nr, column_nr, buffer_map](){ + auto prefix_copy=prefix; + std::thread autocomplete_thread([this, ac_data, line_nr, column_nr, buffer_map, prefix_copy](){ parsing_mutex.lock(); - *ac_data=move(get_autocomplete_suggestions(line_nr, column_nr, *buffer_map)); + *ac_data=move(get_autocomplete_suggestions(line_nr, column_nr, *buffer_map, prefix_copy)); autocomplete_done(); parsing_mutex.unlock(); }); @@ -711,7 +713,7 @@ void Source::ClangViewAutocomplete::autocomplete() { } std::vector Source::ClangViewAutocomplete:: -get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map) { +get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map, const std::string& prefix) { INFO("Getting auto complete suggestions"); std::vector suggestions; clang::CodeCompleteResults results(clang_tu.get(), @@ -722,8 +724,19 @@ get_autocomplete_suggestions(int line_number, int column, std::map=prefix.size() && chunk.chunk.compare(0, prefix.size(), prefix)==0) + match=true; + break; + } + } + if(match) { + suggestions.emplace_back(std::move(chunks)); + suggestions.back().brief_comments=result.get_brief_comments(); + } } } DEBUG("Number of suggestions"); diff --git a/juci/source.h b/juci/source.h index a86654c..66ff9ac 100644 --- a/juci/source.h +++ b/juci/source.h @@ -131,7 +131,7 @@ namespace Source { private: void autocomplete(); SelectionDialog selection_dialog; - std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map); + std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map, const std::string& prefix); Glib::Dispatcher autocomplete_done; sigc::connection autocomplete_done_connection; bool autocomplete_starting=false; From 66bfb0bed68e48ce7987f1d5345e93d6b3599250 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 12 Jul 2015 23:45:35 +0200 Subject: [PATCH 2/4] Optimized autocomplete more. --- juci/source.cc | 54 ++++++++++++++++++++++++++++---------------------- juci/source.h | 5 +++-- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/juci/source.cc b/juci/source.cc index f90ae44..49b8595 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -580,9 +580,9 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) { ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// - +//TODO: Raise autocomplete window after alt-tab back to application Source::ClangViewAutocomplete::ClangViewAutocomplete(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal): -Source::ClangView(file_path, project_path, terminal), selection_dialog(*this) { +Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), autocomplete_cancel_starting(false) { get_buffer()->signal_changed().connect([this](){ if(last_keyval==GDK_KEY_BackSpace) return; @@ -592,7 +592,9 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this) { const std::regex within_namespace("^(.*)([^a-zA-Z0-9_]+)([a-zA-Z0-9_]{3,})$"); std::smatch sm; if(std::regex_match(line, sm, in_specified_namespace)) { + prefix_mutex.lock(); prefix=sm[3].str(); + prefix_mutex.unlock(); if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !selection_dialog.shown) { autocomplete(); } @@ -600,7 +602,9 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this) { autocomplete_cancel_starting=true; } else if(std::regex_match(line, sm, within_namespace)) { + prefix_mutex.lock(); prefix=sm[3].str(); + prefix_mutex.unlock(); if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !selection_dialog.shown) { autocomplete(); } @@ -674,10 +678,8 @@ void Source::ClangViewAutocomplete::autocomplete() { } auto ss_str=ss.str(); if (ss_str.length() > 0) { // if length is 0 the result is empty - if(ss_str.size()>=prefix.size() && ss_str.compare(0, prefix.size(), prefix)==0) { - auto pair=std::pair(ss_str, data.brief_comments); - rows[ss.str() + " --> " + return_value] = pair; - } + auto pair=std::pair(ss_str, data.brief_comments); + rows[ss.str() + " --> " + return_value] = pair; } } if (rows.empty()) { @@ -700,10 +702,9 @@ void Source::ClangViewAutocomplete::autocomplete() { column_nr--; } buffer+="\n"; - auto prefix_copy=prefix; - std::thread autocomplete_thread([this, ac_data, line_nr, column_nr, buffer_map, prefix_copy](){ + std::thread autocomplete_thread([this, ac_data, line_nr, column_nr, buffer_map](){ parsing_mutex.lock(); - *ac_data=move(get_autocomplete_suggestions(line_nr, column_nr, *buffer_map, prefix_copy)); + *ac_data=move(get_autocomplete_suggestions(line_nr, column_nr, *buffer_map)); autocomplete_done(); parsing_mutex.unlock(); }); @@ -713,7 +714,7 @@ void Source::ClangViewAutocomplete::autocomplete() { } std::vector Source::ClangViewAutocomplete:: -get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map, const std::string& prefix) { +get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map) { INFO("Getting auto complete suggestions"); std::vector suggestions; clang::CodeCompleteResults results(clang_tu.get(), @@ -721,21 +722,26 @@ get_autocomplete_suggestions(int line_number, int column, std::map=prefix.size() && chunk.chunk.compare(0, prefix.size(), prefix)==0) - match=true; - break; + if(!autocomplete_cancel_starting) { + prefix_mutex.lock(); + auto prefix_copy=prefix; + prefix_mutex.unlock(); + for (int i = 0; i < results.size(); i++) { + auto result=results.get(i); + if(result.available()) { + auto chunks=result.get_chunks(); + bool match=false; + for(auto &chunk: chunks) { + if(chunk.kind!=clang::CompletionChunk_ResultType && chunk.kind!=clang::CompletionChunk_Informative) { + if(chunk.chunk.size()>=prefix_copy.size() && chunk.chunk.compare(0, prefix_copy.size(), prefix_copy)==0) + match=true; + break; + } + } + if(match) { + suggestions.emplace_back(std::move(chunks)); + suggestions.back().brief_comments=result.get_brief_comments(); } - } - if(match) { - suggestions.emplace_back(std::move(chunks)); - suggestions.back().brief_comments=result.get_brief_comments(); } } } diff --git a/juci/source.h b/juci/source.h index 66ff9ac..51386c0 100644 --- a/juci/source.h +++ b/juci/source.h @@ -131,13 +131,14 @@ namespace Source { private: void autocomplete(); SelectionDialog selection_dialog; - std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map, const std::string& prefix); + std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map); Glib::Dispatcher autocomplete_done; sigc::connection autocomplete_done_connection; bool autocomplete_starting=false; - bool autocomplete_cancel_starting=false; + std::atomic autocomplete_cancel_starting; guint last_keyval=0; std::string prefix; + std::mutex prefix_mutex; }; class Controller { From 4f7afedcc47b54096ac11141c25f7e3c2991a6f2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 13 Jul 2015 00:12:02 +0200 Subject: [PATCH 3/4] Minor autocomplete fixes. --- juci/selectiondialog.cc | 2 +- juci/source.cc | 12 ++++++++++-- juci/source.h | 3 ++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/juci/selectiondialog.cc b/juci/selectiondialog.cc index ca794bc..be51467 100644 --- a/juci/selectiondialog.cc +++ b/juci/selectiondialog.cc @@ -61,8 +61,8 @@ void SelectionDialog::show() { } void SelectionDialog::hide() { - window->hide(); shown=false; + window->hide(); if(tooltips) tooltips->hide(); } diff --git a/juci/source.cc b/juci/source.cc index 49b8595..51c024d 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -580,7 +580,6 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) { ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// -//TODO: Raise autocomplete window after alt-tab back to application Source::ClangViewAutocomplete::ClangViewAutocomplete(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal): Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), autocomplete_cancel_starting(false) { get_buffer()->signal_changed().connect([this](){ @@ -625,7 +624,7 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), a }); signal_scroll_event().connect([this](GdkEventScroll* event){ if(selection_dialog.shown) - selection_dialog.move(); + selection_dialog.hide(); return false; }, false); signal_key_release_event().connect([this](GdkEventKey* key){ @@ -647,6 +646,15 @@ bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { } return ClangView::on_key_press_event(key); } + +bool Source::ClangViewAutocomplete::on_focus_out_event(GdkEventFocus* event) { + if(selection_dialog.shown) { + selection_dialog.hide(); + } + + return Source::ClangView::on_focus_out_event(event); +} + void Source::ClangViewAutocomplete::autocomplete() { if(!autocomplete_starting) { autocomplete_starting=true; diff --git a/juci/source.h b/juci/source.h index 51386c0..40a8ad0 100644 --- a/juci/source.h +++ b/juci/source.h @@ -83,6 +83,7 @@ namespace Source { std::mutex parsing_mutex; sigc::connection delayed_reparse_connection; bool on_key_press_event(GdkEventKey* key); + bool on_focus_out_event(GdkEventFocus* event); private: // inits the syntax highligthing on file open void init_syntax_highlighting(const std::map @@ -99,7 +100,6 @@ namespace Source { bool on_motion_notify_event(GdkEventMotion* event); void on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark); sigc::connection delayed_tooltips_connection; - bool on_focus_out_event(GdkEventFocus* event); bool on_scroll_event(GdkEventScroll* event); static clang::Index clang_index; std::unique_ptr clang_tokens; @@ -128,6 +128,7 @@ namespace Source { ClangViewAutocomplete(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal); protected: bool on_key_press_event(GdkEventKey* key); + bool on_focus_out_event(GdkEventFocus* event); private: void autocomplete(); SelectionDialog selection_dialog; From b9b7d2181ff542d6c717514adae3928e87832477 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 13 Jul 2015 00:48:05 +0200 Subject: [PATCH 4/4] Fixed }-key. --- juci/source.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/juci/source.cc b/juci/source.cc index 51c024d..ad31333 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -561,7 +561,7 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) { if(line.size()>=config->tab_size) { for(auto c: line) { if(c!=config->tab_char) - return false; + return Source::View::on_key_press_event(key); } 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()); @@ -571,7 +571,7 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) { get_source_buffer()->erase(line_it, line_plus_it); } - return false; + return Source::View::on_key_press_event(key); } return Source::View::on_key_press_event(key);