|
|
|
|
@ -7,7 +7,6 @@
|
|
|
|
|
#include <algorithm> |
|
|
|
|
#include <regex> |
|
|
|
|
#include "singletons.h" |
|
|
|
|
#include "notebook.h" //TODO: remove |
|
|
|
|
|
|
|
|
|
namespace sigc { |
|
|
|
|
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE |
|
|
|
|
@ -151,6 +150,9 @@ clang::Index Source::ClangView::clang_index(0, 0);
|
|
|
|
|
Source::ClangView::ClangView(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal): |
|
|
|
|
Source::View(file_path, project_path), terminal(terminal), |
|
|
|
|
parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { |
|
|
|
|
similar_tokens_tag=get_buffer()->create_tag(); |
|
|
|
|
similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD; |
|
|
|
|
|
|
|
|
|
int start_offset = get_source_buffer()->begin().get_offset(); |
|
|
|
|
int end_offset = get_source_buffer()->end().get_offset(); |
|
|
|
|
auto buffer_map=get_buffer_map(); |
|
|
|
|
@ -222,16 +224,20 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
|
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
get_source_buffer()->signal_changed().connect([this]() { |
|
|
|
|
get_buffer()->signal_changed().connect([this]() { |
|
|
|
|
parse_thread_mapped=false; |
|
|
|
|
clang_readable=false; |
|
|
|
|
delayed_reparse_connection.disconnect(); |
|
|
|
|
delayed_reparse_connection=Glib::signal_timeout().connect([this]() { |
|
|
|
|
clang_readable=false; |
|
|
|
|
parse_thread_go=true; |
|
|
|
|
return false; |
|
|
|
|
}, 1000); |
|
|
|
|
type_tooltips.hide(); |
|
|
|
|
diagnostic_tooltips.hide(); |
|
|
|
|
if(last_similar_token_marked!="") { |
|
|
|
|
get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); |
|
|
|
|
last_similar_token_marked=""; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangView::on_mark_set), false); |
|
|
|
|
@ -427,18 +433,32 @@ void Source::ClangView::on_mark_set(const Gtk::TextBuffer::iterator& iterator, c
|
|
|
|
|
type_tooltips.hide(); |
|
|
|
|
diagnostic_tooltips.hide(); |
|
|
|
|
|
|
|
|
|
//TODO: For testing purposes
|
|
|
|
|
bool found=false; |
|
|
|
|
if(clang_readable) { |
|
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
|
if(token.has_type()) { |
|
|
|
|
auto range_data=token.source_range.get_range_data(); |
|
|
|
|
auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset(); |
|
|
|
|
auto insert_offset=(unsigned)get_buffer()->get_insert()->get_iter().get_offset(); |
|
|
|
|
if(range_data.path==file_path && insert_offset>=range_data.start_offset && insert_offset<=range_data.end_offset) { |
|
|
|
|
//cout << token.get_type() << endl;
|
|
|
|
|
found=true; |
|
|
|
|
auto referenced_usr_and_token_spelling=token.get_cursor().get_referenced_usr()+token.get_token_spelling(); |
|
|
|
|
if(last_similar_token_marked!=referenced_usr_and_token_spelling) { |
|
|
|
|
get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); |
|
|
|
|
auto offsets=clang_tokens->get_similar_token_offsets(token); |
|
|
|
|
for(auto &offset: offsets) { |
|
|
|
|
get_buffer()->apply_tag(similar_tokens_tag, get_buffer()->get_iter_at_offset(offset.first), get_buffer()->get_iter_at_offset(offset.second)); |
|
|
|
|
} |
|
|
|
|
last_similar_token_marked=referenced_usr_and_token_spelling; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(!found && last_similar_token_marked!="") { |
|
|
|
|
get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); |
|
|
|
|
last_similar_token_marked=""; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -482,6 +502,7 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//TODO: insert without moving mark backwards.
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm[1].str()+config->tab+"\n"+sm[1].str()+"}"); |
|
|
|
|
auto insert_it = get_source_buffer()->get_insert()->get_iter(); |
|
|
|
|
for(size_t c=0;c<config->tab_size+sm[1].str().size();c++) |
|
|
|
|
@ -547,14 +568,21 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) {
|
|
|
|
|
//////////////////////////////
|
|
|
|
|
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) { |
|
|
|
|
selection_dialog.on_hide=[this](){ |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
get_buffer()->signal_changed().connect([this](){ |
|
|
|
|
if(last_keyval==GDK_KEY_BackSpace) |
|
|
|
|
if(selection_dialog.shown) |
|
|
|
|
delayed_reparse_connection.disconnect(); |
|
|
|
|
const std::regex autocomplete_keys("[a-zA-Z0-9_>\\.:]"); |
|
|
|
|
std::smatch sm; |
|
|
|
|
if(!std::regex_match(std::string()+(char)last_keyval, sm, autocomplete_keys)) |
|
|
|
|
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 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(); |
|
|
|
|
@ -605,7 +633,6 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), a
|
|
|
|
|
bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { |
|
|
|
|
last_keyval=key->keyval; |
|
|
|
|
if(selection_dialog.shown) { |
|
|
|
|
delayed_reparse_connection.disconnect(); |
|
|
|
|
if(selection_dialog.on_key_press(key)) |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|