Browse Source

Now attempts to make compile_commands.json if its missing, also remake it after changes to CMakeLists.txt and reparses the open clang-files. Some work left on terminal-execute/run/compile etc functions (only execute and async_execute (last one for compiling and running) will remain).

merge-requests/365/head
eidheim 10 years ago
parent
commit
02513f9b98
  1. 39
      src/notebook.cc
  2. 1
      src/notebook.h
  3. 60
      src/source.cc
  4. 7
      src/source.h
  5. 32
      src/terminal.cc
  6. 20
      src/terminal.h
  7. 6
      src/window.cc

39
src/notebook.cc

@ -4,6 +4,9 @@
#include "singletons.h"
#include <fstream>
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
}
@ -52,8 +55,12 @@ void Notebook::open(std::string 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(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();
}
source_views.emplace_back(new Source::ClangView(path, tmp_project_path));
}
else
source_views.emplace_back(new Source::GenericView(path, tmp_project_path, language));
@ -102,10 +109,38 @@ bool Notebook::save(int page) {
if(juci::filesystem::write(view->file_path, view->get_buffer())) {
view->get_buffer()->set_modified(false);
Singleton::terminal()->print("File saved to: " +view->file_path+"\n");
//If CMakeLists.txt have been modified:
if(boost::filesystem::path(view->file_path).filename().string()=="CMakeLists.txt") {
if(make_compile_commands()) {
for(auto source_view: source_views) {
if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
if(project_path==source_view->project_path) {
if(source_clang_view->restart_parse())
Singleton::terminal()->print("Reparsing "+source_clang_view->file_path+"\n");
else
Singleton::terminal()->print("Already reparsing "+source_clang_view->file_path+". Please reopen the file manually.\n");
}
}
}
}
}
return true;
}
Singleton::terminal()->print("Error: could not save file " +view->file_path+"\n");
}
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");
if(Singleton::terminal()->execute(project_path, "cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 2>&1")) {
//TODO: refresh directories
return true;
}
}
Singleton::terminal()->print("Error: could not save file " +view->file_path+"\n");
return false;
}

1
src/notebook.h

@ -22,6 +22,7 @@ public:
std::string project_path;
private:
bool make_compile_commands();
bool save_modified_dialog();
std::vector<Source::View*> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;

60
src/source.cc

@ -278,8 +278,7 @@ Source::GenericView::GenericView(const std::string& file_path, const std::string
clang::Index Source::ClangViewParse::clang_index(0, 0);
Source::ClangViewParse::ClangViewParse(const std::string& file_path, const std::string& project_path):
Source::View(file_path, project_path),
parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
Source::View(file_path, project_path) {
override_font(Pango::FontDescription(Singleton::Config::source()->font));
override_background_color(Gdk::RGBA(Singleton::Config::source()->background));
override_background_color(Gdk::RGBA(Singleton::Config::source()->background_selected), Gtk::StateFlags::STATE_FLAG_SELECTED);
@ -308,6 +307,28 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
}
//TODO: clear tag_class and param_spec?
parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path);
init_parse();
get_buffer()->signal_changed().connect([this]() {
start_reparse();
type_tooltips.hide();
diagnostic_tooltips.hide();
});
get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangViewParse::on_mark_set), false);
}
void Source::ClangViewParse::init_parse() {
type_tooltips.hide();
diagnostic_tooltips.hide();
get_buffer()->remove_all_tags(get_buffer()->begin(), get_buffer()->end());
clang_readable=false;
parse_thread_go=true;
parse_thread_mapped=false;
parse_thread_stop=false;
int start_offset = get_source_buffer()->begin().get_offset();
int end_offset = get_source_buffer()->end().get_offset();
auto buffer_map=get_buffer_map();
@ -340,7 +361,6 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
parse_thread_go=true;
});
parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path);
parse_done.connect([this](){
if(parse_thread_mapped) {
if(parsing_mutex.try_lock()) {
@ -361,6 +381,8 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
});
set_status("parsing...");
if(parse_thread.joinable())
parse_thread.join();
parse_thread=std::thread([this]() {
while(true) {
while(!parse_thread_go && !parse_thread_stop)
@ -380,14 +402,6 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
}
}
});
get_buffer()->signal_changed().connect([this]() {
start_reparse();
type_tooltips.hide();
diagnostic_tooltips.hide();
});
get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangViewParse::on_mark_set), false);
}
void Source::ClangViewParse::
@ -1048,6 +1062,10 @@ Source::ClangView::ClangView(const std::string& file_path, const std::string& pr
delete_thread.join();
delete this;
});
do_restart_parse.connect([this](){
init_parse();
restart_parse_running=false;
});
}
void Source::ClangView::delete_object() {
@ -1055,10 +1073,30 @@ void Source::ClangView::delete_object() {
parse_thread_stop=true;
delete_thread=std::thread([this](){
//TODO: Is it possible to stop the clang-process in progress?
if(restart_parse_thread.joinable())
restart_parse_thread.join();
if(parse_thread.joinable())
parse_thread.join();
if(autocomplete_thread.joinable())
autocomplete_thread.join();
do_delete_object();
});
}
bool Source::ClangView::restart_parse() {
if(!restart_parse_running) {
restart_parse_running=true;
parse_thread_stop=true;
if(restart_parse_thread.joinable())
restart_parse_thread.join();
restart_parse_thread=std::thread([this](){
if(parse_thread.joinable())
parse_thread.join();
if(autocomplete_thread.joinable())
autocomplete_thread.join();
do_restart_parse();
});
return true;
}
return false;
}

7
src/source.h

@ -91,13 +91,14 @@ namespace Source {
public:
ClangViewParse(const std::string& file_path, const std::string& project_path);
protected:
void init_parse();
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::mutex parsing_mutex;
std::unique_ptr<clang::Tokens> clang_tokens;
bool clang_readable=false;
bool clang_readable;
sigc::connection delayed_reparse_connection;
sigc::connection delayed_tooltips_connection;
@ -169,9 +170,13 @@ namespace Source {
public:
ClangView(const std::string& file_path, const std::string& project_path);
void delete_object();
bool restart_parse();
private:
Glib::Dispatcher do_delete_object;
Glib::Dispatcher do_restart_parse;
std::thread delete_thread;
std::thread restart_parse_thread;
bool restart_parse_running=false;
};
}; // class Source
#endif // JUCI_SOURCE_H_

32
src/terminal.cc

@ -56,6 +56,38 @@ Terminal::Terminal() {
});
}
bool Terminal::execute(const std::string &path, const std::string &command) {
boost::filesystem::path boost_path;
if(path=="")
boost_path=boost::filesystem::current_path();
else
boost_path=boost::filesystem::path(path);
auto cd_path_and_command="cd "+boost_path.string()+" 2>&1 && "+command;
FILE* p = NULL;
p = popen(cd_path_and_command.c_str(), "r");
if (p == NULL) {
print("Error: Failed to run command" + command + "\n");
return false;
}
else {
char buffer[1028];
while (fgets(buffer, 1028, p) != NULL) {
print(buffer);
}
int exit_code=pclose(p);
if(exit_code==0)
return true;
else
return false;
}
}
void Terminal::async_execute(const std::string &path, const std::string &command) {
}
void Terminal::set_change_folder_command(boost::filesystem::path CMake_path) {
INFO("Terminal: set_change_folder_command");
path = CMake_path.string();

20
src/terminal.h

@ -31,23 +31,25 @@ public:
};
Terminal();
void set_change_folder_command(boost::filesystem::path CMake_path);
void run(std::string executable);
void compile();
bool execute(const std::string &path, const std::string &command);
void async_execute(const std::string &path, const std::string &command);
void set_change_folder_command(boost::filesystem::path CMake_path); //TODO: remove
void run(std::string executable); //TODO: remove
void compile(); //TODO: remove
int print(std::string message);
void print(int line_nr, std::string message);
std::shared_ptr<InProgress> print_in_progress(std::string start_msg);
private:
void execute_command(std::string command, std::string mode);
void execute_command(std::string command, std::string mode); //TODO: remove
Gtk::TextView text_view;
Gtk::ScrolledWindow scrolled_window;
std::string change_folder_command;
std::string path;
const std::string cmake_sucsess = "Build files have been written to:";
const std::string make_built = "Built target";
const std::string make_executable = "Linking CXX executable";
std::string change_folder_command; //TODO: remove
std::string path; //TODO: remove
const std::string cmake_sucsess = "Build files have been written to:"; //TODO: remove
const std::string make_built = "Built target"; //TODO: remove
const std::string make_executable = "Linking CXX executable"; //TODO: remove
};
#endif // JUCI_TERMINAL_H_

6
src/window.cc

@ -5,6 +5,9 @@
#include "config.h"
#include "api.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
}
@ -82,6 +85,9 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL) {
Singleton::status()->set_text(notebook.get_current_view()->status);
}
});
notebook.signal_page_removed().connect([this](Gtk::Widget* page, guint page_num) {
entry_box.hide();
});
INFO("Window created");
} // Window constructor

Loading…
Cancel
Save