Browse Source

Major project cleanup. Fixes #97 making it possible to support other build tools

merge-requests/365/head
eidheim 10 years ago
parent
commit
9c69f18f18
  1. 2
      src/CMakeLists.txt
  2. 14
      src/cmake.cc
  3. 8
      src/cmake.h
  4. 35
      src/directories.cc
  5. 5
      src/directories.h
  6. 8
      src/filesystem.cc
  7. 2
      src/filesystem.h
  8. 69
      src/notebook.cc
  9. 1
      src/notebook.h
  10. 99
      src/project.cc
  11. 41
      src/project.h
  12. 29
      src/project_build.cc
  13. 39
      src/project_build.h
  14. 4
      src/source.cc
  15. 5
      src/source.h
  16. 27
      src/source_clang.cc
  17. 8
      src/source_clang.h
  18. 25
      src/window.cc
  19. 1
      src/window.h

2
src/CMakeLists.txt

@ -86,6 +86,8 @@ set(source_files juci.h
dialogs.cc
project.h
project.cc
project_build.h
project_build.cc
dispatcher.h
dispatcher.cc

14
src/cmake.cc

@ -18,7 +18,7 @@ CMake::CMake(const boost::filesystem::path &path) {
return false;
};
auto search_path=path;
auto search_path=boost::filesystem::is_directory(path)?path:path.parent_path();
while(true) {
auto search_cmake_path=search_path/"CMakeLists.txt";
if(boost::filesystem::exists(search_cmake_path))
@ -35,7 +35,7 @@ CMake::CMake(const boost::filesystem::path &path) {
}
}
boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &project_path) {
boost::filesystem::path CMake::get_default_build_path() {
boost::filesystem::path default_build_path=Config::get().project.default_build_path;
const std::string path_variable_project_directory_name="<project_directory_name>";
@ -55,7 +55,7 @@ boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::p
return default_build_path;
}
boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::path &project_path) {
boost::filesystem::path CMake::get_debug_build_path() {
boost::filesystem::path debug_build_path=Config::get().project.debug_build_path;
const std::string path_variable_project_directory_name="<project_directory_name>";
@ -86,14 +86,14 @@ boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::pat
return debug_build_path;
}
bool CMake::create_default_build(const boost::filesystem::path &project_path, bool force) {
bool CMake::update_default_build(bool force) {
if(project_path.empty())
return false;
if(!boost::filesystem::exists(project_path/"CMakeLists.txt"))
return false;
auto default_build_path=get_default_build_path(project_path);
auto default_build_path=get_default_build_path();
if(default_build_path.empty())
return false;
if(!boost::filesystem::exists(default_build_path)) {
@ -135,14 +135,14 @@ bool CMake::create_default_build(const boost::filesystem::path &project_path, bo
return false;
}
bool CMake::create_debug_build(const boost::filesystem::path &project_path) {
bool CMake::update_debug_build() {
if(project_path.empty())
return false;
if(!boost::filesystem::exists(project_path/"CMakeLists.txt"))
return false;
auto debug_build_path=get_debug_build_path(project_path);
auto debug_build_path=get_debug_build_path();
if(debug_build_path.empty())
return false;
if(!boost::filesystem::exists(debug_build_path)) {

8
src/cmake.h

@ -11,10 +11,10 @@ public:
boost::filesystem::path project_path;
std::vector<boost::filesystem::path> paths;
static boost::filesystem::path get_default_build_path(const boost::filesystem::path &project_path);
static boost::filesystem::path get_debug_build_path(const boost::filesystem::path &project_path);
static bool create_default_build(const boost::filesystem::path &project_path, bool force=false);
static bool create_debug_build(const boost::filesystem::path &project_path);
boost::filesystem::path get_default_build_path();
boost::filesystem::path get_debug_build_path();
bool update_default_build(bool force=false);
bool update_debug_build();
boost::filesystem::path get_executable(const boost::filesystem::path &file_path);

35
src/directories.cc

@ -32,7 +32,7 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat
auto get_target_folder=[this, &directories](const TreeModel::Path &path) {
if(path.size()==1)
return directories.current_path;
return directories.path;
else {
auto it=get_iter(path);
if(it) {
@ -46,7 +46,7 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat
auto prev_path=path;
prev_path.up();
if(prev_path.size()==1)
return directories.current_path;
return directories.path;
else {
prev_path.up();
it=get_iter(prev_path);
@ -222,26 +222,21 @@ void Directories::open(const boost::filesystem::path& dir_path) {
update_paths.clear();
update_mutex.unlock();
cmake=std::unique_ptr<CMake>(new CMake(dir_path));
CMake::create_default_build(cmake->project_path);
auto project=cmake->get_functions_parameters("project");
if(project.size()>0 && project[0].second.size()>0) {
auto title=project[0].second[0];
//TODO: report that set_title does not handle '_' correctly?
auto title=dir_path.filename().string();
size_t pos=0;
while((pos=title.find('_', pos))!=std::string::npos) {
title.replace(pos, 1, "__");
pos+=2;
}
get_column(0)->set_title(title);
}
else
get_column(0)->set_title("");
update_mutex.lock();
add_path(dir_path, Gtk::TreeModel::Row());
update_mutex.unlock();
current_path=dir_path;
path=dir_path;
JDEBUG("end");
}
@ -256,22 +251,22 @@ void Directories::update() {
JDEBUG("end");
}
void Directories::select(const boost::filesystem::path &path) {
void Directories::select(const boost::filesystem::path &select_path) {
JDEBUG("start");
if(current_path=="")
if(path=="")
return;
if(path.generic_string().substr(0, current_path.generic_string().size()+1)!=current_path.generic_string()+'/')
if(select_path.generic_string().substr(0, path.generic_string().size()+1)!=path.generic_string()+'/')
return;
std::list<boost::filesystem::path> paths;
boost::filesystem::path parent_path;
if(boost::filesystem::is_directory(path))
parent_path=path;
if(boost::filesystem::is_directory(select_path))
parent_path=select_path;
else
parent_path=path.parent_path();
parent_path=select_path.parent_path();
paths.emplace_front(parent_path);
while(parent_path!=current_path) {
while(parent_path!=path) {
parent_path=parent_path.parent_path();
paths.emplace_front(parent_path);
}
@ -288,8 +283,8 @@ void Directories::select(const boost::filesystem::path &path) {
});
}
tree_store->foreach_iter([this, &path](const Gtk::TreeModel::iterator& iter){
if(iter->get_value(column_record.path)==path) {
tree_store->foreach_iter([this, &select_path](const Gtk::TreeModel::iterator& iter){
if(iter->get_value(column_record.path)==select_path) {
auto tree_path=Gtk::TreePath(iter);
expand_to_path(tree_path);
set_cursor(tree_path);

5
src/directories.h

@ -5,10 +5,10 @@
#include <vector>
#include <string>
#include "boost/filesystem.hpp"
#include "cmake.h"
#include <thread>
#include <mutex>
#include <atomic>
#include <unordered_map>
#include "dispatcher.h"
class Directories : public Gtk::TreeView {
@ -52,8 +52,7 @@ public:
void select(const boost::filesystem::path &path);
std::function<void(const boost::filesystem::path &path)> on_row_activated;
std::unique_ptr<CMake> cmake;
boost::filesystem::path current_path;
boost::filesystem::path path;
protected:
bool on_button_press_event(GdkEventButton* event) override;

8
src/filesystem.cc

@ -1,6 +1,7 @@
#include <fstream>
#include <iostream>
#include <sstream>
#include <algorithm>
#include "filesystem.h"
#include "logging.h"
@ -161,3 +162,10 @@ std::string filesystem::unescape(const std::string &argument) {
}
return escaped;
}
bool filesystem::file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path) {
if(std::distance(file_path.begin(), file_path.end())<std::distance(path.begin(), path.end()))
return false;
return std::equal(path.begin(), path.end(), file_path.begin());
}

2
src/filesystem.h

@ -28,5 +28,7 @@ public:
static std::string escape_argument(const std::string &argument);
static std::string escape_argument(const boost::filesystem::path &argument) { return escape_argument(argument.string()); };
static std::string unescape(const std::string &argument);
static bool file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path);
};
#endif // JUCI_FILESYSTEM_H_

69
src/notebook.cc

@ -4,7 +4,7 @@
#include "logging.h"
#include <fstream>
#include <regex>
#include "cmake.h"
#include "project_build.h"
#include "filesystem.h"
#if GTKSOURCEVIEWMM_MAJOR_VERSION > 2 & GTKSOURCEVIEWMM_MINOR_VERSION > 17
@ -97,24 +97,10 @@ void Notebook::open(const boost::filesystem::path &file_path) {
}
auto language=Source::guess_language(file_path);
boost::filesystem::path project_path;
auto &directories=Directories::get();
if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/')
project_path=directories.cmake->project_path;
else {
project_path=file_path.parent_path();
CMake cmake(project_path);
if(cmake.project_path!="") {
project_path=cmake.project_path;
Terminal::get().print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
}
}
if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) {
CMake::create_default_build(project_path);
source_views.emplace_back(new Source::ClangView(file_path, project_path, language));
}
if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc"))
source_views.emplace_back(new Source::ClangView(file_path, language));
else
source_views.emplace_back(new Source::GenericView(file_path, project_path, language));
source_views.emplace_back(new Source::GenericView(file_path, language));
source_views.back()->scroll_to_cursor_delayed=[this](Source::View* view, bool center, bool show_tooltips) {
while(g_main_context_pending(NULL))
@ -260,28 +246,18 @@ bool Notebook::save(int page) {
//If CMakeLists.txt have been modified:
boost::filesystem::path project_path;
if(view->file_path.filename()=="CMakeLists.txt") {
auto &directories=Directories::get();
if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') {
if(CMake::create_default_build(directories.cmake->project_path, true))
project_path=directories.cmake->project_path;
}
else {
CMake cmake(view->file_path.parent_path());
if(CMake::create_default_build(cmake.project_path, true))
project_path=cmake.project_path;
}
if(project_path!="") {
auto debug_project_path=CMake::get_debug_build_path(project_path);
if(!debug_project_path.empty() && boost::filesystem::exists(debug_project_path))
CMake::create_debug_build(project_path);
auto build=Project::get_build(view->file_path);
build->update_default_build(true);
if(boost::filesystem::exists(build->get_debug_build_path()))
build->update_debug_build();
for(auto source_view: source_views) {
if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
if(project_path==source_clang_view->project_path)
if(filesystem::file_in_path(source_clang_view->file_path, build->project_path))
source_clang_view->full_reparse_needed=true;
}
}
}
}
JDEBUG("end true");
return true;
}
@ -297,19 +273,6 @@ bool Notebook::save_current() {
return save(get_current_page());
}
void Notebook::save_project_files() {
if(get_current_page()==-1)
return;
auto current_view=get_current_view();
for(int c=0;c<size();c++) {
auto view=get_view(c);
if(view->get_buffer()->get_modified()) {
if(current_view->project_path==view->project_path)
save(c);
}
}
}
bool Notebook::close(int page) {
JDEBUG("start");
if (page!=-1) {
@ -358,14 +321,12 @@ bool Notebook::close_current_page() {
}
boost::filesystem::path Notebook::get_current_folder() {
boost::filesystem::path current_path;
if(get_current_page()!=-1)
current_path=get_current_view()->project_path;
if(!Directories::get().path.empty())
return Directories::get().path;
else if(get_current_page()!=-1)
return get_current_view()->file_path.parent_path();
else
current_path=Directories::get().current_path;
return current_path;
return boost::filesystem::path();
}
bool Notebook::save_modified_dialog(int page) {

1
src/notebook.h

@ -34,7 +34,6 @@ public:
void open(const boost::filesystem::path &file_path);
bool save(int page);
bool save_current();
void save_project_files();
void configure(int view_nr);
boost::filesystem::path get_current_folder();

99
src/project.cc

@ -2,6 +2,7 @@
#include "config.h"
#include "terminal.h"
#include "filesystem.h"
#include "directories.h"
#include <fstream>
#include "menu.h"
#include "notebook.h"
@ -9,15 +10,26 @@
#include "debug_clang.h"
#endif
boost::filesystem::path Project::debug_last_stop_file_path;
std::unordered_map<std::string, std::string> Project::run_arguments;
std::unordered_map<std::string, std::string> Project::debug_run_arguments;
std::atomic<bool> Project::compiling;
std::atomic<bool> Project::debugging;
std::atomic<bool> Project::compiling(false);
std::atomic<bool> Project::debugging(false);
std::pair<boost::filesystem::path, std::pair<int, int> > Project::debug_stop;
boost::filesystem::path Project::debug_last_stop_file_path;
std::unique_ptr<Project::Language> Project::current_language;
void Project::save_files(const boost::filesystem::path &path) {
if(Notebook::get().get_current_page()==-1)
return;
for(int c=0;c<Notebook::get().size();c++) {
auto view=Notebook::get().get_view(c);
if(view->get_buffer()->get_modified()) {
if(filesystem::file_in_path(view->file_path, path))
Notebook::get().save(c);
}
}
}
void Project::debug_update_status(const std::string &debug_status) {
if(debug_status.empty())
debug_status_label().set_text("");
@ -74,39 +86,29 @@ std::unique_ptr<Project::Language> Project::get_language() {
return std::unique_ptr<Project::Language>(new Project::Clang());
}
std::unique_ptr<CMake> Project::Clang::get_cmake() {
boost::filesystem::path path;
Project::Language::Language() {
if(Notebook::get().get_current_page()!=-1)
path=Notebook::get().get_current_view()->file_path.parent_path();
build=get_build(Notebook::get().get_current_view()->file_path);
else
path=Directories::get().current_path;
if(path.empty())
return nullptr;
auto cmake=std::unique_ptr<CMake>(new CMake(path));
if(cmake->project_path.empty())
return nullptr;
if(!CMake::create_default_build(cmake->project_path))
return nullptr;
return cmake;
build=get_build(Directories::get().path);
}
std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
auto cmake=get_cmake();
if(!cmake)
if(build->get_default_build_path().empty() || !build->update_default_build())
return {"", ""};
auto project_path=cmake->project_path.string();
auto project_path=build->project_path.string();
auto run_arguments_it=run_arguments.find(project_path);
std::string arguments;
if(run_arguments_it!=run_arguments.end())
arguments=run_arguments_it->second;
if(arguments.empty()) {
auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
auto executable=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
if(executable!="") {
auto project_path=cmake->project_path;
auto build_path=CMake::get_default_build_path(project_path);
auto project_path=build->project_path;
auto build_path=build->get_default_build_path();
if(!build_path.empty()) {
size_t pos=executable.find(project_path.string());
if(pos!=std::string::npos)
@ -115,34 +117,33 @@ std::pair<std::string, std::string> Project::Clang::get_run_arguments() {
arguments=filesystem::escape_argument(executable);
}
else
arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path));
arguments=filesystem::escape_argument(build->get_default_build_path());
}
return {project_path, arguments};
}
void Project::Clang::compile() {
auto cmake=get_cmake();
if(!cmake)
if(build->get_default_build_path().empty() || !build->update_default_build())
return;
auto default_build_path=CMake::get_default_build_path(cmake->project_path);
auto default_build_path=build->get_default_build_path();
if(default_build_path.empty())
return;
compiling=true;
Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n");
Terminal::get().print("Compiling project "+build->project_path.string()+"\n");
Terminal::get().async_process(Config::get().project.make_command, default_build_path, [this](int exit_status) {
compiling=false;
});
}
void Project::Clang::compile_and_run() {
auto cmake=get_cmake();
if(!cmake)
if(build->get_default_build_path().empty() || !build->update_default_build())
return;
auto project_path=cmake->project_path;
auto default_build_path=CMake::get_default_build_path(project_path);
auto project_path=build->project_path;
auto default_build_path=build->get_default_build_path();
if(default_build_path.empty())
return;
@ -152,11 +153,9 @@ void Project::Clang::compile_and_run() {
arguments=run_arguments_it->second;
if(arguments.empty()) {
arguments=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
arguments=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
if(arguments.empty()) {
Terminal::get().print("Could not find add_executable in the following paths:\n");
for(auto &path: cmake->paths)
Terminal::get().print(" "+path.string()+"\n");
Terminal::get().print("Warning: could not find executable.\n");
Terminal::get().print("Solution: either use Project Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true);
return;
}
@ -180,22 +179,21 @@ void Project::Clang::compile_and_run() {
#ifdef JUCI_ENABLE_DEBUG
std::pair<std::string, std::string> Project::Clang::debug_get_run_arguments() {
auto cmake=get_cmake();
if(!cmake)
if(build->get_default_build_path().empty() || !build->update_default_build())
return {"", ""};
auto project_path=cmake->project_path.string();
auto project_path=build->project_path.string();
auto run_arguments_it=debug_run_arguments.find(project_path);
std::string arguments;
if(run_arguments_it!=debug_run_arguments.end())
arguments=run_arguments_it->second;
if(arguments.empty()) {
auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
auto executable=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
if(executable!="") {
auto project_path=cmake->project_path;
auto build_path=CMake::get_debug_build_path(project_path);
auto project_path=build->project_path;
auto build_path=build->get_debug_build_path();
if(!build_path.empty()) {
size_t pos=executable.find(project_path.string());
if(pos!=std::string::npos)
@ -204,22 +202,21 @@ std::pair<std::string, std::string> Project::Clang::debug_get_run_arguments() {
arguments=filesystem::escape_argument(executable);
}
else
arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path));
arguments=filesystem::escape_argument(build->get_debug_build_path());
}
return {project_path, arguments};
}
void Project::Clang::debug_start() {
auto cmake=get_cmake();
if(!cmake)
if(build->get_default_build_path().empty() || !build->update_default_build())
return;
auto project_path=cmake->project_path;
auto project_path=build->project_path;
auto debug_build_path=CMake::get_debug_build_path(project_path);
auto debug_build_path=build->get_debug_build_path();
if(debug_build_path.empty())
return;
if(!CMake::create_debug_build(project_path))
if(!build->update_debug_build())
return;
auto run_arguments_it=debug_run_arguments.find(project_path.string());
@ -228,11 +225,9 @@ void Project::Clang::debug_start() {
run_arguments=run_arguments_it->second;
if(run_arguments.empty()) {
run_arguments=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
run_arguments=build->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string();
if(run_arguments.empty()) {
Terminal::get().print("Could not find add_executable in the following paths:\n");
for(auto &path: cmake->paths)
Terminal::get().print(" "+path.string()+"\n");
Terminal::get().print("Warning: could not find executable.\n");
Terminal::get().print("Solution: either use Debug Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true);
return;
}
@ -245,7 +240,7 @@ void Project::Clang::debug_start() {
auto breakpoints=std::make_shared<std::vector<std::pair<boost::filesystem::path, int> > >();
for(int c=0;c<Notebook::get().size();c++) {
auto view=Notebook::get().get_view(c);
if(project_path==view->project_path) {
if(filesystem::file_in_path(view->file_path, project_path)) {
auto iter=view->get_buffer()->begin();
if(view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()>0)
breakpoints->emplace_back(view->file_path, iter.get_line()+1);

41
src/project.h

@ -2,37 +2,40 @@
#define JUCI_PROJECT_H_
#include <gtkmm.h>
#include "cmake.h"
#include <boost/filesystem.hpp>
#include "directories.h"
#include <atomic>
#include <mutex>
#include <unordered_map>
#include "tooltips.h"
#include "dispatcher.h"
#include "cmake.h"
#include <iostream>
#include "project_build.h"
namespace Project {
void save_files(const boost::filesystem::path &path);
class Project {
private:
static boost::filesystem::path debug_last_stop_file_path;
public:
static std::unordered_map<std::string, std::string> run_arguments;
static std::unordered_map<std::string, std::string> debug_run_arguments;
static std::atomic<bool> compiling;
static std::atomic<bool> debugging;
static std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
static void debug_update_stop();
static void debug_update_status(const std::string &debug_status);
static Gtk::Label &debug_status_label() {
extern boost::filesystem::path debug_last_stop_file_path;
extern std::unordered_map<std::string, std::string> run_arguments;
extern std::unordered_map<std::string, std::string> debug_run_arguments;
extern std::atomic<bool> compiling;
extern std::atomic<bool> debugging;
extern std::pair<boost::filesystem::path, std::pair<int, int> > debug_stop;
void debug_update_stop();
void debug_update_status(const std::string &debug_status);
inline Gtk::Label &debug_status_label() {
static Gtk::Label label;
return label;
}
class Language {
public:
Language() {}
Language();
virtual ~Language() {}
std::unique_ptr<Build> build;
virtual std::pair<std::string, std::string> get_run_arguments() {return {"", ""};}
virtual void compile() {}
virtual void compile_and_run() {}
@ -63,8 +66,6 @@ public:
Clang() : Language() {}
~Clang() { dispatcher.disconnect(); }
std::unique_ptr<CMake> get_cmake();
std::pair<std::string, std::string> get_run_arguments() override;
void compile() override;
void compile_and_run() override;
@ -120,8 +121,8 @@ public:
void compile_and_run() override;
};
static std::unique_ptr<Language> get_language();
static std::unique_ptr<Language> current_language;
std::unique_ptr<Language> get_language();
extern std::unique_ptr<Language> current_language;
};
#endif // JUCI_PROJECT_H_

29
src/project_build.cc

@ -0,0 +1,29 @@
#include "project_build.h"
std::unique_ptr<Project::Build> Project::get_build(const boost::filesystem::path &path) {
return std::unique_ptr<Project::Build>(new CMake(path));
}
Project::CMake::CMake(const boost::filesystem::path &path) : Project::Build(), cmake(path) {
project_path=cmake.project_path;
}
boost::filesystem::path Project::CMake::get_default_build_path() {
return cmake.get_default_build_path();
}
bool Project::CMake::update_default_build(bool force) {
return cmake.update_default_build(force);
}
boost::filesystem::path Project::CMake::get_debug_build_path() {
return cmake.get_debug_build_path();
}
bool Project::CMake::update_debug_build() {
return cmake.update_debug_build();
}
boost::filesystem::path Project::CMake::get_executable(const boost::filesystem::path &path) {
return cmake.get_executable(path);
}

39
src/project_build.h

@ -0,0 +1,39 @@
#ifndef JUCI_PROJECT_BUILD_H_
#define JUCI_PROJECT_BUILD_H_
#include <boost/filesystem.hpp>
#include "cmake.h"
namespace Project {
class Build {
public:
Build() {}
virtual ~Build() {}
boost::filesystem::path project_path;
virtual boost::filesystem::path get_default_build_path() {return boost::filesystem::path();}
virtual bool update_default_build(bool force=false) {return false;}
virtual boost::filesystem::path get_debug_build_path() {return boost::filesystem::path();}
virtual bool update_debug_build() {return false;}
virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) {return boost::filesystem::path();}
};
class CMake : public Build {
::CMake cmake;
public:
CMake(const boost::filesystem::path &path);
boost::filesystem::path get_default_build_path() override;
bool update_default_build(bool force=false) override;
boost::filesystem::path get_debug_build_path() override;
bool update_debug_build() override;
boost::filesystem::path get_executable(const boost::filesystem::path &path) override;
};
std::unique_ptr<Build> get_build(const boost::filesystem::path &path);
}
#endif // JUCI_PROJECT_BUILD_H_

4
src/source.cc

@ -82,7 +82,7 @@ std::string Source::FixIt::string(Glib::RefPtr<Gtk::TextBuffer> buffer) {
//////////////
AspellConfig* Source::View::spellcheck_config=NULL;
Source::View::View(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr<Gsv::Language> language): file_path(file_path), project_path(project_path), language(language) {
Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language): file_path(file_path), language(language) {
get_source_buffer()->begin_not_undoable_action();
if(language) {
if(filesystem::read_non_utf8(file_path, get_buffer())==-1)
@ -1724,7 +1724,7 @@ std::vector<std::string> Source::View::spellcheck_get_suggestions(const Gtk::Tex
/////////////////////
//// GenericView ////
/////////////////////
Source::GenericView::GenericView(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr<Gsv::Language> language) : View(file_path, project_path, language) {
Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language) : View(file_path, language) {
configure();
spellcheck_all=true;

5
src/source.h

@ -58,7 +58,7 @@ namespace Source {
class View : public Gsv::View {
public:
View(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr<Gsv::Language> language);
View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
~View();
virtual void configure();
@ -74,7 +74,6 @@ namespace Source {
void paste();
boost::filesystem::path file_path;
boost::filesystem::path project_path;
Glib::RefPtr<Gsv::Language> language;
std::function<void()> auto_indent;
@ -181,7 +180,7 @@ namespace Source {
static Glib::RefPtr<CompletionBuffer> create() {return Glib::RefPtr<CompletionBuffer>(new CompletionBuffer());}
};
public:
GenericView(const boost::filesystem::path &file_path, const boost::filesystem::path &project_path, Glib::RefPtr<Gsv::Language> language);
GenericView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
void parse_language_file(Glib::RefPtr<CompletionBuffer> &completion_buffer, bool &has_context_class, const boost::property_tree::ptree &pt);
};

27
src/source_clang.cc

@ -1,7 +1,7 @@
#include "source_clang.h"
#include "config.h"
#include "terminal.h"
#include "cmake.h"
#include "project.h"
#ifdef JUCI_ENABLE_DEBUG
#include "debug_clang.h"
#endif
@ -22,8 +22,8 @@ namespace sigc {
clang::Index Source::ClangViewParse::clang_index(0, 0);
Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language):
Source::View(file_path, project_path, language) {
Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language):
Source::View(file_path, language) {
JDEBUG("start");
auto tag_table=get_buffer()->get_tag_table();
@ -174,7 +174,9 @@ void Source::ClangViewParse::soft_reparse() {
}
std::vector<std::string> Source::ClangViewParse::get_compilation_commands() {
clang::CompilationDatabase db(CMake::get_default_build_path(project_path).string());
auto build=Project::get_build(file_path);
build->update_default_build();
clang::CompilationDatabase db(build->get_default_build_path().string());
clang::CompileCommands commands(file_path.string(), db);
std::vector<clang::CompileCommand> cmds = commands.get_commands();
std::vector<std::string> arguments;
@ -450,8 +452,8 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
//////////////////////////////
//// ClangViewAutocomplete ///
//////////////////////////////
Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language):
Source::ClangViewParse(file_path, project_path, language), autocomplete_state(AutocompleteState::IDLE) {
Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language):
Source::ClangViewParse(file_path, language), autocomplete_state(AutocompleteState::IDLE) {
get_buffer()->signal_changed().connect([this](){
if(autocomplete_dialog && autocomplete_dialog->shown)
delayed_reparse_connection.disconnect();
@ -791,8 +793,8 @@ bool Source::ClangViewAutocomplete::full_reparse() {
////////////////////////////
//// ClangViewRefactor /////
////////////////////////////
Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language):
Source::ClangViewAutocomplete(file_path, project_path, language) {
Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language):
Source::ClangViewAutocomplete(file_path, language) {
similar_tokens_tag=get_buffer()->create_tag();
similar_tokens_tag->property_weight()=1000; //TODO: replace with Pango::WEIGHT_ULTRAHEAVY in 2016 or so (when Ubuntu 14 is history)
@ -1007,13 +1009,6 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
auto referenced=cursor.get_referenced();
if(referenced) {
auto usr=referenced.get_usr();
boost::filesystem::path referenced_path=referenced.get_source_location().get_path();
//Terminal::get().print(usr+'\n', true); //TODO: remove
//Return empty if referenced is within project
if(referenced_path.generic_string().substr(0, this->project_path.generic_string().size()+1)==this->project_path.generic_string()+'/')
return data;
data.emplace_back("clang");
@ -1169,7 +1164,7 @@ void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) {
}
}
Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language): ClangViewRefactor(file_path, project_path, language) {
Source::ClangView::ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language): ClangViewRefactor(file_path, language) {
if(language) {
get_source_buffer()->set_highlight_syntax(true);
get_source_buffer()->set_language(language);

8
src/source_clang.h

@ -24,7 +24,7 @@ namespace Source {
int kind;
};
ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
void configure() override;
@ -71,7 +71,7 @@ namespace Source {
std::string brief_comments;
};
ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
virtual void async_delete();
bool full_reparse() override;
@ -96,7 +96,7 @@ namespace Source {
class ClangViewRefactor : public ClangViewAutocomplete {
public:
ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
protected:
sigc::connection delayed_tag_similar_tokens_connection;
private:
@ -109,7 +109,7 @@ namespace Source {
class ClangView : public ClangViewRefactor {
public:
ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
ClangView(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
void async_delete() override;
};
}

25
src/window.cc

@ -6,6 +6,7 @@
//#include "api.h"
#include "dialogs.h"
#include "filesystem.h"
#include "project.h"
namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
@ -168,7 +169,7 @@ void Window::set_menu_actions() {
}
else {
if(filesystem::write(path)) {
if(Directories::get().current_path!="")
if(Directories::get().path!="")
Directories::get().update();
notebook.open(path);
Terminal::get().print("New file "+path.string()+" created.\n");
@ -185,7 +186,7 @@ void Window::set_menu_actions() {
boost::system::error_code ec;
auto last_write_time=boost::filesystem::last_write_time(path, ec);
if(!ec && last_write_time>=time_now) {
if(Directories::get().current_path!="")
if(Directories::get().path!="")
Directories::get().update();
Terminal::get().print("New folder "+path.string()+" created.\n");
}
@ -260,7 +261,7 @@ void Window::set_menu_actions() {
if(file) {
file << notebook.get_current_view()->get_buffer()->get_text();
file.close();
if(Directories::get().current_path!="")
if(Directories::get().path!="")
Directories::get().update();
notebook.open(path);
Terminal::get().print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n");
@ -526,20 +527,22 @@ void Window::set_menu_actions() {
if(Project::compiling || Project::debugging)
return;
Project::current_language=Project::get_language();
if(Config::get().project.save_on_compile_or_run)
notebook.save_project_files();
Project::save_files(Project::current_language->build->project_path);
Project::current_language=Project::get_language();
Project::current_language->compile_and_run();
});
menu.add_action("compile", [this]() {
if(Project::compiling || Project::debugging)
return;
Project::current_language=Project::get_language();
if(Config::get().project.save_on_compile_or_run)
notebook.save_project_files();
Project::save_files(Project::current_language->build->project_path);
Project::current_language=Project::get_language();
Project::current_language->compile();
});
@ -548,7 +551,7 @@ void Window::set_menu_actions() {
entry_box.labels.emplace_back();
auto label_it=entry_box.labels.begin();
label_it->update=[label_it](int state, const std::string& message){
label_it->set_text("Run Command directory order: file project path, opened directory, current directory");
label_it->set_text("Run Command directory order: opened directory, file path, current directory");
};
label_it->update(0, "");
entry_box.entries.emplace_back(last_run_command, [this](const std::string& content){
@ -611,11 +614,11 @@ void Window::set_menu_actions() {
return;
}
if(Config::get().project.save_on_compile_or_run)
notebook.save_project_files();
Project::current_language=Project::get_language();
if(Config::get().project.save_on_compile_or_run)
Project::save_files(Project::current_language->build->project_path);
Project::current_language->debug_start();
});
menu.add_action("debug_stop", [this]() {

1
src/window.h

@ -4,7 +4,6 @@
#include <gtkmm.h>
#include "entrybox.h"
#include "notebook.h"
#include "project.h"
#include <atomic>
class Window : public Gtk::ApplicationWindow {

Loading…
Cancel
Save