diff --git a/src/notebook.cc b/src/notebook.cc index b0226cf..3a39842 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -3,6 +3,7 @@ #include "sourcefile.h" #include "singletons.h" #include +#include #include //TODO: remove using namespace std; //TODO: remove @@ -50,19 +51,29 @@ void Notebook::open(std::string path) { } can_read.close(); - auto tmp_project_path=project_path; - if(tmp_project_path=="") { - tmp_project_path=boost::filesystem::path(path).parent_path().string(); - } auto language=Source::guess_language(path); if(language && (language->get_id()=="chdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { - if(boost::filesystem::exists(tmp_project_path+"/CMakeLists.txt") && !boost::filesystem::exists(tmp_project_path+"/compile_commands.json")) { - make_compile_commands(); + auto view_project_path=project_path; + if(view_project_path=="") { + view_project_path=boost::filesystem::path(path).parent_path().string(); + auto found_project_path=find_project_path(view_project_path); + if(found_project_path!="") { + view_project_path=found_project_path; + Singleton::terminal()->print("Project path for "+path+" set to "+view_project_path+"\n"); + } + else + Singleton::terminal()->print("Error: could not find project path for "+path+"\n"); } - source_views.emplace_back(new Source::ClangView(path, tmp_project_path)); + if(boost::filesystem::exists(view_project_path+"/CMakeLists.txt") && !boost::filesystem::exists(view_project_path+"/compile_commands.json")) + make_compile_commands(view_project_path); + source_views.emplace_back(new Source::ClangView(path, view_project_path)); + } + else { + auto view_project_path=project_path; + if(view_project_path=="") + view_project_path=boost::filesystem::path(path).parent_path().string(); + source_views.emplace_back(new Source::GenericView(path, view_project_path, language)); } - else - source_views.emplace_back(new Source::GenericView(path, tmp_project_path, language)); scrolled_windows.emplace_back(new Gtk::ScrolledWindow()); hboxes.emplace_back(new Gtk::HBox()); @@ -101,6 +112,32 @@ void Notebook::open(std::string path) { }; } +std::string Notebook::find_project_path(const std::string &path) { + auto find_cmake_project=[this](const boost::filesystem::path &path) { + auto cmake_path=path; + cmake_path+="/CMakeLists.txt"; + for(auto &line: juci::filesystem::read_lines(cmake_path)) { + const std::regex cmake_project("^ *project *\\(.*$"); + std::smatch sm; + if(std::regex_match(line, sm, cmake_project)) { + return true; + } + } + return false; + }; + + auto boost_path=boost::filesystem::path(path); + if(find_cmake_project(boost_path)) + return boost_path.string(); + do { + boost_path=boost_path.parent_path(); + if(find_cmake_project(boost_path)) + return boost_path.string(); + } while(boost_path!=boost_path.root_directory()); + + return ""; +} + bool Notebook::save(int page) { if(page>=size()) return false; @@ -112,7 +149,7 @@ bool Notebook::save(int page) { //If CMakeLists.txt have been modified: if(boost::filesystem::path(view->file_path).filename().string()=="CMakeLists.txt") { - if(make_compile_commands()) { + if(project_path!="" && make_compile_commands(project_path)) { for(auto source_view: source_views) { if(auto source_clang_view=dynamic_cast(source_view)) { if(project_path==source_view->project_path) { @@ -133,14 +170,12 @@ bool Notebook::save(int page) { return false; } -bool Notebook::make_compile_commands() { - if(project_path.size()>0) { - Singleton::terminal()->print("Creating "+boost::filesystem::path(project_path+"/compile_commands.json").string()+"\n"); - //TODO: Windows... - if(Singleton::terminal()->execute(project_path, "cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 2>&1")) { - //TODO: refresh directories - return true; - } +bool Notebook::make_compile_commands(const std::string &path) { + Singleton::terminal()->print("Creating "+boost::filesystem::path(path+"/compile_commands.json").string()+"\n"); + //TODO: Windows... + if(Singleton::terminal()->execute(path, "cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 2>&1")) { + //TODO: refresh directories + return true; } return false; } diff --git a/src/notebook.h b/src/notebook.h index 43254f6..2c9d980 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -22,7 +22,8 @@ public: std::string project_path; private: - bool make_compile_commands(); + std::string find_project_path(const std::string &path); + bool make_compile_commands(const std::string &path); bool save_modified_dialog(); std::vector source_views; //Is NOT freed in destructor, this is intended for quick program exit. std::vector > scrolled_windows;