diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fe31bd5..86bf961 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,6 +84,8 @@ set(project_files files.h filesystem.cc filesystem.h + info.h + info.cc juci.cc juci.h menu.cc diff --git a/src/info.cc b/src/info.cc new file mode 100644 index 0000000..ce5510d --- /dev/null +++ b/src/info.cc @@ -0,0 +1,29 @@ +#include "info.h" + +Info::Info() { + set_hexpand(false); + set_halign(Gtk::Align::ALIGN_END); + + auto content_area=dynamic_cast(get_content_area()); + label.set_max_width_chars(40); + label.set_line_wrap(true); + content_area->add(label); + + auto provider = Gtk::CssProvider::create(); + provider->load_from_data("* {border-radius: 5px;}"); + get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); +} + +void Info::print(const std::string &text) { + if(!enabled) + return; + + timeout_connection.disconnect(); + timeout_connection=Glib::signal_timeout().connect([this]() { + hide(); + return false; + }, 3000); + + label.set_text(text); + show(); +} diff --git a/src/info.h b/src/info.h new file mode 100644 index 0000000..c89ced1 --- /dev/null +++ b/src/info.h @@ -0,0 +1,22 @@ +#ifndef JUCI_INFO_H_ +#define JUCI_INFO_H_ + +#include + +class Info : public Gtk::InfoBar { + Info(); +public: + static Info &get() { + static Info instance; + return instance; + } + + void print(const std::string &text); + bool enabled=true; + +private: + Gtk::Label label; + sigc::connection timeout_connection; +}; + +#endif // JUCI_INFO_H_ \ No newline at end of file diff --git a/src/project_build.cc b/src/project_build.cc index 586aafd..c7fe338 100644 --- a/src/project_build.cc +++ b/src/project_build.cc @@ -1,12 +1,15 @@ #include "project_build.h" #include "config.h" +#include "info.h" std::unique_ptr Project::get_build(const boost::filesystem::path &path) { std::unique_ptr cmake(new CMake(path)); if(!cmake->project_path.empty()) return cmake; - else + else { + Info::get().print("Could not find a supported project"); return std::unique_ptr(new Project::Build()); + } } boost::filesystem::path Project::Build::get_default_build_path() { diff --git a/src/source_clang.cc b/src/source_clang.cc index fde75d7..ee1470d 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -5,6 +5,7 @@ #ifdef JUCI_ENABLE_DEBUG #include "debug_clang.h" #endif +#include "info.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -859,20 +860,22 @@ Source::ClangViewAutocomplete(file_path, language) { }); get_token=[this]() -> Token { - if(parsed) { - auto iter=get_buffer()->get_insert()->get_iter(); - auto line=(unsigned)iter.get_line(); - auto index=(unsigned)iter.get_line_index(); - for(auto &token: *clang_tokens) { - auto cursor=token.get_cursor(); - if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { - if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { - if(static_cast(token.get_cursor().get_kind())==103) //These cursors are buggy - continue; - auto referenced=cursor.get_referenced(); - if(referenced) - return Token(this->language, static_cast(referenced.get_kind()), token.get_spelling(), referenced.get_usr()); - } + if(!parsed) { + Info::get().print("Buffer is parsing"); + return Token(); + } + auto iter=get_buffer()->get_insert()->get_iter(); + auto line=(unsigned)iter.get_line(); + auto index=(unsigned)iter.get_line_index(); + for(auto &token: *clang_tokens) { + auto cursor=token.get_cursor(); + if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { + if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { + if(static_cast(token.get_cursor().get_kind())==103) //These cursors are buggy + continue; + auto referenced=cursor.get_referenced(); + if(referenced) + return Token(this->language, static_cast(referenced.get_kind()), token.get_spelling(), referenced.get_usr()); } } } @@ -907,7 +910,9 @@ Source::ClangViewAutocomplete(file_path, language) { if(mark->get_name()=="insert") { delayed_tag_similar_tokens_connection.disconnect(); delayed_tag_similar_tokens_connection=Glib::signal_timeout().connect([this]() { + Info::get().enabled=false; auto token=get_token(); + Info::get().enabled=true; tag_similar_tokens(token); return false; }, 100); @@ -916,22 +921,24 @@ Source::ClangViewAutocomplete(file_path, language) { get_declaration_location=[this](){ Offset location; - if(parsed) { - auto iter=get_buffer()->get_insert()->get_iter(); - auto line=(unsigned)iter.get_line(); - auto index=(unsigned)iter.get_line_index(); - for(auto &token: *clang_tokens) { - auto cursor=token.get_cursor(); - if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { - if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { - auto referenced=cursor.get_referenced(); - if(referenced) { - location.file_path=referenced.get_source_location().get_path(); - auto clang_offset=referenced.get_source_location().get_offset(); - location.line=clang_offset.line; - location.index=clang_offset.index; - break; - } + if(!parsed) { + Info::get().print("Buffer is parsing"); + return location; + } + auto iter=get_buffer()->get_insert()->get_iter(); + auto line=(unsigned)iter.get_line(); + auto index=(unsigned)iter.get_line_index(); + for(auto &token: *clang_tokens) { + auto cursor=token.get_cursor(); + if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { + if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { + auto referenced=cursor.get_referenced(); + if(referenced) { + location.file_path=referenced.get_source_location().get_path(); + 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) { std::vector > usages; - 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")) { auto offsets=clang_tokens->get_similar_token_offsets(static_cast(token.type), token.spelling, token.usr); @@ -1006,55 +1012,57 @@ Source::ClangViewAutocomplete(file_path, language) { return usages; }; - goto_method=[this](){ - if(parsed) { - auto iter=get_iter_for_dialog(); - selection_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); - auto methods=clang_tokens->get_cxx_methods(); - if(methods.size()==0) - return; - for(auto &method: methods) { - std::string row=std::to_string(method.second.line)+": "+Glib::Markup::escape_text(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; + goto_method=[this](){ + if(!parsed) { + Info::get().print("Buffer is parsing"); + return; + } + auto iter=get_iter_for_dialog(); + selection_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true)); + auto rows=std::make_shared >(); + auto methods=clang_tokens->get_cxx_methods(); + if(methods.size()==0) + return; + for(auto &method: methods) { + std::string row=std::to_string(method.second.line)+": "+Glib::Markup::escape_text(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 { - 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, ""); - row.insert(pos+1, ""); - (*rows)[row]=method.second; - selection_dialog->add_row(row); + 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); } - 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(); + 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, ""); + row.insert(pos+1, ""); + (*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]() { @@ -1070,85 +1078,87 @@ Source::ClangViewAutocomplete(file_path, language) { }; std::vector data; - if(parsed) { - auto iter=get_buffer()->get_insert()->get_iter(); - auto line=(unsigned)iter.get_line(); - auto index=(unsigned)iter.get_line_index(); - for(auto &token: *clang_tokens) { - auto cursor=token.get_cursor(); - if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { - if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { - auto referenced=cursor.get_referenced(); - if(referenced) { - auto usr=referenced.get_usr(); - - data.emplace_back("clang"); - - //namespace - size_t pos1, pos2=0; - while((pos1=usr.find('@', pos2))!=std::string::npos && pos1+1get_insert()->get_iter(); + auto line=(unsigned)iter.get_line(); + auto index=(unsigned)iter.get_line_index(); + for(auto &token: *clang_tokens) { + auto cursor=token.get_cursor(); + if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { + if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { + auto referenced=cursor.get_referenced(); + if(referenced) { + auto usr=referenced.get_usr(); + + data.emplace_back("clang"); + + //namespace + size_t pos1, pos2=0; + while((pos1=usr.find('@', pos2))!=std::string::npos && pos1+1get_insert()->get_iter().get_offset(); - for(auto offset: diagnostic_offsets) { - if(offset>insert_offset) { - get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset)); - 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); + if(!parsed) { + Info::get().print("Buffer is parsing"); + return; + } + auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset(); + for(auto offset: diagnostic_offsets) { + if(offset>insert_offset) { + get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset)); 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]() { + if(!parsed) { + Info::get().print("Buffer is parsing"); + return; + } std::vector, Glib::RefPtr > > fix_it_marks; - if(parsed) { - 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 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)); + 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 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)); + } + 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; - 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); - } - 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++; + 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); } - for(auto &mark_pair: fix_it_marks) { - get_buffer()->delete_mark(mark_pair.first); - get_buffer()->delete_mark(mark_pair.second); + if(fix_it.type==FixIt::Type::ERASE) { + get_buffer()->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter()); } - 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(); }; } diff --git a/src/terminal.cc b/src/terminal.cc index f043bd5..5f15c69 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -2,6 +2,7 @@ #include #include "config.h" #include "project.h" +#include "info.h" Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) { start(start_msg); @@ -138,7 +139,9 @@ void Terminal::async_process(const std::string &command, const boost::filesystem void Terminal::kill_last_async_process(bool force) { std::unique_lock lock(processes_mutex); - if(processes.size()>0) + if(processes.empty()) + Info::get().print("No running processes"); + else processes.back()->kill(force); } diff --git a/src/window.cc b/src/window.cc index 1fb249e..6fe7c20 100644 --- a/src/window.cc +++ b/src/window.cc @@ -7,6 +7,7 @@ #include "filesystem.h" #include "project.h" #include "entrybox.h" +#include "info.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -31,10 +32,6 @@ Window::Window() : notebook(Notebook::get()) { configure(); set_default_size(Config::get().window.default_size.first, Config::get().window.default_size.second); - //PluginApi(&this->notebook, &this->menu); - - add(vpaned); - directories_scrolled_window.add(Directories::get()); directory_and_notebook_panes.pack1(directories_scrolled_window, Gtk::SHRINK); notebook_vbox.pack_start(notebook); @@ -59,7 +56,16 @@ Window::Window() : notebook(Notebook::get()) { terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); vpaned.pack2(terminal_vbox, true, true); + overlay_vbox.pack_start(Info::get(), Gtk::PACK_SHRINK, 20); + overlay_hbox.pack_end(overlay_vbox, Gtk::PACK_SHRINK, 20); + + overlay.add(vpaned); + overlay.add_overlay(overlay_hbox); + overlay.set_overlay_pass_through(overlay_hbox, true); + add(overlay); + show_all_children(); + Info::get().hide(); Directories::get().on_row_activated=[this](const boost::filesystem::path &path) { notebook.open(path); @@ -481,6 +487,7 @@ void Window::set_menu_actions() { } } } + Info::get().print("Could not find implementation"); } } } diff --git a/src/window.h b/src/window.h index 34e1a2d..12c8d8b 100644 --- a/src/window.h +++ b/src/window.h @@ -27,6 +27,9 @@ private: Gtk::ScrolledWindow directories_scrolled_window; Gtk::ScrolledWindow terminal_scrolled_window; Gtk::HBox info_and_status_hbox; + Gtk::VBox overlay_vbox; + Gtk::HBox overlay_hbox; + Gtk::Overlay overlay; Gtk::AboutDialog about; Glib::RefPtr css_provider;