|
|
|
@ -70,10 +70,6 @@ void Source::ClangViewParse::configure() { |
|
|
|
JINFO("Style " + item.second + " not found in " + scheme->get_name()); |
|
|
|
JINFO("Style " + item.second + " not found in " + scheme->get_name()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bracket_regex=boost::regex("^([ \\t]*).*\\{ *$"); |
|
|
|
|
|
|
|
no_bracket_statement_regex=boost::regex("^([ \\t]*)(if|for|else if|while) *\\(.*[^;}] *$"); |
|
|
|
|
|
|
|
no_bracket_no_para_statement_regex=boost::regex("^([ \\t]*)(else) *$"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Source::ClangViewParse::parse_initialize() { |
|
|
|
void Source::ClangViewParse::parse_initialize() { |
|
|
|
@ -111,7 +107,7 @@ void Source::ClangViewParse::parse_initialize() { |
|
|
|
break; |
|
|
|
break; |
|
|
|
auto expected=ParseProcessState::STARTING; |
|
|
|
auto expected=ParseProcessState::STARTING; |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { |
|
|
|
dispatcher.push([this] { |
|
|
|
dispatcher.post([this] { |
|
|
|
auto expected=ParseProcessState::PREPROCESSING; |
|
|
|
auto expected=ParseProcessState::PREPROCESSING; |
|
|
|
if(parse_mutex.try_lock()) { |
|
|
|
if(parse_mutex.try_lock()) { |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) |
|
|
|
@ -130,7 +126,7 @@ void Source::ClangViewParse::parse_initialize() { |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { |
|
|
|
clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); |
|
|
|
clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); |
|
|
|
parse_mutex.unlock(); |
|
|
|
parse_mutex.unlock(); |
|
|
|
dispatcher.push([this] { |
|
|
|
dispatcher.post([this] { |
|
|
|
if(parse_mutex.try_lock()) { |
|
|
|
if(parse_mutex.try_lock()) { |
|
|
|
auto expected=ParseProcessState::POSTPROCESSING; |
|
|
|
auto expected=ParseProcessState::POSTPROCESSING; |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { |
|
|
|
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { |
|
|
|
@ -149,7 +145,7 @@ void Source::ClangViewParse::parse_initialize() { |
|
|
|
else { |
|
|
|
else { |
|
|
|
parse_state=ParseState::STOP; |
|
|
|
parse_state=ParseState::STOP; |
|
|
|
parse_mutex.unlock(); |
|
|
|
parse_mutex.unlock(); |
|
|
|
dispatcher.push([this] { |
|
|
|
dispatcher.post([this] { |
|
|
|
Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); |
|
|
|
Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); |
|
|
|
set_status(""); |
|
|
|
set_status(""); |
|
|
|
set_info(""); |
|
|
|
set_info(""); |
|
|
|
@ -451,215 +447,6 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) |
|
|
|
//type_tooltips.show(rectangle);
|
|
|
|
//type_tooltips.show(rectangle);
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Clang indentation.
|
|
|
|
|
|
|
|
bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { |
|
|
|
|
|
|
|
if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->shown) { |
|
|
|
|
|
|
|
if(spellcheck_suggestions_dialog->on_key_press(key)) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
if(iter.backward_char() && (get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) |
|
|
|
|
|
|
|
return Source::View::on_key_press_event(key); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(get_buffer()->get_has_selection()) { |
|
|
|
|
|
|
|
return Source::View::on_key_press_event(key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->begin_user_action(); |
|
|
|
|
|
|
|
iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
//Indent depending on if/else/etc and brackets
|
|
|
|
|
|
|
|
if(key->keyval==GDK_KEY_Return && !iter.starts_line()) { |
|
|
|
|
|
|
|
//First remove spaces or tabs around cursor
|
|
|
|
|
|
|
|
auto start_blank_iter=iter; |
|
|
|
|
|
|
|
auto end_blank_iter=iter; |
|
|
|
|
|
|
|
while((*end_blank_iter==' ' || *end_blank_iter=='\t') && |
|
|
|
|
|
|
|
!end_blank_iter.ends_line() && end_blank_iter.forward_char()) {} |
|
|
|
|
|
|
|
start_blank_iter.backward_char(); |
|
|
|
|
|
|
|
while((*start_blank_iter==' ' || *start_blank_iter=='\t' || start_blank_iter.ends_line()) && |
|
|
|
|
|
|
|
!start_blank_iter.starts_line() && start_blank_iter.backward_char()) {} |
|
|
|
|
|
|
|
if(!start_blank_iter.starts_line()) { |
|
|
|
|
|
|
|
start_blank_iter.forward_char(); |
|
|
|
|
|
|
|
get_buffer()->erase(start_blank_iter, end_blank_iter); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
get_buffer()->erase(iter, end_blank_iter); |
|
|
|
|
|
|
|
iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Gtk::TextIter start_of_sentence_iter; |
|
|
|
|
|
|
|
if(find_start_of_closed_expression(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); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boost::smatch sm; |
|
|
|
|
|
|
|
if(iter.backward_char() && *iter=='{') { |
|
|
|
|
|
|
|
auto found_iter=iter; |
|
|
|
|
|
|
|
bool found_right_bracket=find_right_bracket_forward(iter, found_iter); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool has_bracket=false; |
|
|
|
|
|
|
|
if(found_right_bracket) { |
|
|
|
|
|
|
|
auto tabs_end_iter=get_tabs_end_iter(found_iter); |
|
|
|
|
|
|
|
auto line_tabs=get_line_before(tabs_end_iter); |
|
|
|
|
|
|
|
if(tabs.size()==line_tabs.size()) |
|
|
|
|
|
|
|
has_bracket=true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(*get_buffer()->get_insert()->get_iter()=='}') { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs); |
|
|
|
|
|
|
|
auto insert_it = get_source_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
if(insert_it.backward_chars(tabs.size()+1)) { |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->place_cursor(insert_it); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(!has_bracket) { |
|
|
|
|
|
|
|
//Insert new lines with bracket end
|
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab+"\n"+tabs+"}"); |
|
|
|
|
|
|
|
auto insert_it = get_source_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
if(insert_it.backward_chars(tabs.size()+2)) { |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->place_cursor(insert_it); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
|
|
|
|
scroll_to(get_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
auto line=get_line_before(); |
|
|
|
|
|
|
|
iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
auto found_iter=iter; |
|
|
|
|
|
|
|
if(find_open_expression_symbol(iter, start_of_sentence_iter, found_iter)) { |
|
|
|
|
|
|
|
auto tabs_end_iter=get_tabs_end_iter(found_iter); |
|
|
|
|
|
|
|
tabs=get_line_before(tabs_end_iter); |
|
|
|
|
|
|
|
auto iter=tabs_end_iter; |
|
|
|
|
|
|
|
while(iter<=found_iter) { |
|
|
|
|
|
|
|
tabs+=' '; |
|
|
|
|
|
|
|
iter.forward_char(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(boost::regex_match(line, sm, no_bracket_statement_regex)) { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(boost::regex_match(line, sm, no_bracket_no_para_statement_regex)) { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//Indenting after for instance if(...)\n...;\n
|
|
|
|
|
|
|
|
else if(iter.backward_char() && *iter==';') { |
|
|
|
|
|
|
|
boost::smatch sm2; |
|
|
|
|
|
|
|
size_t line_nr=get_source_buffer()->get_insert()->get_iter().get_line(); |
|
|
|
|
|
|
|
if(line_nr>0 && tabs.size()>=tab_size) { |
|
|
|
|
|
|
|
std::string previous_line=get_line(line_nr-1); |
|
|
|
|
|
|
|
if(!boost::regex_match(previous_line, sm2, bracket_regex)) { |
|
|
|
|
|
|
|
if(boost::regex_match(previous_line, sm2, no_bracket_statement_regex)) { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(boost::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str()); |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//Indenting after ':'
|
|
|
|
|
|
|
|
else if(*iter==':') { |
|
|
|
|
|
|
|
Gtk::TextIter left_bracket_iter; |
|
|
|
|
|
|
|
if(find_left_bracket_backward(iter, left_bracket_iter)) { |
|
|
|
|
|
|
|
if(!left_bracket_iter.ends_line()) |
|
|
|
|
|
|
|
left_bracket_iter.forward_char(); |
|
|
|
|
|
|
|
Gtk::TextIter start_of_left_bracket_sentence_iter; |
|
|
|
|
|
|
|
if(find_start_of_closed_expression(left_bracket_iter, start_of_left_bracket_sentence_iter)) { |
|
|
|
|
|
|
|
boost::smatch sm; |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
if(tabs.size()==(tabs_start_of_sentence.size()+tab_size)) { |
|
|
|
|
|
|
|
auto start_line_iter=get_buffer()->get_iter_at_line(iter.get_line()); |
|
|
|
|
|
|
|
auto start_line_plus_tab_size=start_line_iter; |
|
|
|
|
|
|
|
for(size_t c=0;c<tab_size;c++) |
|
|
|
|
|
|
|
start_line_plus_tab_size.forward_char(); |
|
|
|
|
|
|
|
get_buffer()->erase(start_line_iter, start_line_plus_tab_size); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs+tab); |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("\n"+tabs); |
|
|
|
|
|
|
|
scroll_to(get_source_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//Indent left when writing } on a new line
|
|
|
|
|
|
|
|
else if(key->keyval==GDK_KEY_braceright) { |
|
|
|
|
|
|
|
std::string line=get_line_before(); |
|
|
|
|
|
|
|
if(line.size()>=tab_size) { |
|
|
|
|
|
|
|
for(auto c: line) { |
|
|
|
|
|
|
|
if(c!=tab_char) { |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("}"); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Gtk::TextIter insert_it = get_source_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(insert_it.get_line()); |
|
|
|
|
|
|
|
Gtk::TextIter line_plus_it=line_it; |
|
|
|
|
|
|
|
line_plus_it.forward_chars(tab_size); |
|
|
|
|
|
|
|
get_source_buffer()->erase(line_it, line_plus_it); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->insert_at_cursor("}"); |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//Indent left when writing { on a new line after for instance if(...)\n...
|
|
|
|
|
|
|
|
else if(key->keyval==GDK_KEY_braceleft) { |
|
|
|
|
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
auto tabs_end_iter=get_tabs_end_iter(); |
|
|
|
|
|
|
|
auto tabs=get_line_before(tabs_end_iter); |
|
|
|
|
|
|
|
size_t line_nr=iter.get_line(); |
|
|
|
|
|
|
|
if(line_nr>0 && tabs.size()>=tab_size && iter==tabs_end_iter) { |
|
|
|
|
|
|
|
std::string previous_line=get_line(line_nr-1); |
|
|
|
|
|
|
|
boost::smatch sm; |
|
|
|
|
|
|
|
if(!boost::regex_match(previous_line, sm, bracket_regex)) { |
|
|
|
|
|
|
|
auto start_iter=iter; |
|
|
|
|
|
|
|
start_iter.backward_chars(tab_size); |
|
|
|
|
|
|
|
if(boost::regex_match(previous_line, sm, no_bracket_statement_regex) || |
|
|
|
|
|
|
|
boost::regex_match(previous_line, sm, no_bracket_no_para_statement_regex)) { |
|
|
|
|
|
|
|
if((tabs.size()-tab_size)==sm[1].str().size()) { |
|
|
|
|
|
|
|
get_buffer()->erase(start_iter, iter); |
|
|
|
|
|
|
|
get_buffer()->insert_at_cursor("{"); |
|
|
|
|
|
|
|
scroll_to(get_buffer()->get_insert()); |
|
|
|
|
|
|
|
get_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
return Source::View::on_key_press_event(key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////
|
|
|
|
//////////////////////////////
|
|
|
|
//// ClangViewAutocomplete ///
|
|
|
|
//// ClangViewAutocomplete ///
|
|
|
|
//////////////////////////////
|
|
|
|
//////////////////////////////
|
|
|
|
@ -714,15 +501,6 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_state(Au |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { |
|
|
|
|
|
|
|
last_keyval=key->keyval; |
|
|
|
|
|
|
|
if(autocomplete_dialog && autocomplete_dialog->shown) { |
|
|
|
|
|
|
|
if(autocomplete_dialog->on_key_press(key)) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return ClangViewParse::on_key_press_event(key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { |
|
|
|
void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { |
|
|
|
auto start_iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto start_iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
if(prefix.size()>0 && !start_iter.backward_chars(prefix.size())) |
|
|
|
if(prefix.size()>0 && !start_iter.backward_chars(prefix.size())) |
|
|
|
@ -874,7 +652,7 @@ void Source::ClangViewAutocomplete::autocomplete() { |
|
|
|
auto autocomplete_data=std::make_shared<std::vector<AutoCompleteData> >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); |
|
|
|
auto autocomplete_data=std::make_shared<std::vector<AutoCompleteData> >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); |
|
|
|
|
|
|
|
|
|
|
|
if(parse_state==ParseState::PROCESSING) { |
|
|
|
if(parse_state==ParseState::PROCESSING) { |
|
|
|
dispatcher.push([this, autocomplete_data] { |
|
|
|
dispatcher.post([this, autocomplete_data] { |
|
|
|
if(autocomplete_state==AutocompleteState::CANCELED) { |
|
|
|
if(autocomplete_state==AutocompleteState::CANCELED) { |
|
|
|
set_status(""); |
|
|
|
set_status(""); |
|
|
|
soft_reparse(); |
|
|
|
soft_reparse(); |
|
|
|
@ -920,7 +698,7 @@ void Source::ClangViewAutocomplete::autocomplete() { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
dispatcher.push([this] { |
|
|
|
dispatcher.post([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); |
|
|
|
autocomplete_state=AutocompleteState::CANCELED; |
|
|
|
autocomplete_state=AutocompleteState::CANCELED; |
|
|
|
full_reparse(); |
|
|
|
full_reparse(); |
|
|
|
@ -1000,7 +778,7 @@ bool Source::ClangViewAutocomplete::full_reparse() { |
|
|
|
parse_thread.join(); |
|
|
|
parse_thread.join(); |
|
|
|
if(autocomplete_thread.joinable()) |
|
|
|
if(autocomplete_thread.joinable()) |
|
|
|
autocomplete_thread.join(); |
|
|
|
autocomplete_thread.join(); |
|
|
|
dispatcher.push([this] { |
|
|
|
dispatcher.post([this] { |
|
|
|
parse_initialize(); |
|
|
|
parse_initialize(); |
|
|
|
full_reparse_running=false; |
|
|
|
full_reparse_running=false; |
|
|
|
}); |
|
|
|
}); |
|
|
|
@ -1030,72 +808,6 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
auto_indent=[this]() { |
|
|
|
|
|
|
|
auto command=Config::get().terminal.clang_format_command; |
|
|
|
|
|
|
|
bool use_style_file=false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto style_file_search_path=this->file_path.parent_path(); |
|
|
|
|
|
|
|
while(true) { |
|
|
|
|
|
|
|
auto style_file=style_file_search_path/"CMakeLists.txt"; |
|
|
|
|
|
|
|
if(boost::filesystem::exists(style_file_search_path/".clang-format") || boost::filesystem::exists(style_file_search_path/"_clang-format")) { |
|
|
|
|
|
|
|
use_style_file=true; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(style_file_search_path==style_file_search_path.root_directory()) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
style_file_search_path=style_file_search_path.parent_path(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(use_style_file) |
|
|
|
|
|
|
|
command+=" -style=file"; |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
unsigned indent_width; |
|
|
|
|
|
|
|
std::string tab_style; |
|
|
|
|
|
|
|
if(tab_char=='\t') { |
|
|
|
|
|
|
|
indent_width=tab_size*8; |
|
|
|
|
|
|
|
tab_style="UseTab: Always"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
indent_width=tab_size; |
|
|
|
|
|
|
|
tab_style="UseTab: Never"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
command+=" -style=\"{IndentWidth: "+std::to_string(indent_width); |
|
|
|
|
|
|
|
command+=", "+tab_style; |
|
|
|
|
|
|
|
command+=", "+std::string("AccessModifierOffset: -")+std::to_string(indent_width); |
|
|
|
|
|
|
|
if(Config::get().source.clang_format_style!="") |
|
|
|
|
|
|
|
command+=", "+Config::get().source.clang_format_style; |
|
|
|
|
|
|
|
command+="}\""; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path()); |
|
|
|
|
|
|
|
if(exit_status==0) { |
|
|
|
|
|
|
|
get_source_buffer()->begin_user_action(); |
|
|
|
|
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|
|
|
|
auto cursor_line_nr=iter.get_line(); |
|
|
|
|
|
|
|
auto cursor_line_offset=iter.get_line_offset(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_buffer()->erase(get_buffer()->begin(), get_buffer()->end()); |
|
|
|
|
|
|
|
get_buffer()->insert(get_buffer()->begin(), stdout_stream.str()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cursor_line_nr=std::min(cursor_line_nr, get_buffer()->get_line_count()-1); |
|
|
|
|
|
|
|
if(cursor_line_nr>=0) { |
|
|
|
|
|
|
|
iter=get_buffer()->get_iter_at_line(cursor_line_nr); |
|
|
|
|
|
|
|
for(int c=0;c<cursor_line_offset;c++) { |
|
|
|
|
|
|
|
if(iter.ends_line()) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
iter.forward_char(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_buffer()->place_cursor(iter); |
|
|
|
|
|
|
|
while(g_main_context_pending(NULL)) //TODO: minor: might crash if the buffer is saved and closed really fast right after doing auto indent
|
|
|
|
|
|
|
|
g_main_context_iteration(NULL, false); |
|
|
|
|
|
|
|
scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
get_source_buffer()->end_user_action(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_token=[this]() -> Token { |
|
|
|
get_token=[this]() -> Token { |
|
|
|
if(parsed) { |
|
|
|
if(parsed) { |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
auto iter=get_buffer()->get_insert()->get_iter(); |
|
|
|
|