Browse Source

Merge branch 'master' of https://github.com/eidheim/jucipp

merge-requests/365/head
Jørgen Lien Sellæg 11 years ago
parent
commit
2cce109f59
  1. 2
      juci/selectiondialog.cc
  2. 1
      juci/selectiondialog.h
  3. 124
      juci/source.cc
  4. 9
      juci/source.h

2
juci/selectiondialog.cc

@ -65,6 +65,8 @@ void SelectionDialog::hide() {
window->hide(); window->hide();
if(tooltips) if(tooltips)
tooltips->hide(); tooltips->hide();
if(on_hide)
on_hide();
} }
void SelectionDialog::select(bool hide_window) { void SelectionDialog::select(bool hide_window) {

1
juci/selectiondialog.h

@ -14,6 +14,7 @@ public:
void move(); void move();
bool on_key_release(GdkEventKey* key); bool on_key_release(GdkEventKey* key);
bool on_key_press(GdkEventKey* key); bool on_key_press(GdkEventKey* key);
std::function<void()> on_hide;
std::map<std::string, std::pair<std::string, std::string> > rows; std::map<std::string, std::pair<std::string, std::string> > rows;
bool shown=false; bool shown=false;

124
juci/source.cc

@ -150,8 +150,8 @@ 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::ClangView::ClangView(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal):
Source::View(file_path, project_path), terminal(terminal), Source::View(file_path, project_path), terminal(terminal),
parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
similar_token_tag=get_buffer()->create_tag(); similar_tokens_tag=get_buffer()->create_tag();
similar_token_tag->property_weight()=Pango::WEIGHT_BOLD; similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD;
int start_offset = get_source_buffer()->begin().get_offset(); int start_offset = get_source_buffer()->begin().get_offset();
int end_offset = get_source_buffer()->end().get_offset(); int end_offset = get_source_buffer()->end().get_offset();
@ -225,15 +225,13 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
}); });
get_buffer()->signal_changed().connect([this]() { get_buffer()->signal_changed().connect([this]() {
parse_thread_mapped=false; start_reparse();
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(); type_tooltips.hide();
diagnostic_tooltips.hide(); diagnostic_tooltips.hide();
if(last_similar_tokens_tagged!="") {
get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end());
last_similar_tokens_tagged="";
}
}); });
get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangView::on_mark_set), false); get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangView::on_mark_set), false);
@ -262,15 +260,23 @@ init_syntax_highlighting(const std::map<std::string, std::string>
clang_tokens=clang_tu->get_tokens(0, buffers.find(file_path)->second.size()-1); clang_tokens=clang_tu->get_tokens(0, buffers.find(file_path)->second.size()-1);
} }
std::map<std::string, std::string> Source::ClangView:: std::map<std::string, std::string> Source::ClangView::get_buffer_map() const {
get_buffer_map() const {
std::map<std::string, std::string> buffer_map; std::map<std::string, std::string> buffer_map;
buffer_map[file_path]=get_source_buffer()->get_text().raw(); buffer_map[file_path]=get_source_buffer()->get_text().raw();
return buffer_map; return buffer_map;
} }
int Source::ClangView:: void Source::ClangView::start_reparse() {
reparse(const std::map<std::string, std::string> &buffer) { parse_thread_mapped=false;
clang_readable=false;
delayed_reparse_connection.disconnect();
delayed_reparse_connection=Glib::signal_timeout().connect([this]() {
parse_thread_go=true;
return false;
}, 1000);
}
int Source::ClangView::reparse(const std::map<std::string, std::string> &buffer) {
int status = clang_tu->ReparseTranslationUnit(buffer); int status = clang_tu->ReparseTranslationUnit(buffer);
clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path)->second.size()-1); clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path)->second.size()-1);
return status; return status;
@ -429,20 +435,31 @@ void Source::ClangView::on_mark_set(const Gtk::TextBuffer::iterator& iterator, c
type_tooltips.hide(); type_tooltips.hide();
diagnostic_tooltips.hide(); diagnostic_tooltips.hide();
get_buffer()->remove_tag(similar_token_tag, get_buffer()->begin(), get_buffer()->end()); bool found=false;
if(clang_readable) { if(clang_readable) {
for(auto &token: *clang_tokens) { for(auto &token: *clang_tokens) {
if(token.has_type()) { if(token.has_type()) {
auto range_data=token.source_range.get_range_data(); auto range_data=token.source_range.get_range_data();
auto insert_offset=(unsigned)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) { if(range_data.path==file_path && insert_offset>=range_data.start_offset && insert_offset<=range_data.end_offset) {
found=true;
auto referenced_usr_and_token_spelling=token.get_cursor().get_referenced_usr()+token.get_token_spelling();
if(last_similar_tokens_tagged!=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); auto offsets=clang_tokens->get_similar_token_offsets(token);
for(auto &offset: offsets) { for(auto &offset: offsets) {
get_buffer()->apply_tag(similar_token_tag, get_buffer()->get_iter_at_offset(offset.first), get_buffer()->get_iter_at_offset(offset.second)); 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_tokens_tagged=referenced_usr_and_token_spelling;
break;
}
} }
} }
} }
} }
if(!found && last_similar_tokens_tagged!="") {
get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end());
last_similar_tokens_tagged="";
} }
} }
} }
@ -553,37 +570,14 @@ 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::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) { Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), autocomplete_cancel_starting(false) {
selection_dialog.on_hide=[this](){
start_reparse();
};
get_buffer()->signal_changed().connect([this](){ get_buffer()->signal_changed().connect([this](){
if(last_keyval==GDK_KEY_BackSpace) if(selection_dialog.shown)
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();
prefix_mutex.unlock();
if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !selection_dialog.shown) {
autocomplete();
}
else if(last_keyval=='.' && autocomplete_starting)
autocomplete_cancel_starting=true;
}
else if(std::regex_match(line, sm, within_namespace)) {
prefix_mutex.lock();
prefix=sm[3].str();
prefix_mutex.unlock();
if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !selection_dialog.shown) {
autocomplete();
}
}
else
autocomplete_cancel_starting=true;
if(autocomplete_starting || selection_dialog.shown)
delayed_reparse_connection.disconnect(); delayed_reparse_connection.disconnect();
} start_autocomplete();
}); });
get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark){ get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark){
if(mark->get_name()=="insert") { if(mark->get_name()=="insert") {
@ -600,7 +594,6 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), a
}, false); }, false);
signal_key_release_event().connect([this](GdkEventKey* key){ signal_key_release_event().connect([this](GdkEventKey* key){
if(selection_dialog.shown) { if(selection_dialog.shown) {
delayed_reparse_connection.disconnect(); //TODO: place this somewhere better (buffer_changed maybe)
if(selection_dialog.on_key_release(key)) if(selection_dialog.on_key_release(key))
return true; return true;
} }
@ -612,7 +605,6 @@ Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), a
bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) {
last_keyval=key->keyval; last_keyval=key->keyval;
if(selection_dialog.shown) { if(selection_dialog.shown) {
delayed_reparse_connection.disconnect(); //TODO: place this somewhere better (buffer_changed maybe)
if(selection_dialog.on_key_press(key)) if(selection_dialog.on_key_press(key))
return true; return true;
} }
@ -627,6 +619,42 @@ bool Source::ClangViewAutocomplete::on_focus_out_event(GdkEventFocus* event) {
return Source::ClangView::on_focus_out_event(event); return Source::ClangView::on_focus_out_event(event);
} }
void Source::ClangViewAutocomplete::start_autocomplete() {
const std::regex autocomplete_keys("[a-zA-Z0-9_>\\.:]");
std::smatch sm;
if(!std::regex_match(std::string()+(char)last_keyval, sm, autocomplete_keys)) {
autocomplete_cancel_starting=true;
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,})$");
if(std::regex_match(line, sm, in_specified_namespace)) {
prefix_mutex.lock();
prefix=sm[3].str();
prefix_mutex.unlock();
if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !selection_dialog.shown) {
autocomplete();
}
else if(last_keyval=='.' && autocomplete_starting)
autocomplete_cancel_starting=true;
}
else if(std::regex_match(line, sm, within_namespace)) {
prefix_mutex.lock();
prefix=sm[3].str();
prefix_mutex.unlock();
if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !selection_dialog.shown) {
autocomplete();
}
}
else
autocomplete_cancel_starting=true;
if(autocomplete_starting || selection_dialog.shown)
delayed_reparse_connection.disconnect();
}
}
void Source::ClangViewAutocomplete::autocomplete() { void Source::ClangViewAutocomplete::autocomplete() {
if(!autocomplete_starting) { if(!autocomplete_starting) {
autocomplete_starting=true; autocomplete_starting=true;
@ -635,6 +663,7 @@ void Source::ClangViewAutocomplete::autocomplete() {
std::shared_ptr<std::vector<Source::AutoCompleteData> > ac_data=std::make_shared<std::vector<Source::AutoCompleteData> >(); std::shared_ptr<std::vector<Source::AutoCompleteData> > ac_data=std::make_shared<std::vector<Source::AutoCompleteData> >();
autocomplete_done_connection.disconnect(); autocomplete_done_connection.disconnect();
autocomplete_done_connection=autocomplete_done.connect([this, ac_data](){ autocomplete_done_connection=autocomplete_done.connect([this, ac_data](){
autocomplete_starting=false;
if(!autocomplete_cancel_starting) { if(!autocomplete_cancel_starting) {
if(selection_dialog.start_mark) if(selection_dialog.start_mark)
get_buffer()->delete_mark(selection_dialog.start_mark); get_buffer()->delete_mark(selection_dialog.start_mark);
@ -668,7 +697,8 @@ void Source::ClangViewAutocomplete::autocomplete() {
selection_dialog.rows=std::move(rows); selection_dialog.rows=std::move(rows);
selection_dialog.show(); selection_dialog.show();
} }
autocomplete_starting=false; else
start_autocomplete();
}); });
std::shared_ptr<std::map<std::string, std::string> > buffer_map=std::make_shared<std::map<std::string, std::string> >(); std::shared_ptr<std::map<std::string, std::string> > buffer_map=std::make_shared<std::map<std::string, std::string> >();

9
juci/source.h

@ -70,12 +70,13 @@ namespace Source {
ClangView(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal); ClangView(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal);
~ClangView(); ~ClangView();
protected: protected:
void start_reparse();
bool on_key_press_event(GdkEventKey* key);
bool on_focus_out_event(GdkEventFocus* event);
std::unique_ptr<clang::TranslationUnit> clang_tu; std::unique_ptr<clang::TranslationUnit> clang_tu;
std::map<std::string, std::string> get_buffer_map() const; std::map<std::string, std::string> get_buffer_map() const;
std::mutex parsing_mutex; std::mutex parsing_mutex;
sigc::connection delayed_reparse_connection; sigc::connection delayed_reparse_connection;
bool on_key_press_event(GdkEventKey* key);
bool on_focus_out_event(GdkEventFocus* event);
private: private:
// inits the syntax highligthing on file open // inits the syntax highligthing on file open
void init_syntax_highlighting(const std::map<std::string, std::string> void init_syntax_highlighting(const std::map<std::string, std::string>
@ -91,7 +92,8 @@ namespace Source {
bool on_motion_notify_event(GdkEventMotion* event); bool on_motion_notify_event(GdkEventMotion* event);
void on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark); void on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark);
sigc::connection delayed_tooltips_connection; sigc::connection delayed_tooltips_connection;
Glib::RefPtr<Gtk::TextTag> similar_token_tag; Glib::RefPtr<Gtk::TextTag> similar_tokens_tag;
std::string last_similar_tokens_tagged;
bool on_scroll_event(GdkEventScroll* event); bool on_scroll_event(GdkEventScroll* event);
static clang::Index clang_index; static clang::Index clang_index;
@ -118,6 +120,7 @@ namespace Source {
bool on_key_press_event(GdkEventKey* key); bool on_key_press_event(GdkEventKey* key);
bool on_focus_out_event(GdkEventFocus* event); bool on_focus_out_event(GdkEventFocus* event);
private: private:
void start_autocomplete();
void autocomplete(); void autocomplete();
SelectionDialog selection_dialog; SelectionDialog selection_dialog;
std::vector<Source::AutoCompleteData> get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map); std::vector<Source::AutoCompleteData> get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map);

Loading…
Cancel
Save