Browse Source

Autocomplete no longer freezes the application while loading.

merge-requests/365/head
eidheim 11 years ago
parent
commit
459cfe4823
  1. 103
      juci/source.cc
  2. 6
      juci/source.h

103
juci/source.cc

@ -186,13 +186,16 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
parsing_in_progress=this->terminal.print_in_progress("Parsing "+file_path); parsing_in_progress=this->terminal.print_in_progress("Parsing "+file_path);
parse_done.connect([this](){ parse_done.connect([this](){
if(parse_thread_mapped) { if(parse_thread_mapped) {
INFO("Updating syntax"); if(parsing_mutex.try_lock()) {
update_syntax(extract_tokens(0, get_source_buffer()->get_text().size())); INFO("Updating syntax");
update_diagnostics(); update_syntax(extract_tokens(0, get_source_buffer()->get_text().size()));
update_types(); update_diagnostics();
clang_updated=true; update_types();
clang_updated=true;
parsing_mutex.unlock();
INFO("Syntax updated");
}
parsing_in_progress->done("done"); parsing_in_progress->done("done");
INFO("Syntax updated");
} }
else { else {
parse_thread_go=true; parse_thread_go=true;
@ -219,7 +222,13 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
} }
}); });
autocomplete_done.connect([this](){
if(autocomplete_done_function)
autocomplete_done_function();
});
get_source_buffer()->signal_changed().connect([this]() { get_source_buffer()->signal_changed().connect([this]() {
autocomplete_cancel=true;
parse_thread_mapped=false; parse_thread_mapped=false;
clang_updated=false; clang_updated=false;
parse_thread_go=true; parse_thread_go=true;
@ -269,13 +278,9 @@ reparse(const std::map<std::string, std::string> &buffer) {
} }
std::vector<Source::AutoCompleteData> Source::ClangView:: std::vector<Source::AutoCompleteData> Source::ClangView::
get_autocomplete_suggestions(int line_number, int column) { get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map) {
INFO("Getting auto complete suggestions"); INFO("Getting auto complete suggestions");
std::vector<Source::AutoCompleteData> suggestions; std::vector<Source::AutoCompleteData> suggestions;
std::map<std::string, std::string> buffer_map;
buffer_map[file_path]=get_source_buffer()->get_text(get_source_buffer()->begin(), get_source_buffer()->get_insert()->get_iter());
buffer_map[file_path]+="\n";
parsing_mutex.lock();
clang::CodeCompleteResults results(clang_tu.get(), clang::CodeCompleteResults results(clang_tu.get(),
file_path, file_path,
buffer_map, buffer_map,
@ -289,7 +294,6 @@ get_autocomplete_suggestions(int line_number, int column) {
} }
suggestions.emplace_back(chunks); suggestions.emplace_back(chunks);
} }
parsing_mutex.unlock();
DEBUG("Number of suggestions"); DEBUG("Number of suggestions");
DEBUG_VAR(suggestions.size()); DEBUG_VAR(suggestions.size());
return suggestions; return suggestions;
@ -561,33 +565,62 @@ bool Source::ClangView::on_key_release(GdkEventKey* key) {
} else { } else {
return false; return false;
} }
INFO("Source::ClangView::on_key_release getting autocompletions"); if(!autocomplete_running) {
std::vector<Source::AutoCompleteData> acdata=get_autocomplete_suggestions(beg.get_line()+1, autocomplete_running=true;
beg.get_line_offset()+2); autocomplete_cancel=false;
std::map<std::string, std::string> rows; INFO("Source::ClangView::on_key_release getting autocompletions");
for (auto &data : acdata) { std::shared_ptr<std::vector<Source::AutoCompleteData> > ac_data=std::make_shared<std::vector<Source::AutoCompleteData> >();
std::stringstream ss; autocomplete_done_function=[this, ac_data](){
std::string return_value; if(!autocomplete_cancel) {
for (auto &chunk : data.chunks) { std::map<std::string, std::string> rows;
switch (chunk.kind) { for (auto &data : *ac_data) {
case clang::CompletionChunk_ResultType: std::stringstream ss;
return_value = chunk.chunk; std::string return_value;
break; for (auto &chunk : data.chunks) {
case clang::CompletionChunk_Informative: break; switch (chunk.kind) {
default: ss << chunk.chunk; break; case clang::CompletionChunk_ResultType:
return_value = chunk.chunk;
break;
case clang::CompletionChunk_Informative: break;
default: ss << chunk.chunk; break;
}
}
if (ss.str().length() > 0) { // if length is 0 the result is empty
rows[ss.str() + " --> " + return_value] = ss.str();
}
}
if (rows.empty()) {
rows["No suggestions found..."] = "";
}
selection_dialog.rows=std::move(rows);
selection_dialog.show();
} }
} autocomplete_running=false;
if (ss.str().length() > 0) { // if length is 0 the result is empty };
rows[ss.str() + " --> " + return_value] = ss.str();
} std::shared_ptr<std::map<std::string, std::string> > buffer_map=std::make_shared<std::map<std::string, std::string> >();
(*buffer_map)[file_path]=get_buffer()->get_text(get_buffer()->begin(), get_buffer()->get_insert()->get_iter());
(*buffer_map)[file_path]+="\n";
auto line_nr=beg.get_line()+1;
auto column_nr=beg.get_line_offset()+2;
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));
autocomplete_done();
parsing_mutex.unlock();
});
autocomplete_thread.detach();
} }
if (rows.empty()) { else {
rows["No suggestions found..."] = ""; std::map<std::string, std::string> rows;
rows["Autocomplete already running, try again."] = "";
selection_dialog.rows=std::move(rows);
selection_dialog.show();
} }
selection_dialog.rows=std::move(rows);
selection_dialog.show();
return true; return false;
} }
//Clang indentation //Clang indentation

6
juci/source.h

@ -93,7 +93,7 @@ namespace Source {
int start_offset, int start_offset,
int end_offset, int end_offset,
clang::Index *index); clang::Index *index);
std::vector<Source::AutoCompleteData> get_autocomplete_suggestions(int line_number, int column); std::vector<Source::AutoCompleteData> get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map);
SelectionDialog selection_dialog; SelectionDialog selection_dialog;
int reparse(const std::map<std::string, std::string> &buffers); int reparse(const std::map<std::string, std::string> &buffers);
std::vector<Range> extract_tokens(int, int); std::vector<Range> extract_tokens(int, int);
@ -126,6 +126,10 @@ namespace Source {
Terminal::Controller& terminal; Terminal::Controller& terminal;
std::shared_ptr<Terminal::InProgress> parsing_in_progress; std::shared_ptr<Terminal::InProgress> parsing_in_progress;
Glib::Dispatcher autocomplete_done;
std::function<void()> autocomplete_done_function;
bool autocomplete_running=false;
bool autocomplete_cancel=false;
Glib::Dispatcher parse_done; Glib::Dispatcher parse_done;
Glib::Dispatcher parse_start; Glib::Dispatcher parse_start;
std::thread parse_thread; std::thread parse_thread;

Loading…
Cancel
Save