Browse Source

Added Go to Usage, and fixed #82 by removing the directory ignore option. This also makes implementing git integration easier.

merge-requests/365/head
eidheim 10 years ago
parent
commit
eb13a7e81f
  1. 13
      src/config.cc
  2. 8
      src/config.h
  3. 71
      src/directories.cc
  4. 1
      src/directories.h
  5. 9
      src/files.h
  6. 5
      src/menu.cc
  7. 12
      src/source.h
  8. 28
      src/source_clang.cc
  9. 1
      src/source_clang.h
  10. 78
      src/window.cc

13
src/config.cc

@ -81,7 +81,6 @@ void Config::retrieve_config() {
menu.keys[i.first] = i.second.get_value<std::string>(); menu.keys[i.first] = i.second.get_value<std::string>();
} }
get_source(); get_source();
get_directory_filter();
window.theme_name=cfg.get<std::string>("gtk_theme.name"); window.theme_name=cfg.get<std::string>("gtk_theme.name");
window.theme_variant=cfg.get<std::string>("gtk_theme.variant"); window.theme_variant=cfg.get<std::string>("gtk_theme.variant");
@ -188,15 +187,3 @@ void Config::get_source() {
} }
} }
} }
void Config::get_directory_filter() {
boost::property_tree::ptree dir_json = cfg.get_child("directoryfilter");
boost::property_tree::ptree ignore_json = dir_json.get_child("ignore");
boost::property_tree::ptree except_json = dir_json.get_child("exceptions");
directories.exceptions.clear();
directories.ignored.clear();
for ( auto &i : except_json )
directories.exceptions.emplace_back(i.second.get_value<std::string>());
for ( auto &i : ignore_json )
directories.ignored.emplace_back(i.second.get_value<std::string>());
}

8
src/config.h

@ -31,12 +31,6 @@ public:
int history_size; int history_size;
}; };
class Directories {
public:
std::vector<std::string> ignored;
std::vector<std::string> exceptions;
};
class Source { class Source {
public: public:
class DocumentationSearch { class DocumentationSearch {
@ -72,7 +66,6 @@ public:
Menu menu; Menu menu;
Window window; Window window;
Terminal terminal; Terminal terminal;
Directories directories;
Source source; Source source;
const boost::filesystem::path& juci_home_path() const { return home; } const boost::filesystem::path& juci_home_path() const { return home; }
@ -83,7 +76,6 @@ private:
bool check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path=""); bool check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path="");
void update_config_file(); void update_config_file();
void get_source(); void get_source();
void get_directory_filter();
boost::property_tree::ptree cfg; boost::property_tree::ptree cfg;
boost::filesystem::path home; boost::filesystem::path home;

71
src/directories.cc

@ -197,21 +197,6 @@ void Directories::select(const boost::filesystem::path &path) {
JDEBUG("end"); JDEBUG("end");
} }
bool Directories::ignored(std::string path) {
std::transform(path.begin(), path.end(), path.begin(), ::tolower);
for(std::string &i : Singleton::config->directories.exceptions) {
if(i == path)
return false;
}
for(auto &i : Singleton::config->directories.ignored) {
if(path.find(i, 0) != std::string::npos)
return true;
}
return false;
}
void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) { void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &parent) {
last_write_times[dir_path.string()]={parent, boost::filesystem::last_write_time(dir_path)}; last_write_times[dir_path.string()]={parent, boost::filesystem::last_write_time(dir_path)};
std::unique_ptr<Gtk::TreeNodeChildren> children; //Gtk::TreeNodeChildren is missing default constructor... std::unique_ptr<Gtk::TreeNodeChildren> children; //Gtk::TreeNodeChildren is missing default constructor...
@ -227,39 +212,37 @@ void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::T
boost::filesystem::directory_iterator end_it; boost::filesystem::directory_iterator end_it;
for(boost::filesystem::directory_iterator it(dir_path);it!=end_it;it++) { for(boost::filesystem::directory_iterator it(dir_path);it!=end_it;it++) {
auto filename=it->path().filename().string(); auto filename=it->path().filename().string();
if (!ignored(filename)) { bool already_added=false;
bool already_added=false; if(*children) {
if(*children) { for(auto &child: *children) {
for(auto &child: *children) { if(child.get_value(column_record.name)==filename) {
if(child.get_value(column_record.name)==filename) { not_deleted.emplace(filename);
not_deleted.emplace(filename); already_added=true;
already_added=true; break;
break;
}
} }
} }
if(!already_added) { }
auto child = tree_store->append(*children); if(!already_added) {
not_deleted.emplace(filename); auto child = tree_store->append(*children);
child->set_value(column_record.name, filename); not_deleted.emplace(filename);
child->set_value(column_record.path, it->path().string()); child->set_value(column_record.name, filename);
if (boost::filesystem::is_directory(*it)) { child->set_value(column_record.path, it->path().string());
child->set_value(column_record.id, "a"+filename); if (boost::filesystem::is_directory(*it)) {
auto grandchild=tree_store->append(child->children()); child->set_value(column_record.id, "a"+filename);
grandchild->set_value(column_record.name, std::string("(empty)")); auto grandchild=tree_store->append(child->children());
grandchild->set_value(column_record.name, std::string("(empty)"));
Gdk::RGBA rgba;
rgba.set_rgba(0.5, 0.5, 0.5);
grandchild->set_value(column_record.color, rgba);
}
else {
child->set_value(column_record.id, "b"+filename);
auto language=Source::guess_language(it->path().filename());
if(!language) {
Gdk::RGBA rgba; Gdk::RGBA rgba;
rgba.set_rgba(0.5, 0.5, 0.5); rgba.set_rgba(0.5, 0.5, 0.5);
grandchild->set_value(column_record.color, rgba); child->set_value(column_record.color, rgba);
}
else {
child->set_value(column_record.id, "b"+filename);
auto language=Source::guess_language(it->path().filename());
if(!language) {
Gdk::RGBA rgba;
rgba.set_rgba(0.5, 0.5, 0.5);
child->set_value(column_record.color, rgba);
}
} }
} }
} }

1
src/directories.h

@ -38,7 +38,6 @@ public:
private: private:
void add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row); void add_path(const boost::filesystem::path& dir_path, const Gtk::TreeModel::Row &row);
bool ignored(std::string path);
Gtk::TreeView tree_view; Gtk::TreeView tree_view;
Glib::RefPtr<Gtk::TreeStore> tree_store; Glib::RefPtr<Gtk::TreeStore> tree_store;
ColumnRecord column_record; ColumnRecord column_record;

9
src/files.h

@ -1,6 +1,6 @@
#include <string> #include <string>
#define JUCI_VERSION "0.9.5" #define JUCI_VERSION "0.9.6"
const std::string configjson = const std::string configjson =
"{\n" "{\n"
@ -85,6 +85,7 @@ const std::string configjson =
" \"source_center_cursor\": \"<primary>l\",\n" " \"source_center_cursor\": \"<primary>l\",\n"
" \"source_find_documentation\": \"<primary><shift>d\",\n" " \"source_find_documentation\": \"<primary><shift>d\",\n"
" \"source_goto_declaration\": \"<primary>d\",\n" " \"source_goto_declaration\": \"<primary>d\",\n"
" \"source_goto_usage\": \"<primary>u\",\n"
" \"source_goto_method\": \"<primary>m\",\n" " \"source_goto_method\": \"<primary>m\",\n"
" \"source_rename\": \"<primary>r\",\n" " \"source_rename\": \"<primary>r\",\n"
" \"source_goto_next_diagnostic\": \"<primary>e\",\n" " \"source_goto_next_diagnostic\": \"<primary>e\",\n"
@ -117,12 +118,6 @@ const std::string configjson =
" \"@any\": \"https://www.google.com/search?btnI&q=\"\n" " \"@any\": \"https://www.google.com/search?btnI&q=\"\n"
" }\n" " }\n"
" }\n" " }\n"
" },\n"
" \"directoryfilter\": {\n"
" \"ignore\": [\n"
" ],\n"
" \"exceptions\": [\n"
" ]\n"
" }\n" " }\n"
"}\n"; "}\n";

5
src/menu.cc

@ -211,6 +211,11 @@ void Menu::init() {
+accels["source_goto_declaration"]+ //For Ubuntu... +accels["source_goto_declaration"]+ //For Ubuntu...
" </item>" " </item>"
" <item>" " <item>"
" <attribute name='label' translatable='yes'>_Go to Usage</attribute>"
" <attribute name='action'>app.source_goto_usage</attribute>"
+accels["source_goto_usage"]+ //For Ubuntu...
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Go to Method</attribute>" " <attribute name='label' translatable='yes'>_Go to Method</attribute>"
" <attribute name='action'>app.source_goto_method</attribute>" " <attribute name='action'>app.source_goto_method</attribute>"
+accels["source_goto_method"]+ //For Ubuntu... +accels["source_goto_method"]+ //For Ubuntu...

12
src/source.h

@ -19,6 +19,10 @@ namespace Source {
Token(Glib::RefPtr<Gsv::Language> language, int type, const std::string &spelling, const std::string &usr): Token(Glib::RefPtr<Gsv::Language> language, int type, const std::string &spelling, const std::string &usr):
language(language), type(type), spelling(spelling), usr(usr) {} language(language), type(type), spelling(spelling), usr(usr) {}
operator bool() const {return (type>=0 && spelling.size()>0 && usr.size()>0);} operator bool() const {return (type>=0 && spelling.size()>0 && usr.size()>0);}
bool operator==(const Token &o) const {return (type==o.type &&
spelling==o.spelling &&
usr==o.usr);}
bool operator!=(const Token &o) const {return !(*this==o);}
Glib::RefPtr<Gsv::Language> language; Glib::RefPtr<Gsv::Language> language;
int type; int type;
@ -29,11 +33,12 @@ namespace Source {
class Offset { class Offset {
public: public:
Offset() {} Offset() {}
Offset(unsigned line, unsigned index): line(line), index(index) {} Offset(unsigned line, unsigned index, const boost::filesystem::path &file_path=""): line(line), index(index), file_path(file_path) {}
bool operator==(const Offset &o) {return (line==o.line && index==o.index);} bool operator==(const Offset &o) {return (line==o.line && index==o.index);}
unsigned line; unsigned line;
unsigned index; unsigned index;
boost::filesystem::path file_path;
}; };
class FixIt { class FixIt {
@ -71,7 +76,8 @@ namespace Source {
Glib::RefPtr<Gsv::Language> language; Glib::RefPtr<Gsv::Language> language;
std::function<void()> auto_indent; std::function<void()> auto_indent;
std::function<std::pair<std::string, Offset>()> get_declaration_location; std::function<Offset()> get_declaration_location;
std::function<std::vector<std::pair<Offset, std::string> >(const Token &token)> get_usages;
std::function<void()> goto_method; std::function<void()> goto_method;
std::function<Token()> get_token; std::function<Token()> get_token;
std::function<std::vector<std::string>()> get_token_data; std::function<std::vector<std::string>()> get_token_data;
@ -79,6 +85,8 @@ namespace Source {
std::function<void()> goto_next_diagnostic; std::function<void()> goto_next_diagnostic;
std::function<void()> apply_fix_its; std::function<void()> apply_fix_its;
std::unique_ptr<SelectionDialog> selection_dialog;
std::function<void(View* view, const std::string &status)> on_update_status; std::function<void(View* view, const std::string &status)> on_update_status;
std::function<void(View* view, const std::string &info)> on_update_info; std::function<void(View* view, const std::string &info)> on_update_info;
void set_status(const std::string &status); void set_status(const std::string &status);

28
src/source_clang.cc

@ -1028,7 +1028,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
}); });
get_declaration_location=[this](){ get_declaration_location=[this](){
std::pair<std::string, Offset> location; Offset location;
if(source_readable) { if(source_readable) {
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();
auto line=(unsigned)iter.get_line(); auto line=(unsigned)iter.get_line();
@ -1039,10 +1039,10 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) {
auto referenced=cursor.get_referenced(); auto referenced=cursor.get_referenced();
if(referenced) { if(referenced) {
location.first=referenced.get_source_location().get_path(); location.file_path=referenced.get_source_location().get_path();
auto clang_offset=referenced.get_source_location().get_offset(); auto clang_offset=referenced.get_source_location().get_offset();
location.second.line=clang_offset.line; location.line=clang_offset.line;
location.second.index=clang_offset.index; location.index=clang_offset.index;
break; break;
} }
} }
@ -1052,6 +1052,26 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
return location; return location;
}; };
get_usages=[this](const Token &token) {
std::vector<std::pair<Offset, std::string> > usages;
if(source_readable && 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<clang::CursorKind>(token.type), token.spelling, token.usr);
for(auto &offset: offsets) {
auto start_iter=get_buffer()->get_iter_at_line(offset.first.line-1);
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t'))
start_iter.forward_char();
auto end_iter=start_iter;
while(!end_iter.ends_line())
end_iter.forward_char();
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), get_buffer()->get_text(start_iter, end_iter));
}
}
return usages;
};
goto_method=[this](){ goto_method=[this](){
if(source_readable) { if(source_readable) {
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();

1
src/source_clang.h

@ -121,7 +121,6 @@ namespace Source {
void tag_similar_tokens(const Token &token); void tag_similar_tokens(const Token &token);
Glib::RefPtr<Gtk::TextTag> similar_tokens_tag; Glib::RefPtr<Gtk::TextTag> similar_tokens_tag;
Token last_tagged_token; Token last_tagged_token;
std::unique_ptr<SelectionDialog> selection_dialog;
bool renaming=false; bool renaming=false;
}; };

78
src/window.cc

@ -382,10 +382,15 @@ void Window::set_menu_actions() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_declaration_location) { if(notebook.get_current_view()->get_declaration_location) {
auto location=notebook.get_current_view()->get_declaration_location(); auto location=notebook.get_current_view()->get_declaration_location();
if(location.first.size()>0) { if(!location.file_path.empty()) {
notebook.open(location.first); boost::filesystem::path declaration_file;
auto line=static_cast<int>(location.second.line)-1; boost::system::error_code ec;
auto index=static_cast<int>(location.second.index)-1; declaration_file=boost::filesystem::canonical(location.file_path, ec);
if(ec)
declaration_file=location.file_path;
notebook.open(declaration_file);
auto line=static_cast<int>(location.line)-1;
auto index=static_cast<int>(location.index)-1;
auto buffer=notebook.get_current_view()->get_buffer(); auto buffer=notebook.get_current_view()->get_buffer();
line=std::min(line, buffer->get_line_count()-1); line=std::min(line, buffer->get_line_count()-1);
if(line>=0) { if(line>=0) {
@ -405,6 +410,71 @@ void Window::set_menu_actions() {
} }
} }
}); });
menu->add_action("source_goto_usage", [this]() {
if(notebook.get_current_page()!=-1) {
auto current_view=notebook.get_current_view();
if(current_view->get_token && current_view->get_usages) {
auto token=current_view->get_token();
if(token) {
auto iter=current_view->get_buffer()->get_insert()->get_iter();
Gdk::Rectangle visible_rect;
current_view->get_visible_rect(visible_rect);
Gdk::Rectangle iter_rect;
current_view->get_iter_location(iter, iter_rect);
iter_rect.set_width(1);
if(!visible_rect.intersects(iter_rect)) {
current_view->get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3);
}
current_view->selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*current_view, current_view->get_buffer()->create_mark(iter)));
auto rows=std::make_shared<std::unordered_map<std::string, Source::Offset> >();
//First add usages in current file
auto usages=current_view->get_usages(token);
for(auto &usage: usages) {
auto iter=current_view->get_buffer()->get_iter_at_line_index(usage.first.line, usage.first.index);
auto row=std::to_string(iter.get_line()+1)+':'+std::to_string(iter.get_line_offset()+1)+' '+usage.second;
(*rows)[row]=usage.first;
current_view->selection_dialog->add_row(row);
}
//Then the remaining opened files
for(int page=0;page<notebook.size();page++) {
auto view=notebook.get_view(page);
if(view!=current_view) {
if(view->get_usages) {
auto usages=view->get_usages(token);
for(auto &usage: usages) {
auto iter=view->get_buffer()->get_iter_at_line_index(usage.first.line, usage.first.index);
auto row=usage.first.file_path.filename().string()+":"+std::to_string(iter.get_line()+1)+':'+std::to_string(iter.get_line_offset()+1)+' '+usage.second;
(*rows)[row]=usage.first;
current_view->selection_dialog->add_row(row);
}
}
}
}
if(rows->size()==0)
return;
current_view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) {
auto offset=rows->at(selected);
boost::filesystem::path declaration_file;
boost::system::error_code ec;
declaration_file=boost::filesystem::canonical(offset.file_path, ec);
if(ec)
declaration_file=offset.file_path;
notebook.open(declaration_file);
auto view=notebook.get_current_view();
view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(offset.line, offset.index));
while(g_main_context_pending(NULL))
g_main_context_iteration(NULL, false);
if(notebook.get_current_page()!=-1)
view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
//delayed_tooltips_connection.disconnect();
};
current_view->selection_dialog->show();
}
}
}
});
menu->add_action("source_goto_method", [this]() { menu->add_action("source_goto_method", [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->goto_method) { if(notebook.get_current_view()->goto_method) {

Loading…
Cancel
Save