|
|
|
@ -447,6 +447,8 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
autocomplete.reparse=[this] { |
|
|
|
autocomplete.reparse=[this] { |
|
|
|
|
|
|
|
selected_completion_string=nullptr; |
|
|
|
|
|
|
|
code_complete_results=nullptr; |
|
|
|
soft_reparse(true); |
|
|
|
soft_reparse(true); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
@ -588,14 +590,16 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
|
|
|
|
|
|
|
|
autocomplete.on_add_rows_error=[this] { |
|
|
|
autocomplete.on_add_rows_error=[this] { |
|
|
|
Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); |
|
|
|
Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); |
|
|
|
|
|
|
|
selected_completion_string=nullptr; |
|
|
|
|
|
|
|
code_complete_results=nullptr; |
|
|
|
full_reparse(); |
|
|
|
full_reparse(); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
autocomplete.add_rows=[this](std::string &buffer, int line_number, int column) { |
|
|
|
autocomplete.add_rows=[this](std::string &buffer, int line_number, int column) { |
|
|
|
if(this->language && (this->language->get_id()=="chdr" || this->language->get_id()=="cpphdr")) |
|
|
|
if(this->language && (this->language->get_id()=="chdr" || this->language->get_id()=="cpphdr")) |
|
|
|
clangmm::remove_include_guard(buffer); |
|
|
|
clangmm::remove_include_guard(buffer); |
|
|
|
auto results=clang_tu->get_code_completions(buffer, line_number, column); |
|
|
|
code_complete_results=std::make_unique<clangmm::CodeCompleteResults>(clang_tu->get_code_completions(buffer, line_number, column)); |
|
|
|
if(results.cx_results==nullptr) { |
|
|
|
if(code_complete_results->cx_results==nullptr) { |
|
|
|
auto expected=ParseState::PROCESSING; |
|
|
|
auto expected=ParseState::PROCESSING; |
|
|
|
parse_state.compare_exchange_strong(expected, ParseState::RESTARTING); |
|
|
|
parse_state.compare_exchange_strong(expected, ParseState::RESTARTING); |
|
|
|
return; |
|
|
|
return; |
|
|
|
@ -608,8 +612,9 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
prefix_copy=autocomplete.prefix; |
|
|
|
prefix_copy=autocomplete.prefix; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < results.size(); ++i) { |
|
|
|
completion_strings.clear(); |
|
|
|
auto result=results.get(i); |
|
|
|
for (unsigned i = 0; i < code_complete_results->size(); ++i) { |
|
|
|
|
|
|
|
auto result=code_complete_results->get(i); |
|
|
|
if(result.available()) { |
|
|
|
if(result.available()) { |
|
|
|
std::string text; |
|
|
|
std::string text; |
|
|
|
if(show_arguments) { |
|
|
|
if(show_arguments) { |
|
|
|
@ -617,11 +622,11 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
public: |
|
|
|
public: |
|
|
|
static void f(const clangmm::CompletionString &completion_string, std::string &text) { |
|
|
|
static void f(const clangmm::CompletionString &completion_string, std::string &text) { |
|
|
|
for(unsigned i = 0; i < completion_string.get_num_chunks(); ++i) { |
|
|
|
for(unsigned i = 0; i < completion_string.get_num_chunks(); ++i) { |
|
|
|
auto kind=static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(completion_string.cx_completion_sting, i)); |
|
|
|
auto kind=static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(completion_string.cx_completion_string, i)); |
|
|
|
if(kind==clangmm::CompletionChunk_Optional) |
|
|
|
if(kind==clangmm::CompletionChunk_Optional) |
|
|
|
f(clangmm::CompletionString(clang_getCompletionChunkCompletionString(completion_string.cx_completion_sting, i)), text); |
|
|
|
f(clangmm::CompletionString(clang_getCompletionChunkCompletionString(completion_string.cx_completion_string, i)), text); |
|
|
|
else if(kind==clangmm::CompletionChunk_CurrentParameter) { |
|
|
|
else if(kind==clangmm::CompletionChunk_CurrentParameter) { |
|
|
|
auto chunk_cstr=clangmm::String(clang_getCompletionChunkText(completion_string.cx_completion_sting, i)); |
|
|
|
auto chunk_cstr=clangmm::String(clang_getCompletionChunkText(completion_string.cx_completion_string, i)); |
|
|
|
text+=chunk_cstr.c_str; |
|
|
|
text+=chunk_cstr.c_str; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -636,17 +641,19 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if(!already_added) |
|
|
|
if(!already_added) { |
|
|
|
autocomplete.rows.emplace_back(std::move(text), result.get_brief_comment()); |
|
|
|
autocomplete.rows.emplace_back(std::move(text), result.get_brief_comment()); |
|
|
|
|
|
|
|
completion_strings.emplace_back(result.cx_completion_string); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
std::string return_text; |
|
|
|
std::string return_text; |
|
|
|
bool match=false; |
|
|
|
bool match=false; |
|
|
|
for(unsigned i = 0; i < result.get_num_chunks(); ++i) { |
|
|
|
for(unsigned i = 0; i < result.get_num_chunks(); ++i) { |
|
|
|
auto kind=static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(result.cx_completion_sting, i)); |
|
|
|
auto kind=static_cast<clangmm::CompletionChunkKind>(clang_getCompletionChunkKind(result.cx_completion_string, i)); |
|
|
|
if(kind!=clangmm::CompletionChunk_Informative) { |
|
|
|
if(kind!=clangmm::CompletionChunk_Informative) { |
|
|
|
auto chunk_cstr=clangmm::String(clang_getCompletionChunkText(result.cx_completion_sting, i)); |
|
|
|
auto chunk_cstr=clangmm::String(clang_getCompletionChunkText(result.cx_completion_string, i)); |
|
|
|
if(kind==clangmm::CompletionChunk_TypedText) { |
|
|
|
if(kind==clangmm::CompletionChunk_TypedText) { |
|
|
|
if(strlen(chunk_cstr.c_str)>=prefix_copy.size() && prefix_copy.compare(0, prefix_copy.size(), chunk_cstr.c_str, prefix_copy.size())==0) |
|
|
|
if(strlen(chunk_cstr.c_str)>=prefix_copy.size() && prefix_copy.compare(0, prefix_copy.size(), chunk_cstr.c_str, prefix_copy.size())==0) |
|
|
|
match = true; |
|
|
|
match = true; |
|
|
|
@ -663,6 +670,7 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
if(!return_text.empty()) |
|
|
|
if(!return_text.empty()) |
|
|
|
text+=return_text; |
|
|
|
text+=return_text; |
|
|
|
autocomplete.rows.emplace_back(std::move(text), result.get_brief_comment()); |
|
|
|
autocomplete.rows.emplace_back(std::move(text), result.get_brief_comment()); |
|
|
|
|
|
|
|
completion_strings.emplace_back(result.cx_completion_string); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -670,91 +678,105 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
autocomplete.setup_dialog=[this] { |
|
|
|
autocomplete.on_show = [this] { |
|
|
|
CompletionDialog::get()->on_show=[this] { |
|
|
|
hide_tooltips(); |
|
|
|
hide_tooltips(); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
autocomplete.on_hide = [this] { |
|
|
|
CompletionDialog::get()->on_select=[this](unsigned int index, const std::string &text, bool hide_window) { |
|
|
|
selected_completion_string=nullptr; |
|
|
|
if(index>=autocomplete.rows.size()) |
|
|
|
code_complete_results=nullptr; |
|
|
|
return; |
|
|
|
}; |
|
|
|
std::string row; |
|
|
|
|
|
|
|
auto pos=text.find(" → "); |
|
|
|
autocomplete.on_changed = [this](unsigned int index, const std::string &text) { |
|
|
|
if(pos!=std::string::npos) |
|
|
|
selected_completion_string=completion_strings[index]; |
|
|
|
row=text.substr(0, pos); |
|
|
|
}; |
|
|
|
else |
|
|
|
|
|
|
|
row=text; |
|
|
|
autocomplete.on_select = [this](unsigned int index, const std::string &text, bool hide_window) { |
|
|
|
//erase existing variable or function before insert iter
|
|
|
|
std::string row; |
|
|
|
get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); |
|
|
|
auto pos=text.find(" → "); |
|
|
|
//do not insert template argument or function parameters if they already exist
|
|
|
|
if(pos!=std::string::npos) |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
row=text.substr(0, pos); |
|
|
|
if(*iter=='<' || *iter=='(') { |
|
|
|
else |
|
|
|
auto bracket_pos=row.find(*iter); |
|
|
|
row=text; |
|
|
|
if(bracket_pos!=std::string::npos) { |
|
|
|
//erase existing variable or function before insert iter
|
|
|
|
row=row.substr(0, bracket_pos); |
|
|
|
get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); |
|
|
|
|
|
|
|
//do not insert template argument or function parameters if they already exist
|
|
|
|
|
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
if(*iter=='<' || *iter=='(') { |
|
|
|
|
|
|
|
auto bracket_pos=row.find(*iter); |
|
|
|
|
|
|
|
if(bracket_pos!=std::string::npos) { |
|
|
|
|
|
|
|
row=row.substr(0, bracket_pos); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//Fixes for the most commonly used stream manipulators
|
|
|
|
|
|
|
|
auto manipulators_map=autocomplete_manipulators_map(); |
|
|
|
|
|
|
|
auto it=manipulators_map.find(row); |
|
|
|
|
|
|
|
if(it!=manipulators_map.end()) |
|
|
|
|
|
|
|
row=it->second; |
|
|
|
|
|
|
|
//Do not insert template argument, function parameters or ':' unless hide_window is true
|
|
|
|
|
|
|
|
if(!hide_window) { |
|
|
|
|
|
|
|
for(size_t c=0;c<row.size();++c) { |
|
|
|
|
|
|
|
if(row[c]=='<' || row[c]=='(' || row[c]==':') { |
|
|
|
|
|
|
|
row.erase(c); |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
//Fixes for the most commonly used stream manipulators
|
|
|
|
} |
|
|
|
auto manipulators_map=autocomplete_manipulators_map(); |
|
|
|
get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row); |
|
|
|
auto it=manipulators_map.find(row); |
|
|
|
//if selection is finalized, select text inside template arguments or function parameters
|
|
|
|
if(it!=manipulators_map.end()) |
|
|
|
if(hide_window) { |
|
|
|
row=it->second; |
|
|
|
size_t start_pos=std::string::npos; |
|
|
|
get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row); |
|
|
|
size_t end_pos=std::string::npos; |
|
|
|
//if selection is finalized, select text inside template arguments or function parameters
|
|
|
|
if(show_arguments) { |
|
|
|
if(hide_window) { |
|
|
|
start_pos=0; |
|
|
|
size_t start_pos=std::string::npos; |
|
|
|
end_pos=row.size(); |
|
|
|
size_t end_pos=std::string::npos; |
|
|
|
} |
|
|
|
if(show_arguments) { |
|
|
|
else { |
|
|
|
start_pos=0; |
|
|
|
auto para_pos=row.find('('); |
|
|
|
end_pos=row.size(); |
|
|
|
auto angle_pos=row.find('<'); |
|
|
|
|
|
|
|
if(angle_pos<para_pos) { |
|
|
|
|
|
|
|
start_pos=angle_pos+1; |
|
|
|
|
|
|
|
end_pos=row.find('>'); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else if(para_pos!=std::string::npos) { |
|
|
|
auto para_pos=row.find('('); |
|
|
|
start_pos=para_pos+1; |
|
|
|
auto angle_pos=row.find('<'); |
|
|
|
end_pos=row.size()-1; |
|
|
|
if(angle_pos<para_pos) { |
|
|
|
|
|
|
|
start_pos=angle_pos+1; |
|
|
|
|
|
|
|
end_pos=row.find('>'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(para_pos!=std::string::npos) { |
|
|
|
|
|
|
|
start_pos=para_pos+1; |
|
|
|
|
|
|
|
end_pos=row.size()-1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(start_pos==std::string::npos || end_pos==std::string::npos) { |
|
|
|
|
|
|
|
if((start_pos=row.find('\"'))!=std::string::npos) { |
|
|
|
|
|
|
|
end_pos=row.find('\"', start_pos+1); |
|
|
|
|
|
|
|
++start_pos; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if(start_pos==std::string::npos || end_pos==std::string::npos) { |
|
|
|
if(start_pos==std::string::npos || end_pos==std::string::npos) { |
|
|
|
if((start_pos=row.find(' '))!=std::string::npos) { |
|
|
|
if((start_pos=row.find('\"'))!=std::string::npos) { |
|
|
|
std::vector<std::string> parameters={"expression", "arguments", "identifier", "type name", "qualifier::name", "macro", "condition"}; |
|
|
|
end_pos=row.find('\"', start_pos+1); |
|
|
|
for(auto ¶meter: parameters) { |
|
|
|
++start_pos; |
|
|
|
if((start_pos=row.find(parameter, start_pos+1))!=std::string::npos) { |
|
|
|
|
|
|
|
end_pos=start_pos+parameter.size(); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if(start_pos!=std::string::npos && end_pos!=std::string::npos) { |
|
|
|
if(start_pos==std::string::npos || end_pos==std::string::npos) { |
|
|
|
int start_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+start_pos; |
|
|
|
if((start_pos=row.find(' '))!=std::string::npos) { |
|
|
|
int end_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+end_pos; |
|
|
|
std::vector<std::string> parameters={"expression", "arguments", "identifier", "type name", "qualifier::name", "macro", "condition"}; |
|
|
|
auto size=get_buffer()->size(); |
|
|
|
for(auto ¶meter: parameters) { |
|
|
|
if(start_offset!=end_offset && start_offset<size && end_offset<size) |
|
|
|
if((start_pos=row.find(parameter, start_pos+1))!=std::string::npos) { |
|
|
|
get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset), get_buffer()->get_iter_at_offset(end_offset)); |
|
|
|
end_pos=start_pos+parameter.size(); |
|
|
|
} |
|
|
|
break; |
|
|
|
else { |
|
|
|
} |
|
|
|
//new autocomplete after for instance when selecting "std::"
|
|
|
|
|
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
if(iter.backward_char() && *iter==':') { |
|
|
|
|
|
|
|
autocomplete.run(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if(start_pos!=std::string::npos && end_pos!=std::string::npos) { |
|
|
|
|
|
|
|
int start_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+start_pos; |
|
|
|
|
|
|
|
int end_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+end_pos; |
|
|
|
|
|
|
|
auto size=get_buffer()->size(); |
|
|
|
|
|
|
|
if(start_offset!=end_offset && start_offset<size && end_offset<size) |
|
|
|
|
|
|
|
get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset), get_buffer()->get_iter_at_offset(end_offset)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
//new autocomplete after for instance when selecting "std::"
|
|
|
|
|
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
if(iter.backward_char() && *iter==':') { |
|
|
|
|
|
|
|
autocomplete.run(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1008,6 +1030,21 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file |
|
|
|
|
|
|
|
|
|
|
|
get_declaration_location=[this, declaration_location](){ |
|
|
|
get_declaration_location=[this, declaration_location](){ |
|
|
|
if(!parsed) { |
|
|
|
if(!parsed) { |
|
|
|
|
|
|
|
if(selected_completion_string) { |
|
|
|
|
|
|
|
auto completion_cursor=clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu); |
|
|
|
|
|
|
|
if(completion_cursor) { |
|
|
|
|
|
|
|
auto source_location=completion_cursor.get_source_location(); |
|
|
|
|
|
|
|
auto offset=source_location.get_offset(); |
|
|
|
|
|
|
|
if(CompletionDialog::get()) |
|
|
|
|
|
|
|
CompletionDialog::get()->hide(); |
|
|
|
|
|
|
|
return Offset(offset.line-1, offset.index-1, source_location.get_path()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
Info::get().print("No declaration found"); |
|
|
|
|
|
|
|
return Offset(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
return Offset(); |
|
|
|
return Offset(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1025,9 +1062,8 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file |
|
|
|
return offset; |
|
|
|
return offset; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
auto implementation_locations=[this]() { |
|
|
|
auto implementation_locations=[this](const Identifier &identifier) { |
|
|
|
std::vector<Offset> offsets; |
|
|
|
std::vector<Offset> offsets; |
|
|
|
auto identifier=get_identifier(); |
|
|
|
|
|
|
|
if(identifier) { |
|
|
|
if(identifier) { |
|
|
|
wait_parsing(); |
|
|
|
wait_parsing(); |
|
|
|
|
|
|
|
|
|
|
|
@ -1113,10 +1149,28 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file |
|
|
|
|
|
|
|
|
|
|
|
get_implementation_locations=[this, implementation_locations](){ |
|
|
|
get_implementation_locations=[this, implementation_locations](){ |
|
|
|
if(!parsed) { |
|
|
|
if(!parsed) { |
|
|
|
|
|
|
|
if(selected_completion_string) { |
|
|
|
|
|
|
|
auto completion_cursor=clangmm::CompletionString(selected_completion_string).get_cursor(clang_tu->cx_tu); |
|
|
|
|
|
|
|
if(completion_cursor) { |
|
|
|
|
|
|
|
auto offsets=implementation_locations(Identifier(completion_cursor.get_token_spelling(), completion_cursor)); |
|
|
|
|
|
|
|
if(offsets.empty()) { |
|
|
|
|
|
|
|
Info::get().print("No implementation found"); |
|
|
|
|
|
|
|
return std::vector<Offset>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(CompletionDialog::get()) |
|
|
|
|
|
|
|
CompletionDialog::get()->hide(); |
|
|
|
|
|
|
|
return offsets; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
Info::get().print("No implementation found"); |
|
|
|
|
|
|
|
return std::vector<Offset>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
Info::get().print("Buffer is parsing"); |
|
|
|
return std::vector<Offset>(); |
|
|
|
return std::vector<Offset>(); |
|
|
|
} |
|
|
|
} |
|
|
|
auto offsets=implementation_locations(); |
|
|
|
auto offsets=implementation_locations(get_identifier()); |
|
|
|
if(offsets.empty()) |
|
|
|
if(offsets.empty()) |
|
|
|
Info::get().print("No implementation found"); |
|
|
|
Info::get().print("No implementation found"); |
|
|
|
|
|
|
|
|
|
|
|
@ -1162,7 +1216,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file |
|
|
|
offsets.emplace_back(offset); |
|
|
|
offsets.emplace_back(offset); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
auto implementation_offsets=implementation_locations(); |
|
|
|
auto implementation_offsets=implementation_locations(get_identifier()); |
|
|
|
if(!implementation_offsets.empty()) { |
|
|
|
if(!implementation_offsets.empty()) { |
|
|
|
offsets=std::move(implementation_offsets); |
|
|
|
offsets=std::move(implementation_offsets); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1584,7 +1638,7 @@ void Source::ClangViewRefactor::wait_parsing() { |
|
|
|
std::vector<Source::ClangView*> clang_views; |
|
|
|
std::vector<Source::ClangView*> clang_views; |
|
|
|
for(auto &view: views) { |
|
|
|
for(auto &view: views) { |
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) { |
|
|
|
if(!clang_view->parsed) { |
|
|
|
if(!clang_view->parsed && !clang_view->selected_completion_string) { |
|
|
|
clang_views.emplace_back(clang_view); |
|
|
|
clang_views.emplace_back(clang_view); |
|
|
|
if(!message) |
|
|
|
if(!message) |
|
|
|
message=std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing"); |
|
|
|
message=std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing"); |
|
|
|
|