|
|
|
@ -5,6 +5,7 @@ |
|
|
|
#ifdef JUCI_ENABLE_DEBUG |
|
|
|
#ifdef JUCI_ENABLE_DEBUG |
|
|
|
#include "debug_clang.h" |
|
|
|
#include "debug_clang.h" |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "info.h" |
|
|
|
|
|
|
|
|
|
|
|
namespace sigc { |
|
|
|
namespace sigc { |
|
|
|
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE |
|
|
|
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE |
|
|
|
@ -222,9 +223,9 @@ void Source::ClangViewParse::update_syntax() { |
|
|
|
if(token.get_kind()==1) // KeywordToken
|
|
|
|
if(token.get_kind()==1) // KeywordToken
|
|
|
|
ranges.emplace_back(token.offsets, 702); |
|
|
|
ranges.emplace_back(token.offsets, 702); |
|
|
|
else if(token.get_kind()==2) {// IdentifierToken
|
|
|
|
else if(token.get_kind()==2) {// IdentifierToken
|
|
|
|
auto kind=(int)token.get_cursor().get_kind(); |
|
|
|
auto kind=static_cast<int>(token.get_cursor().get_kind()); |
|
|
|
if(kind==101 || kind==102) |
|
|
|
if(kind==101 || kind==102) |
|
|
|
kind=(int)token.get_cursor().get_referenced().get_kind(); |
|
|
|
kind=static_cast<int>(token.get_cursor().get_referenced().get_kind()); |
|
|
|
if(kind!=500) |
|
|
|
if(kind!=500) |
|
|
|
ranges.emplace_back(token.offsets, kind); |
|
|
|
ranges.emplace_back(token.offsets, kind); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -859,20 +860,22 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
get_token=[this]() -> Token { |
|
|
|
get_token=[this]() -> Token { |
|
|
|
if(parsed) { |
|
|
|
if(!parsed) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
auto line=(unsigned)iter.get_line(); |
|
|
|
return Token(); |
|
|
|
auto index=(unsigned)iter.get_line_index(); |
|
|
|
} |
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto cursor=token.get_cursor(); |
|
|
|
auto line=static_cast<unsigned>(iter.get_line()); |
|
|
|
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
auto index=static_cast<unsigned>(iter.get_line_index()); |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
if(static_cast<unsigned>(token.get_cursor().get_kind())==103) //These cursors are buggy
|
|
|
|
auto cursor=token.get_cursor(); |
|
|
|
continue; |
|
|
|
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
if(referenced) |
|
|
|
if(static_cast<unsigned>(token.get_cursor().get_kind())==103) //These cursors are buggy
|
|
|
|
return Token(this->language, static_cast<int>(referenced.get_kind()), token.get_spelling(), referenced.get_usr()); |
|
|
|
continue; |
|
|
|
} |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
|
|
|
|
if(referenced) |
|
|
|
|
|
|
|
return Token(this->language, static_cast<int>(referenced.get_kind()), token.get_spelling(), referenced.get_usr()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -907,7 +910,9 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
if(mark->get_name()=="insert") { |
|
|
|
if(mark->get_name()=="insert") { |
|
|
|
delayed_tag_similar_tokens_connection.disconnect(); |
|
|
|
delayed_tag_similar_tokens_connection.disconnect(); |
|
|
|
delayed_tag_similar_tokens_connection=Glib::signal_timeout().connect([this]() { |
|
|
|
delayed_tag_similar_tokens_connection=Glib::signal_timeout().connect([this]() { |
|
|
|
|
|
|
|
Info::get().enabled=false; |
|
|
|
auto token=get_token(); |
|
|
|
auto token=get_token(); |
|
|
|
|
|
|
|
Info::get().enabled=true; |
|
|
|
tag_similar_tokens(token); |
|
|
|
tag_similar_tokens(token); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
}, 100); |
|
|
|
}, 100); |
|
|
|
@ -916,22 +921,24 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
|
|
|
|
|
|
|
|
get_declaration_location=[this](){ |
|
|
|
get_declaration_location=[this](){ |
|
|
|
Offset location; |
|
|
|
Offset location; |
|
|
|
if(parsed) { |
|
|
|
if(!parsed) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
auto line=(unsigned)iter.get_line(); |
|
|
|
return location; |
|
|
|
auto index=(unsigned)iter.get_line_index(); |
|
|
|
} |
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto cursor=token.get_cursor(); |
|
|
|
auto line=static_cast<unsigned>(iter.get_line()); |
|
|
|
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
auto index=static_cast<unsigned>(iter.get_line_index()); |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
auto cursor=token.get_cursor(); |
|
|
|
if(referenced) { |
|
|
|
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
location.file_path=referenced.get_source_location().get_path(); |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
auto clang_offset=referenced.get_source_location().get_offset(); |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
location.line=clang_offset.line; |
|
|
|
if(referenced) { |
|
|
|
location.index=clang_offset.index; |
|
|
|
location.file_path=referenced.get_source_location().get_path(); |
|
|
|
break; |
|
|
|
auto clang_offset=referenced.get_source_location().get_offset(); |
|
|
|
} |
|
|
|
location.line=clang_offset.line; |
|
|
|
|
|
|
|
location.index=clang_offset.index; |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -965,7 +972,6 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
|
|
|
|
|
|
|
|
get_usages=[this](const Token &token) { |
|
|
|
get_usages=[this](const Token &token) { |
|
|
|
std::vector<std::pair<Offset, std::string> > usages; |
|
|
|
std::vector<std::pair<Offset, std::string> > usages; |
|
|
|
|
|
|
|
|
|
|
|
if(parsed && token.language && |
|
|
|
if(parsed && 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")) { |
|
|
|
(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); |
|
|
|
@ -1006,55 +1012,57 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
return usages; |
|
|
|
return usages; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
goto_method=[this](){
|
|
|
|
goto_method=[this](){ |
|
|
|
if(parsed) { |
|
|
|
if(!parsed) { |
|
|
|
auto iter=get_iter_for_dialog(); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true)); |
|
|
|
return; |
|
|
|
auto rows=std::make_shared<std::unordered_map<std::string, clang::Offset> >(); |
|
|
|
} |
|
|
|
auto methods=clang_tokens->get_cxx_methods(); |
|
|
|
auto iter=get_iter_for_dialog(); |
|
|
|
if(methods.size()==0) |
|
|
|
selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true)); |
|
|
|
return; |
|
|
|
auto rows=std::make_shared<std::unordered_map<std::string, clang::Offset> >(); |
|
|
|
for(auto &method: methods) { |
|
|
|
auto methods=clang_tokens->get_cxx_methods(); |
|
|
|
std::string row=std::to_string(method.second.line)+": "+Glib::Markup::escape_text(method.first); |
|
|
|
if(methods.size()==0) |
|
|
|
//Add bold method token
|
|
|
|
return; |
|
|
|
size_t token_end_pos=row.find('('); |
|
|
|
for(auto &method: methods) { |
|
|
|
if(token_end_pos==0 || token_end_pos==std::string::npos) |
|
|
|
std::string row=std::to_string(method.second.line)+": "+Glib::Markup::escape_text(method.first); |
|
|
|
continue; |
|
|
|
//Add bold method token
|
|
|
|
if(token_end_pos>8 && row.substr(token_end_pos-4, 4)==">") { |
|
|
|
size_t token_end_pos=row.find('('); |
|
|
|
token_end_pos-=8; |
|
|
|
if(token_end_pos==0 || token_end_pos==std::string::npos) |
|
|
|
size_t angle_bracket_count=1; |
|
|
|
continue; |
|
|
|
do { |
|
|
|
if(token_end_pos>8 && row.substr(token_end_pos-4, 4)==">") { |
|
|
|
if(row.substr(token_end_pos-4, 4)==">") { |
|
|
|
token_end_pos-=8; |
|
|
|
angle_bracket_count++; |
|
|
|
size_t angle_bracket_count=1; |
|
|
|
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 { |
|
|
|
do { |
|
|
|
pos--; |
|
|
|
if(row.substr(token_end_pos-4, 4)==">") { |
|
|
|
} while(((row[pos]>='a' && row[pos]<='z') || |
|
|
|
angle_bracket_count++; |
|
|
|
(row[pos]>='A' && row[pos]<='Z') || |
|
|
|
token_end_pos-=4; |
|
|
|
(row[pos]>='0' && row[pos]<='9') || row[pos]=='_' || row[pos]=='~') && pos>0); |
|
|
|
} |
|
|
|
row.insert(token_end_pos, "</b>"); |
|
|
|
else if(row.substr(token_end_pos-4, 4)=="<") { |
|
|
|
row.insert(pos+1, "<b>"); |
|
|
|
angle_bracket_count--; |
|
|
|
(*rows)[row]=method.second; |
|
|
|
token_end_pos-=4; |
|
|
|
selection_dialog->add_row(row); |
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
token_end_pos--; |
|
|
|
|
|
|
|
} while(angle_bracket_count>0 && token_end_pos>4); |
|
|
|
} |
|
|
|
} |
|
|
|
selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { |
|
|
|
auto pos=token_end_pos; |
|
|
|
auto offset=rows->at(selected); |
|
|
|
do { |
|
|
|
get_buffer()->place_cursor(get_buffer()->get_iter_at_line_index(offset.line-1, offset.index-1)); |
|
|
|
pos--; |
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
} while(((row[pos]>='a' && row[pos]<='z') || |
|
|
|
delayed_tooltips_connection.disconnect(); |
|
|
|
(row[pos]>='A' && row[pos]<='Z') || |
|
|
|
}; |
|
|
|
(row[pos]>='0' && row[pos]<='9') || row[pos]=='_' || row[pos]=='~') && pos>0); |
|
|
|
selection_dialog->show(); |
|
|
|
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) { |
|
|
|
|
|
|
|
auto offset=rows->at(selected); |
|
|
|
|
|
|
|
get_buffer()->place_cursor(get_buffer()->get_iter_at_line_index(offset.line-1, offset.index-1)); |
|
|
|
|
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
|
|
|
|
delayed_tooltips_connection.disconnect(); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
selection_dialog->show(); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
get_token_data=[this]() { |
|
|
|
get_token_data=[this]() { |
|
|
|
@ -1070,85 +1078,87 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> data; |
|
|
|
std::vector<std::string> data; |
|
|
|
if(parsed) { |
|
|
|
if(!parsed) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
auto line=(unsigned)iter.get_line(); |
|
|
|
return data; |
|
|
|
auto index=(unsigned)iter.get_line_index(); |
|
|
|
} |
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto cursor=token.get_cursor(); |
|
|
|
auto line=static_cast<unsigned>(iter.get_line()); |
|
|
|
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
auto index=static_cast<unsigned>(iter.get_line_index()); |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
for(auto &token: *clang_tokens) { |
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
auto cursor=token.get_cursor(); |
|
|
|
if(referenced) { |
|
|
|
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { |
|
|
|
auto usr=referenced.get_usr(); |
|
|
|
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { |
|
|
|
|
|
|
|
auto referenced=cursor.get_referenced(); |
|
|
|
data.emplace_back("clang"); |
|
|
|
if(referenced) { |
|
|
|
|
|
|
|
auto usr=referenced.get_usr(); |
|
|
|
//namespace
|
|
|
|
|
|
|
|
size_t pos1, pos2=0; |
|
|
|
data.emplace_back("clang"); |
|
|
|
while((pos1=usr.find('@', pos2))!=std::string::npos && pos1+1<usr.size() && usr[pos1+1]=='N') { |
|
|
|
|
|
|
|
pos1+=3; |
|
|
|
//namespace
|
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
size_t pos1, pos2=0; |
|
|
|
if(pos2!=std::string::npos) { |
|
|
|
while((pos1=usr.find('@', pos2))!=std::string::npos && pos1+1<usr.size() && usr[pos1+1]=='N') { |
|
|
|
auto ns=usr.substr(pos1, pos2-pos1); |
|
|
|
pos1+=3; |
|
|
|
if(ns=="__1") |
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
break; |
|
|
|
if(pos2!=std::string::npos) { |
|
|
|
data.emplace_back(ns); |
|
|
|
auto ns=usr.substr(pos1, pos2-pos1); |
|
|
|
} |
|
|
|
if(ns=="__1") |
|
|
|
else |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(data.size()==1) |
|
|
|
|
|
|
|
data.emplace_back(""); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//template arguments
|
|
|
|
|
|
|
|
size_t template_pos=usr.find('$'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool found_type_or_function=false; |
|
|
|
|
|
|
|
//type
|
|
|
|
|
|
|
|
pos2=0; |
|
|
|
|
|
|
|
while(((pos1=usr.find("T@", pos2))!=std::string::npos || (pos1=usr.find("S@", pos2))!=std::string::npos) && pos1<template_pos) { |
|
|
|
|
|
|
|
found_type_or_function=true; |
|
|
|
|
|
|
|
pos1+=2; |
|
|
|
|
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
|
|
|
|
if(pos2!=std::string::npos) |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1, pos2-pos1)); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1)); |
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
data.emplace_back(ns); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//function/constant//variable
|
|
|
|
|
|
|
|
pos1=usr.find("F@"); |
|
|
|
|
|
|
|
if(pos1==std::string::npos) |
|
|
|
|
|
|
|
pos1=usr.find("C@"); |
|
|
|
|
|
|
|
if(pos1==std::string::npos) |
|
|
|
|
|
|
|
pos1=usr.find("I@"); |
|
|
|
|
|
|
|
if(pos1!=std::string::npos) { |
|
|
|
|
|
|
|
pos1+=2; |
|
|
|
|
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if(pos1!=std::string::npos) { |
|
|
|
else |
|
|
|
found_type_or_function=true; |
|
|
|
break; |
|
|
|
if(pos2!=std::string::npos) |
|
|
|
} |
|
|
|
data.emplace_back(usr.substr(pos1, pos2-pos1)); |
|
|
|
if(data.size()==1) |
|
|
|
else |
|
|
|
data.emplace_back(""); |
|
|
|
data.emplace_back(usr.substr(pos1)); |
|
|
|
|
|
|
|
} |
|
|
|
//template arguments
|
|
|
|
|
|
|
|
size_t template_pos=usr.find('$'); |
|
|
|
//Sometimes a method is at end without a identifier it seems:
|
|
|
|
|
|
|
|
if(!found_type_or_function && (pos1=usr.rfind('@'))!=std::string::npos) { |
|
|
|
bool found_type_or_function=false; |
|
|
|
pos1++; |
|
|
|
//type
|
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
pos2=0; |
|
|
|
if(pos2!=std::string::npos) |
|
|
|
while(((pos1=usr.find("T@", pos2))!=std::string::npos || (pos1=usr.find("S@", pos2))!=std::string::npos) && pos1<template_pos) { |
|
|
|
data.emplace_back(usr.substr(pos1, pos2-pos1)); |
|
|
|
found_type_or_function=true; |
|
|
|
else |
|
|
|
pos1+=2; |
|
|
|
data.emplace_back(usr.substr(pos1)); |
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
|
|
|
|
if(pos2!=std::string::npos) |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1, pos2-pos1)); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1)); |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//function/constant//variable
|
|
|
|
|
|
|
|
pos1=usr.find("F@"); |
|
|
|
|
|
|
|
if(pos1==std::string::npos) |
|
|
|
|
|
|
|
pos1=usr.find("C@"); |
|
|
|
|
|
|
|
if(pos1==std::string::npos) |
|
|
|
|
|
|
|
pos1=usr.find("I@"); |
|
|
|
|
|
|
|
if(pos1!=std::string::npos) { |
|
|
|
|
|
|
|
pos1+=2; |
|
|
|
|
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(pos1!=std::string::npos) { |
|
|
|
|
|
|
|
found_type_or_function=true; |
|
|
|
|
|
|
|
if(pos2!=std::string::npos) |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1, pos2-pos1)); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Sometimes a method is at end without a identifier it seems:
|
|
|
|
|
|
|
|
if(!found_type_or_function && (pos1=usr.rfind('@'))!=std::string::npos) { |
|
|
|
|
|
|
|
pos1++; |
|
|
|
|
|
|
|
pos2=find_non_word_char(usr, pos1); |
|
|
|
|
|
|
|
if(pos2!=std::string::npos) |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1, pos2-pos1)); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
data.emplace_back(usr.substr(pos1)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1157,52 +1167,56 @@ Source::ClangViewAutocomplete(file_path, language) { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
goto_next_diagnostic=[this]() { |
|
|
|
goto_next_diagnostic=[this]() { |
|
|
|
if(parsed) { |
|
|
|
if(!parsed) { |
|
|
|
auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset(); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
for(auto offset: diagnostic_offsets) { |
|
|
|
return; |
|
|
|
if(offset>insert_offset) { |
|
|
|
} |
|
|
|
get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset)); |
|
|
|
auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset(); |
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
for(auto offset: diagnostic_offsets) { |
|
|
|
return; |
|
|
|
if(offset>insert_offset) { |
|
|
|
} |
|
|
|
get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset)); |
|
|
|
} |
|
|
|
|
|
|
|
if(diagnostic_offsets.size()>0) { |
|
|
|
|
|
|
|
auto iter=get_buffer()->get_iter_at_offset(*diagnostic_offsets.begin()); |
|
|
|
|
|
|
|
get_buffer()->place_cursor(iter); |
|
|
|
|
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(diagnostic_offsets.size()>0) { |
|
|
|
|
|
|
|
auto iter=get_buffer()->get_iter_at_offset(*diagnostic_offsets.begin()); |
|
|
|
|
|
|
|
get_buffer()->place_cursor(iter); |
|
|
|
|
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
apply_fix_its=[this]() { |
|
|
|
apply_fix_its=[this]() { |
|
|
|
|
|
|
|
if(!parsed) { |
|
|
|
|
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks; |
|
|
|
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks; |
|
|
|
if(parsed) { |
|
|
|
for(auto &fix_it: fix_its) { |
|
|
|
for(auto &fix_it: fix_its) { |
|
|
|
auto start_iter=get_buffer()->get_iter_at_line_index(fix_it.offsets.first.line-1, fix_it.offsets.first.index-1); |
|
|
|
auto start_iter=get_buffer()->get_iter_at_line_index(fix_it.offsets.first.line-1, fix_it.offsets.first.index-1); |
|
|
|
auto end_iter=get_buffer()->get_iter_at_line_index(fix_it.offsets.second.line-1, fix_it.offsets.second.index-1); |
|
|
|
auto end_iter=get_buffer()->get_iter_at_line_index(fix_it.offsets.second.line-1, fix_it.offsets.second.index-1); |
|
|
|
fix_it_marks.emplace_back(get_buffer()->create_mark(start_iter), get_buffer()->create_mark(end_iter)); |
|
|
|
fix_it_marks.emplace_back(get_buffer()->create_mark(start_iter), get_buffer()->create_mark(end_iter)); |
|
|
|
} |
|
|
|
|
|
|
|
size_t c=0; |
|
|
|
|
|
|
|
get_source_buffer()->begin_user_action(); |
|
|
|
|
|
|
|
for(auto &fix_it: fix_its) { |
|
|
|
|
|
|
|
if(fix_it.type==FixIt::Type::INSERT) { |
|
|
|
|
|
|
|
get_buffer()->insert(fix_it_marks[c].first->get_iter(), fix_it.source); |
|
|
|
} |
|
|
|
} |
|
|
|
size_t c=0; |
|
|
|
if(fix_it.type==FixIt::Type::REPLACE) { |
|
|
|
get_source_buffer()->begin_user_action(); |
|
|
|
get_buffer()->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter()); |
|
|
|
for(auto &fix_it: fix_its) { |
|
|
|
get_buffer()->insert(fix_it_marks[c].first->get_iter(), fix_it.source); |
|
|
|
if(fix_it.type==FixIt::Type::INSERT) { |
|
|
|
|
|
|
|
get_buffer()->insert(fix_it_marks[c].first->get_iter(), fix_it.source); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(fix_it.type==FixIt::Type::REPLACE) { |
|
|
|
|
|
|
|
get_buffer()->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter()); |
|
|
|
|
|
|
|
get_buffer()->insert(fix_it_marks[c].first->get_iter(), fix_it.source); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(fix_it.type==FixIt::Type::ERASE) { |
|
|
|
|
|
|
|
get_buffer()->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
c++; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
for(auto &mark_pair: fix_it_marks) { |
|
|
|
if(fix_it.type==FixIt::Type::ERASE) { |
|
|
|
get_buffer()->delete_mark(mark_pair.first); |
|
|
|
get_buffer()->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter()); |
|
|
|
get_buffer()->delete_mark(mark_pair.second); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
c++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for(auto &mark_pair: fix_it_marks) { |
|
|
|
|
|
|
|
get_buffer()->delete_mark(mark_pair.first); |
|
|
|
|
|
|
|
get_buffer()->delete_mark(mark_pair.second); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|