|
|
|
@ -100,9 +100,9 @@ void Source::ClangViewParse::configure() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bracket_regex=std::regex("^([ \\t]*).*\\{ *$"); |
|
|
|
bracket_regex=boost::regex("^([ \\t]*).*\\{ *$"); |
|
|
|
no_bracket_statement_regex=std::regex("^([ \\t]*)(if|for|else if|catch|while) *\\(.*[^;}] *$"); |
|
|
|
no_bracket_statement_regex=boost::regex("^([ \\t]*)(if|for|else if|catch|while) *\\(.*[^;}] *$"); |
|
|
|
no_bracket_no_para_statement_regex=std::regex("^([ \\t]*)(else|try|do) *$"); |
|
|
|
no_bracket_no_para_statement_regex=boost::regex("^([ \\t]*)(else|try|do) *$"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Source::ClangViewParse::init_parse() { |
|
|
|
void Source::ClangViewParse::init_parse() { |
|
|
|
@ -194,9 +194,9 @@ std::vector<std::string> Source::ClangViewParse::get_compilation_commands() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
auto clang_version_string=clang::to_string(clang_getClangVersion()); |
|
|
|
auto clang_version_string=clang::to_string(clang_getClangVersion()); |
|
|
|
const std::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$"); |
|
|
|
const boost::regex clang_version_regex("^[A-Za-z ]+([0-9.]+).*$"); |
|
|
|
std::smatch sm; |
|
|
|
boost::smatch sm; |
|
|
|
if(std::regex_match(clang_version_string, sm, clang_version_regex)) { |
|
|
|
if(boost::regex_match(clang_version_string, sm, clang_version_regex)) { |
|
|
|
auto clang_version=sm[1].str(); |
|
|
|
auto clang_version=sm[1].str(); |
|
|
|
arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include"); |
|
|
|
arguments.emplace_back("-I/usr/lib/clang/"+clang_version+"/include"); |
|
|
|
arguments.emplace_back("-I/usr/local/Cellar/llvm/"+clang_version+"/lib/clang/"+clang_version+"/include"); |
|
|
|
arguments.emplace_back("-I/usr/local/Cellar/llvm/"+clang_version+"/lib/clang/"+clang_version+"/include"); |
|
|
|
@ -464,7 +464,7 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { |
|
|
|
auto start_sentence_tabs_end_iter=get_tabs_end_iter(start_of_sentence_iter); |
|
|
|
auto start_sentence_tabs_end_iter=get_tabs_end_iter(start_of_sentence_iter); |
|
|
|
auto tabs=get_line_before(start_sentence_tabs_end_iter); |
|
|
|
auto tabs=get_line_before(start_sentence_tabs_end_iter); |
|
|
|
|
|
|
|
|
|
|
|
std::smatch sm; |
|
|
|
boost::smatch sm; |
|
|
|
if(iter.backward_char() && *iter=='{') { |
|
|
|
if(iter.backward_char() && *iter=='{') { |
|
|
|
auto found_iter=iter; |
|
|
|
auto found_iter=iter; |
|
|
|
bool found_right_bracket=find_right_bracket_forward(iter, found_iter); |
|
|
|
bool found_right_bracket=find_right_bracket_forward(iter, found_iter); |
|
|
|
@ -516,13 +516,13 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { |
|
|
|
iter.forward_char(); |
|
|
|
iter.forward_char(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if(std::regex_match(line, sm, no_bracket_statement_regex)) { |
|
|
|
else if(boost::regex_match(line, sm, no_bracket_statement_regex)) { |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if(std::regex_match(line, sm, no_bracket_no_para_statement_regex)) { |
|
|
|
else if(boost::regex_match(line, sm, no_bracket_no_para_statement_regex)) { |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
@ -530,18 +530,18 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { |
|
|
|
} |
|
|
|
} |
|
|
|
//Indenting after for instance if(...)\n...;\n
|
|
|
|
//Indenting after for instance if(...)\n...;\n
|
|
|
|
else if(iter.backward_char() && *iter==';') { |
|
|
|
else if(iter.backward_char() && *iter==';') { |
|
|
|
std::smatch sm2; |
|
|
|
boost::smatch sm2; |
|
|
|
size_t line_nr=get_source_buffer()->get_insert()->get_iter().get_line(); |
|
|
|
size_t line_nr=get_source_buffer()->get_insert()->get_iter().get_line(); |
|
|
|
if(line_nr>0 && tabs.size()>=tab_size) { |
|
|
|
if(line_nr>0 && tabs.size()>=tab_size) { |
|
|
|
std::string previous_line=get_line(line_nr-1); |
|
|
|
std::string previous_line=get_line(line_nr-1); |
|
|
|
if(!std::regex_match(previous_line, sm2, bracket_regex)) { |
|
|
|
if(!boost::regex_match(previous_line, sm2, bracket_regex)) { |
|
|
|
if(std::regex_match(previous_line, sm2, no_bracket_statement_regex)) { |
|
|
|
if(boost::regex_match(previous_line, sm2, no_bracket_statement_regex)) { |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if(std::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) { |
|
|
|
else if(boost::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) { |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); |
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
@ -558,7 +558,7 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { |
|
|
|
left_bracket_iter.forward_char(); |
|
|
|
left_bracket_iter.forward_char(); |
|
|
|
Gtk::TextIter start_of_left_bracket_sentence_iter; |
|
|
|
Gtk::TextIter start_of_left_bracket_sentence_iter; |
|
|
|
if(find_start_of_closed_expression(left_bracket_iter, start_of_left_bracket_sentence_iter)) { |
|
|
|
if(find_start_of_closed_expression(left_bracket_iter, start_of_left_bracket_sentence_iter)) { |
|
|
|
std::smatch sm; |
|
|
|
boost::smatch sm; |
|
|
|
auto tabs_end_iter=get_tabs_end_iter(start_of_left_bracket_sentence_iter); |
|
|
|
auto tabs_end_iter=get_tabs_end_iter(start_of_left_bracket_sentence_iter); |
|
|
|
auto tabs_start_of_sentence=get_line_before(tabs_end_iter); |
|
|
|
auto tabs_start_of_sentence=get_line_before(tabs_end_iter); |
|
|
|
if(tabs.size()==(tabs_start_of_sentence.size()+tab_size)) { |
|
|
|
if(tabs.size()==(tabs_start_of_sentence.size()+tab_size)) { |
|
|
|
@ -689,10 +689,10 @@ void Source::ClangViewAutocomplete::start_autocomplete() { |
|
|
|
} |
|
|
|
} |
|
|
|
std::string line=" "+get_line_before(); |
|
|
|
std::string line=" "+get_line_before(); |
|
|
|
if((std::count(line.begin(), line.end(), '\"')%2)!=1 && line.find("//")==std::string::npos) { |
|
|
|
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 boost::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,})$"); |
|
|
|
const boost::regex within_namespace("^(.*)([^a-zA-Z0-9_]+)([a-zA-Z0-9_]{3,})$"); |
|
|
|
std::smatch sm; |
|
|
|
boost::smatch sm; |
|
|
|
if(std::regex_match(line, sm, in_specified_namespace)) { |
|
|
|
if(boost::regex_match(line, sm, in_specified_namespace)) { |
|
|
|
prefix_mutex.lock(); |
|
|
|
prefix_mutex.lock(); |
|
|
|
prefix=sm[3].str(); |
|
|
|
prefix=sm[3].str(); |
|
|
|
prefix_mutex.unlock(); |
|
|
|
prefix_mutex.unlock(); |
|
|
|
@ -702,7 +702,7 @@ void Source::ClangViewAutocomplete::start_autocomplete() { |
|
|
|
else if(last_keyval=='.' && autocomplete_starting) |
|
|
|
else if(last_keyval=='.' && autocomplete_starting) |
|
|
|
autocomplete_cancel_starting=true; |
|
|
|
autocomplete_cancel_starting=true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if(std::regex_match(line, sm, within_namespace)) { |
|
|
|
else if(boost::regex_match(line, sm, within_namespace)) { |
|
|
|
prefix_mutex.lock(); |
|
|
|
prefix_mutex.lock(); |
|
|
|
prefix=sm[3].str(); |
|
|
|
prefix=sm[3].str(); |
|
|
|
prefix_mutex.unlock(); |
|
|
|
prefix_mutex.unlock(); |
|
|
|
@ -984,7 +984,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
if(referenced) |
|
|
|
if(referenced) |
|
|
|
return Token(static_cast<int>(referenced.get_kind()), token.get_spelling(), referenced.get_usr()); |
|
|
|
return Token(this->language, static_cast<int>(referenced.get_kind()), token.get_spelling(), referenced.get_usr()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -994,7 +994,8 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
|
|
|
|
|
|
|
|
rename_similar_tokens=[this](const Token &token, const std::string &text) { |
|
|
|
rename_similar_tokens=[this](const Token &token, const std::string &text) { |
|
|
|
size_t number=0; |
|
|
|
size_t number=0; |
|
|
|
if(source_readable) { |
|
|
|
if(source_readable && token.language && |
|
|
|
|
|
|
|
(token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) { |
|
|
|
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr); |
|
|
|
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr); |
|
|
|
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > marks; |
|
|
|
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > marks; |
|
|
|
for(auto &offset: offsets) { |
|
|
|
for(auto &offset: offsets) { |
|
|
|
@ -1027,7 +1028,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
get_declaration_location=[this](){ |
|
|
|
get_declaration_location=[this](){ |
|
|
|
std::pair<std::string, Offset> location; |
|
|
|
Offset location; |
|
|
|
if(source_readable) { |
|
|
|
if(source_readable) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto line=(unsigned)iter.get_line(); |
|
|
|
auto line=(unsigned)iter.get_line(); |
|
|
|
@ -1038,10 +1039,10 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
if(referenced) { |
|
|
|
if(referenced) { |
|
|
|
location.first=referenced.get_source_location().get_path(); |
|
|
|
location.file_path=referenced.get_source_location().get_path(); |
|
|
|
auto clang_offset=referenced.get_source_location().get_offset(); |
|
|
|
auto clang_offset=referenced.get_source_location().get_offset(); |
|
|
|
location.second.line=clang_offset.line; |
|
|
|
location.line=clang_offset.line; |
|
|
|
location.second.index=clang_offset.index; |
|
|
|
location.index=clang_offset.index; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1051,6 +1052,49 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
return location; |
|
|
|
return location; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_usages=[this](const Token &token) { |
|
|
|
|
|
|
|
std::vector<std::pair<Offset, std::string> > usages; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(source_readable && token.language && |
|
|
|
|
|
|
|
(token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) { |
|
|
|
|
|
|
|
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr); |
|
|
|
|
|
|
|
for(auto &offset: offsets) { |
|
|
|
|
|
|
|
size_t whitespaces_removed=0; |
|
|
|
|
|
|
|
auto start_iter=get_buffer()->get_iter_at_line(offset.first.line-1); |
|
|
|
|
|
|
|
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) { |
|
|
|
|
|
|
|
start_iter.forward_char(); |
|
|
|
|
|
|
|
whitespaces_removed++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
auto end_iter=start_iter; |
|
|
|
|
|
|
|
while(!end_iter.ends_line()) |
|
|
|
|
|
|
|
end_iter.forward_char(); |
|
|
|
|
|
|
|
std::string line=Glib::Markup::escape_text(get_buffer()->get_text(start_iter, end_iter)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//markup token as bold
|
|
|
|
|
|
|
|
size_t token_start_pos=offset.first.index-1-whitespaces_removed; |
|
|
|
|
|
|
|
size_t token_end_pos=offset.second.index-1-whitespaces_removed; |
|
|
|
|
|
|
|
size_t pos=0; |
|
|
|
|
|
|
|
while((pos=line.find('&', pos))!=std::string::npos) { |
|
|
|
|
|
|
|
size_t pos2=line.find(';', pos+2); |
|
|
|
|
|
|
|
if(token_start_pos>pos) { |
|
|
|
|
|
|
|
token_start_pos+=pos2-pos; |
|
|
|
|
|
|
|
token_end_pos+=pos2-pos; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(token_end_pos>pos) |
|
|
|
|
|
|
|
token_end_pos+=pos2-pos; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
pos=pos2+1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
line.insert(token_end_pos, "</b>"); |
|
|
|
|
|
|
|
line.insert(token_start_pos, "<b>"); |
|
|
|
|
|
|
|
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), line); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return usages; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
goto_method=[this](){
|
|
|
|
goto_method=[this](){
|
|
|
|
if(source_readable) { |
|
|
|
if(source_readable) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
@ -1062,14 +1106,43 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
if(!visible_rect.intersects(iter_rect)) { |
|
|
|
if(!visible_rect.intersects(iter_rect)) { |
|
|
|
get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); |
|
|
|
get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); |
|
|
|
} |
|
|
|
} |
|
|
|
selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(iter))); |
|
|
|
selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true)); |
|
|
|
auto rows=std::make_shared<std::unordered_map<std::string, clang::Offset> >(); |
|
|
|
auto rows=std::make_shared<std::unordered_map<std::string, clang::Offset> >(); |
|
|
|
auto methods=clang_tokens->get_cxx_methods(); |
|
|
|
auto methods=clang_tokens->get_cxx_methods(); |
|
|
|
if(methods.size()==0) |
|
|
|
if(methods.size()==0) |
|
|
|
return; |
|
|
|
return; |
|
|
|
for(auto &method: methods) { |
|
|
|
for(auto &method: methods) { |
|
|
|
(*rows)[method.first]=method.second; |
|
|
|
std::string row=std::to_string(method.second.line)+": "+Glib::Markup::escape_text(method.first); |
|
|
|
selection_dialog->add_row(method.first); |
|
|
|
//Add bold method token
|
|
|
|
|
|
|
|
size_t token_end_pos=row.find('('); |
|
|
|
|
|
|
|
if(token_end_pos==0 || token_end_pos==std::string::npos) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
if(token_end_pos>8 && row.substr(token_end_pos-4, 4)==">") { |
|
|
|
|
|
|
|
token_end_pos-=8; |
|
|
|
|
|
|
|
size_t angle_bracket_count=1; |
|
|
|
|
|
|
|
do { |
|
|
|
|
|
|
|
if(row.substr(token_end_pos-4, 4)==">") { |
|
|
|
|
|
|
|
angle_bracket_count++; |
|
|
|
|
|
|
|
token_end_pos-=4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(row.substr(token_end_pos-4, 4)=="<") { |
|
|
|
|
|
|
|
angle_bracket_count--; |
|
|
|
|
|
|
|
token_end_pos-=4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
token_end_pos--; |
|
|
|
|
|
|
|
} while(angle_bracket_count>0 && token_end_pos>4); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
auto pos=token_end_pos; |
|
|
|
|
|
|
|
do { |
|
|
|
|
|
|
|
pos--; |
|
|
|
|
|
|
|
} while(((row[pos]>='a' && row[pos]<='z') || |
|
|
|
|
|
|
|
(row[pos]>='A' && row[pos]<='Z') || |
|
|
|
|
|
|
|
(row[pos]>='0' && row[pos]<='9') || row[pos]=='_' || row[pos]=='~') && pos>0); |
|
|
|
|
|
|
|
row.insert(token_end_pos, "</b>"); |
|
|
|
|
|
|
|
row.insert(pos+1, "<b>"); |
|
|
|
|
|
|
|
(*rows)[row]=method.second; |
|
|
|
|
|
|
|
selection_dialog->add_row(row); |
|
|
|
} |
|
|
|
} |
|
|
|
selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { |
|
|
|
selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { |
|
|
|
auto offset=rows->at(selected); |
|
|
|
auto offset=rows->at(selected); |
|
|
|
|