From 07a43c6bd8cdbd54f29300fe257e16596ab15da9 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 8 Feb 2016 22:43:10 +0100 Subject: [PATCH 01/41] WIP: project cleanup, added project classes so that the hard dependency towards clang is removed in Window. In this way, one can add run commands for other project and file types. --- src/CMakeLists.txt | 2 + src/notebook.cc | 8 ++++ src/notebook.h | 2 + src/project.cc | 113 +++++++++++++++++++++++++++++++++++++++++++++ src/project.h | 50 ++++++++++++++++++++ src/window.cc | 99 ++++++--------------------------------- src/window.h | 3 ++ 7 files changed, 191 insertions(+), 86 deletions(-) create mode 100644 src/project.cc create mode 100644 src/project.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 533baf8..e98ca99 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,6 +84,8 @@ set(source_files juci.h cmake.h cmake.cc dialogs.cc + project.h + project.cc ../libclangmm/src/CodeCompleteResults.cc ../libclangmm/src/CompilationDatabase.cc diff --git a/src/notebook.cc b/src/notebook.cc index 9e3b73f..2cdc2d4 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -354,6 +354,14 @@ boost::filesystem::path Notebook::get_current_folder() { return current_path; } +std::unique_ptr Notebook::get_project() { + boost::filesystem::path file_path; + if(get_current_page()!=-1) + file_path=get_current_view()->file_path; + + return std::unique_ptr(new ProjectClang(file_path)); +} + bool Notebook::save_modified_dialog(int page) { Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); dialog.set_default_response(Gtk::RESPONSE_YES); diff --git a/src/notebook.h b/src/notebook.h index 1b6f2d8..2c15ad5 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -5,6 +5,7 @@ #include "gtkmm.h" #include "source.h" #include "source_clang.h" +#include "project.h" #include #include #include @@ -30,6 +31,7 @@ public: void save_project_files(); void configure(int view_nr); boost::filesystem::path get_current_folder(); + std::unique_ptr get_project(); Gtk::Label info; Gtk::Label status; diff --git a/src/project.cc b/src/project.cc new file mode 100644 index 0000000..b14dbcd --- /dev/null +++ b/src/project.cc @@ -0,0 +1,113 @@ +#include "project.h" +#include "config.h" +#include "terminal.h" +#include "filesystem.h" + +std::unordered_map Project::run_arguments; +std::unordered_map Project::debug_run_arguments; +std::atomic Project::compiling(false); +std::atomic Project::debugging(false); + +std::unique_ptr ProjectClang::get_cmake() { + boost::filesystem::path path; + if(!file_path.empty()) + path=file_path.parent_path(); + else + path=Directories::get().current_path; + if(path.empty()) + return nullptr; + auto cmake=std::unique_ptr(new CMake(path)); + if(cmake->project_path.empty()) + return nullptr; + if(!CMake::create_default_build(cmake->project_path)) + return nullptr; + return cmake; +} + +std::pair ProjectClang::get_run_arguments() { + auto cmake=get_cmake(); + if(!cmake) + return {"", ""}; + + auto project_path=cmake->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(file_path).string(); + + if(executable!="") { + auto project_path=cmake->project_path; + auto default_build_path=CMake::get_default_build_path(project_path); + if(!default_build_path.empty()) { + size_t pos=executable.find(project_path.string()); + if(pos!=std::string::npos) + executable.replace(pos, project_path.string().size(), default_build_path.string()); + } + arguments=filesystem::escape_argument(executable); + } + else + arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); + } + + return {project_path, arguments}; +} + +void ProjectClang::compile() { + auto cmake=get_cmake(); + if(!cmake) + return; + + auto default_build_path=CMake::get_default_build_path(cmake->project_path); + if(default_build_path.empty()) + return; + compiling=true; + Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); + Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status) { + compiling=false; + }); +} + +void ProjectClang::compile_and_run() { + auto cmake=get_cmake(); + if(!cmake) + return; + auto project_path=cmake->project_path; + + auto default_build_path=CMake::get_default_build_path(project_path); + if(default_build_path.empty()) + return; + + auto run_arguments_it=run_arguments.find(project_path.string()); + std::string arguments; + if(run_arguments_it!=run_arguments.end()) + arguments=run_arguments_it->second; + + if(arguments.empty()) { + arguments=cmake->get_executable(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("Solution: either use Project Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); + return; + } + size_t pos=arguments.find(project_path.string()); + if(pos!=std::string::npos) + arguments.replace(pos, project_path.string().size(), default_build_path.string()); + arguments=filesystem::escape_argument(arguments); + } + + compiling=true; + Terminal::get().print("Compiling and running "+arguments+"\n"); + Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){ + compiling=false; + if(exit_status==EXIT_SUCCESS) { + Terminal::get().async_process(arguments, default_build_path, [this, arguments](int exit_status){ + Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n'); + }); + } + }); +} diff --git a/src/project.h b/src/project.h new file mode 100644 index 0000000..872f0b5 --- /dev/null +++ b/src/project.h @@ -0,0 +1,50 @@ +#ifndef JUCI_PROJECT_H_ +#define JUCI_PROJECT_H_ + +#include "cmake.h" +#include +#include "directories.h" +#include + +class Project { +public: + Project(const boost::filesystem::path &file_path) : file_path(file_path) {} + virtual ~Project() {} + + boost::filesystem::path file_path; + + static std::unordered_map run_arguments; + static std::unordered_map debug_run_arguments; + static std::atomic compiling; + static std::atomic debugging; + + virtual std::pair get_run_arguments() {return {"", ""};} + virtual void compile() {} + virtual void compile_and_run() {} + + virtual std::pair debug_get_run_arguments() {return {"", ""};} + virtual void debug_start_continue() {} + virtual void debug_stop() {} + virtual void debug_kill() {} + virtual void debug_step_over() {} + virtual void debug_step_into() {} + virtual void debug_step_out() {} + virtual void debug_backtrace() {} + virtual void debug_show_variables() {} + virtual void debug_run_command() {} + virtual void debug_toggle_breakpoint() {} + virtual void debug_goto_stop() {} +}; + +class ProjectClang : public Project { +public: + ProjectClang(const boost::filesystem::path &file_path) : Project(file_path) {} + + std::unique_ptr get_cmake(); + + std::pair get_run_arguments() override; + void compile() override; + void compile_and_run() override; +}; + +#endif // JUCI_PROJECT_H_ diff --git a/src/window.cc b/src/window.cc index ad492d6..108ea41 100644 --- a/src/window.cc +++ b/src/window.cc @@ -591,33 +591,11 @@ void Window::set_menu_actions() { }); menu.add_action("project_set_run_arguments", [this]() { - auto cmake=get_cmake(); - if(!cmake) + project=notebook.get_project(); + auto run_arguments=std::make_shared >(project->get_run_arguments()); + if(run_arguments->second.empty()) return; - auto project_path=std::make_shared(cmake->project_path); - auto run_arguments_it=project_run_arguments.find(project_path->string()); - std::string run_arguments; - if(run_arguments_it!=project_run_arguments.end()) - run_arguments=run_arguments_it->second; - - if(run_arguments.empty()) { - auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); - - if(executable!="") { - auto project_path=cmake->project_path; - auto default_build_path=CMake::get_default_build_path(project_path); - if(!default_build_path.empty()) { - size_t pos=executable.find(project_path.string()); - if(pos!=std::string::npos) - executable.replace(pos, project_path.string().size(), default_build_path.string()); - } - run_arguments=filesystem::escape_argument(executable); - } - else - run_arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); - } - entry_box.clear(); entry_box.labels.emplace_back(); auto label_it=entry_box.labels.begin(); @@ -625,8 +603,8 @@ void Window::set_menu_actions() { label_it->set_text("Set empty to let juCi++ deduce executable"); }; label_it->update(0, ""); - entry_box.entries.emplace_back(run_arguments, [this, project_path](const std::string& content){ - project_run_arguments[project_path->string()]=content; + entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ + Project::run_arguments[run_arguments->first]=content; entry_box.hide(); }, 50); auto entry_it=entry_box.entries.begin(); @@ -637,75 +615,24 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("compile_and_run", [this]() { - if(compiling) + if(Project::compiling) return; if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - - auto cmake=get_cmake(); - if(!cmake) - return; - auto project_path=cmake->project_path; - - auto default_build_path=CMake::get_default_build_path(project_path); - if(default_build_path.empty()) - return; - - auto run_arguments_it=project_run_arguments.find(project_path.string()); - std::string run_arguments; - if(run_arguments_it!=project_run_arguments.end()) - run_arguments=run_arguments_it->second; - - std::string command; - if(!run_arguments.empty()) { - command=run_arguments; - } - else { - command=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); - if(command.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("Solution: either use Project Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); - return; - } - size_t pos=command.find(project_path.string()); - if(pos!=std::string::npos) - command.replace(pos, project_path.string().size(), default_build_path.string()); - command=filesystem::escape_argument(command); - } - - compiling=true; - Terminal::get().print("Compiling and running "+command+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, command, default_build_path](int exit_status){ - compiling=false; - if(exit_status==EXIT_SUCCESS) { - Terminal::get().async_process(command, default_build_path, [this, command](int exit_status){ - Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); - }); - } - }); + + project=notebook.get_project(); + project->compile_and_run(); }); menu.add_action("compile", [this]() { - if(compiling) + if(Project::compiling) return; if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - - auto cmake=get_cmake(); - if(!cmake) - return; - - auto default_build_path=CMake::get_default_build_path(cmake->project_path); - if(default_build_path.empty()) - return; - compiling=true; - Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status){ - compiling=false; - }); + + project=notebook.get_project(); + project->compile(); }); menu.add_action("run_command", [this]() { diff --git a/src/window.h b/src/window.h index a3485a2..a23ad39 100644 --- a/src/window.h +++ b/src/window.h @@ -6,6 +6,7 @@ #include "notebook.h" #include "cmake.h" #include "tooltips.h" +#include "project.h" #include class Window : public Gtk::ApplicationWindow { @@ -34,6 +35,8 @@ private: Gtk::AboutDialog about; EntryBox entry_box; + std::unique_ptr project; + std::atomic compiling; std::atomic debugging; From c62beeb4af04e30f9c410d1c054402fc6ead236f Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 9 Feb 2016 10:40:08 +0100 Subject: [PATCH 02/41] Added markdown view support --- src/notebook.cc | 7 ++++++- src/project.cc | 33 +++++++++++++++++++++++++++++++++ src/project.h | 9 +++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/notebook.cc b/src/notebook.cc index 2cdc2d4..68f8614 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -359,6 +359,12 @@ std::unique_ptr Notebook::get_project() { if(get_current_page()!=-1) file_path=get_current_view()->file_path; + if(get_current_page()!=-1) { + if(get_current_view()->language->get_id()=="markdown") { + return std::unique_ptr(new ProjectMarkDown(file_path)); + } + } + return std::unique_ptr(new ProjectClang(file_path)); } @@ -378,4 +384,3 @@ bool Notebook::save_modified_dialog(int page) { return false; } } - diff --git a/src/project.cc b/src/project.cc index b14dbcd..4385b61 100644 --- a/src/project.cc +++ b/src/project.cc @@ -2,6 +2,7 @@ #include "config.h" #include "terminal.h" #include "filesystem.h" +#include std::unordered_map Project::run_arguments; std::unordered_map Project::debug_run_arguments; @@ -111,3 +112,35 @@ void ProjectClang::compile_and_run() { } }); } + +ProjectMarkDown::~ProjectMarkDown() { + if(!last_temp_path.empty()) { + boost::filesystem::remove(last_temp_path); + last_temp_path=boost::filesystem::path(); + } +} + +void ProjectMarkDown::compile_and_run() { + if(!last_temp_path.empty()) { + boost::filesystem::remove(last_temp_path); + last_temp_path=boost::filesystem::path(); + } + + std::stringstream stdin_stream, stdout_stream; + auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "markdown "+file_path.string(), this->file_path.parent_path()); + if(exit_status==0) { + boost::system::error_code ec; + auto temp_path=boost::filesystem::temp_directory_path(ec); + if(!ec) { + temp_path/=boost::filesystem::unique_path(); + temp_path+=".html"; + if(!boost::filesystem::exists(temp_path)) { + last_temp_path=temp_path; + std::ofstream file_stream(temp_path.string(), std::fstream::binary); + file_stream << stdout_stream.rdbuf(); + file_stream.close(); + Terminal::get().async_process("open "+temp_path.string()); + } + } + } +} diff --git a/src/project.h b/src/project.h index 872f0b5..eb74f85 100644 --- a/src/project.h +++ b/src/project.h @@ -47,4 +47,13 @@ public: void compile_and_run() override; }; +class ProjectMarkDown : public Project { +public: + ProjectMarkDown(const boost::filesystem::path &file_path) : Project(file_path) {} + ~ProjectMarkDown(); + + boost::filesystem::path last_temp_path; + void compile_and_run() override; +}; + #endif // JUCI_PROJECT_H_ From 35ab8810716e89aa504a8b698c8d531aa9eac5f6 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 9 Feb 2016 13:11:27 +0100 Subject: [PATCH 03/41] Finished project cleanup --- src/debug.cc | 16 ++- src/debug.h | 2 +- src/notebook.cc | 8 +- src/notebook.h | 2 + src/project.cc | 284 ++++++++++++++++++++++++++++++++++++++++++-- src/project.h | 38 ++++-- src/window.cc | 305 +++++++----------------------------------------- src/window.h | 11 -- 8 files changed, 360 insertions(+), 306 deletions(-) diff --git a/src/debug.cc b/src/debug.cc index ed27d14..6289da1 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -36,7 +36,7 @@ Debug::Debug(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { } void Debug::start(const std::string &command, const boost::filesystem::path &path, - std::shared_ptr > > breakpoints, + const std::vector > &breakpoints, std::function callback, std::function status_callback, std::function stop_callback) { @@ -88,14 +88,12 @@ void Debug::start(const std::string &command, const boost::filesystem::path &pat } //Set breakpoints - if(breakpoints) { - for(auto &breakpoint: *breakpoints) { - if(!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) { - Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+breakpoint.first.string()+":"+std::to_string(breakpoint.second)+'\n', true); - if(callback) - callback(-1); - return; - } + for(auto &breakpoint: breakpoints) { + if(!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) { + Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+breakpoint.first.string()+":"+std::to_string(breakpoint.second)+'\n', true); + if(callback) + callback(-1); + return; } } diff --git a/src/debug.h b/src/debug.h index 07fd4d2..2d4471d 100644 --- a/src/debug.h +++ b/src/debug.h @@ -39,7 +39,7 @@ public: } void start(const std::string &command, const boost::filesystem::path &path="", - std::shared_ptr > > breakpoints=nullptr, + const std::vector > &breakpoints={}, std::function callback=nullptr, std::function status_callback=nullptr, std::function stop_callback=nullptr); diff --git a/src/notebook.cc b/src/notebook.cc index 68f8614..4ecf9cc 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -355,17 +355,13 @@ boost::filesystem::path Notebook::get_current_folder() { } std::unique_ptr Notebook::get_project() { - boost::filesystem::path file_path; - if(get_current_page()!=-1) - file_path=get_current_view()->file_path; - if(get_current_page()!=-1) { if(get_current_view()->language->get_id()=="markdown") { - return std::unique_ptr(new ProjectMarkDown(file_path)); + return std::unique_ptr(new ProjectMarkDown(*this)); } } - return std::unique_ptr(new ProjectClang(file_path)); + return std::unique_ptr(new ProjectClang(*this)); } bool Notebook::save_modified_dialog(int page) { diff --git a/src/notebook.h b/src/notebook.h index 2c15ad5..5f58308 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -10,6 +10,8 @@ #include #include +class Project; //Avoiding this would lead to bloated code + class Notebook : public Gtk::Notebook { class TabLabel : public Gtk::Box { public: diff --git a/src/project.cc b/src/project.cc index 4385b61..c9d8405 100644 --- a/src/project.cc +++ b/src/project.cc @@ -3,6 +3,9 @@ #include "terminal.h" #include "filesystem.h" #include +#ifdef JUCI_ENABLE_DEBUG +#include "debug.h" +#endif std::unordered_map Project::run_arguments; std::unordered_map Project::debug_run_arguments; @@ -11,8 +14,8 @@ std::atomic Project::debugging(false); std::unique_ptr ProjectClang::get_cmake() { boost::filesystem::path path; - if(!file_path.empty()) - path=file_path.parent_path(); + if(notebook.get_current_page()!=-1) + path=notebook.get_current_view()->file_path.parent_path(); else path=Directories::get().current_path; if(path.empty()) @@ -37,15 +40,15 @@ std::pair ProjectClang::get_run_arguments() { arguments=run_arguments_it->second; if(arguments.empty()) { - auto executable=cmake->get_executable(file_path).string(); + auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); if(executable!="") { auto project_path=cmake->project_path; - auto default_build_path=CMake::get_default_build_path(project_path); - if(!default_build_path.empty()) { + auto build_path=CMake::get_default_build_path(project_path); + if(!build_path.empty()) { size_t pos=executable.find(project_path.string()); if(pos!=std::string::npos) - executable.replace(pos, project_path.string().size(), default_build_path.string()); + executable.replace(pos, project_path.string().size(), build_path.string()); } arguments=filesystem::escape_argument(executable); } @@ -87,7 +90,7 @@ void ProjectClang::compile_and_run() { arguments=run_arguments_it->second; if(arguments.empty()) { - arguments=cmake->get_executable(file_path).string(); + arguments=cmake->get_executable(notebook.get_current_page()!=-1?notebook.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) @@ -113,6 +116,271 @@ void ProjectClang::compile_and_run() { }); } +#ifdef JUCI_ENABLE_DEBUG +std::pair ProjectClang::debug_get_run_arguments() { + auto cmake=get_cmake(); + if(!cmake) + return {"", ""}; + + auto project_path=cmake->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_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + + if(executable!="") { + auto project_path=cmake->project_path; + auto build_path=CMake::get_debug_build_path(project_path); + if(!build_path.empty()) { + size_t pos=executable.find(project_path.string()); + if(pos!=std::string::npos) + executable.replace(pos, project_path.string().size(), build_path.string()); + } + arguments=filesystem::escape_argument(executable); + } + else + arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path)); + } + + return {project_path, arguments}; +} + +void ProjectClang::debug_start(std::function status_callback, + std::function stop_callback) { + auto cmake=get_cmake(); + if(!cmake) + return; + auto project_path=cmake->project_path; + + auto debug_build_path=CMake::get_debug_build_path(project_path); + if(debug_build_path.empty()) + return; + if(!CMake::create_debug_build(project_path)) + return; + + auto run_arguments_it=debug_run_arguments.find(project_path.string()); + std::string run_arguments; + if(run_arguments_it!=debug_run_arguments.end()) + run_arguments=run_arguments_it->second; + + if(run_arguments.empty()) { + run_arguments=cmake->get_executable(notebook.get_current_page()!=-1?notebook.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("Solution: either use Debug Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); + return; + } + size_t pos=run_arguments.find(project_path.string()); + if(pos!=std::string::npos) + run_arguments.replace(pos, project_path.string().size(), debug_build_path.string()); + run_arguments=filesystem::escape_argument(run_arguments); + } + + auto breakpoints=std::make_shared > >(); + for(int c=0;cproject_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); + while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint")) + breakpoints->emplace_back(view->file_path, iter.get_line()+1); + } + } + + debugging=true; + Terminal::get().print("Compiling and debugging "+run_arguments+"\n"); + Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path, status_callback, stop_callback](int exit_status){ + if(exit_status!=EXIT_SUCCESS) + debugging=false; + else { + debug_start_mutex.lock(); + Debug::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ + debugging=false; + Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); + }, status_callback, stop_callback); + debug_start_mutex.unlock(); + } + }); +} + +void ProjectClang::debug_continue() { + Debug::get().continue_debug(); +} + +void ProjectClang::debug_stop() { + if(debugging) + Debug::get().stop(); +} + +void ProjectClang::debug_kill() { + if(debugging) + Debug::get().kill(); +} + +void ProjectClang::debug_step_over() { + if(debugging) + Debug::get().step_over(); +} + +void ProjectClang::debug_step_into() { + if(debugging) + Debug::get().step_into(); +} + +void ProjectClang::debug_step_out() { + if(debugging) + Debug::get().step_out(); +} + +void ProjectClang::debug_backtrace() { + if(debugging && notebook.get_current_page()!=-1) { + auto backtrace=Debug::get().get_backtrace(); + + auto view=notebook.get_current_view(); + auto iter=view->get_iter_for_dialog(); + view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); + auto rows=std::make_shared >(); + if(backtrace.size()==0) + return; + + for(auto &frame: backtrace) { + std::string row=""+frame.module_filename+""; + + //Shorten frame.function_name if it is too long + if(frame.function_name.size()>120) { + frame.function_name=frame.function_name.substr(0, 58)+"...."+frame.function_name.substr(frame.function_name.size()-58); + } + if(frame.file_path.empty()) + row+=" - "+Glib::Markup::escape_text(frame.function_name); + else { + auto file_path=boost::filesystem::path(frame.file_path).filename().string(); + row+=":"+Glib::Markup::escape_text(file_path)+":"+std::to_string(frame.line_nr)+" - "+Glib::Markup::escape_text(frame.function_name); + } + (*rows)[row]=frame; + view->selection_dialog->add_row(row); + } + + view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + auto frame=rows->at(selected); + if(!frame.file_path.empty()) { + notebook.open(frame.file_path); + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + + Debug::get().select_frame(frame.index); + + view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(frame.line_nr-1, frame.line_index-1)); + + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); + if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } + } + }; + view->selection_dialog->show(); + } +} + +void ProjectClang::debug_show_variables() { + if(debugging && notebook.get_current_page()!=-1) { + auto variables=Debug::get().get_variables(); + + auto view=notebook.get_current_view(); + auto iter=view->get_iter_for_dialog(); + view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); + auto rows=std::make_shared >(); + if(variables.size()==0) + return; + + for(auto &variable: variables) { + std::string row="#"+std::to_string(variable.thread_index_id)+":#"+std::to_string(variable.frame_index)+":"+variable.file_path.filename().string()+":"+std::to_string(variable.line_nr)+" - "+Glib::Markup::escape_text(variable.name)+""; + + (*rows)[row]=variable; + view->selection_dialog->add_row(row); + } + + view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + auto variable=rows->at(selected); + if(!variable.file_path.empty()) { + notebook.open(variable.file_path); + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + + Debug::get().select_frame(variable.frame_index, variable.thread_index_id); + + view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(variable.line_nr-1, variable.line_index-1)); + + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); + if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } + } + }; + + view->selection_dialog->on_hide=[this]() { + debug_variable_tooltips.hide(); + debug_variable_tooltips.clear(); + }; + + view->selection_dialog->on_changed=[this, rows, iter](const std::string &selected) { + if(selected.empty()) { + debug_variable_tooltips.hide(); + return; + } + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + debug_variable_tooltips.clear(); + auto create_tooltip_buffer=[this, rows, view, selected]() { + auto variable=rows->at(selected); + auto tooltip_buffer=Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()); + + Glib::ustring value=variable.value; + if(!value.empty()) { + Glib::ustring::iterator iter; + while(!value.validate(iter)) { + auto next_char_iter=iter; + next_char_iter++; + value.replace(iter, next_char_iter, "?"); + } + tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note"); + } + + return tooltip_buffer; + }; + + debug_variable_tooltips.emplace_back(create_tooltip_buffer, *view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter)); + + debug_variable_tooltips.show(true); + } + }; + + view->selection_dialog->show(); + } +} + +void ProjectClang::debug_run_command(const std::string &command) { + if(debugging) { + auto command_return=Debug::get().run_command(command); + Terminal::get().async_print(command_return.first); + Terminal::get().async_print(command_return.second, true); + } +} + +void ProjectClang::debug_delete() { + debug_start_mutex.lock(); + Debug::get().delete_debug(); + debug_start_mutex.unlock(); +} +#endif + ProjectMarkDown::~ProjectMarkDown() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); @@ -127,7 +395,7 @@ void ProjectMarkDown::compile_and_run() { } std::stringstream stdin_stream, stdout_stream; - auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "markdown "+file_path.string(), this->file_path.parent_path()); + auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "markdown "+notebook.get_current_view()->file_path.string()); if(exit_status==0) { boost::system::error_code ec; auto temp_path=boost::filesystem::temp_directory_path(ec); diff --git a/src/project.h b/src/project.h index eb74f85..9cbb183 100644 --- a/src/project.h +++ b/src/project.h @@ -1,17 +1,22 @@ #ifndef JUCI_PROJECT_H_ #define JUCI_PROJECT_H_ +#include "notebook.h" //Avoiding this circular include would lead to bloated code #include "cmake.h" #include #include "directories.h" #include +#include +#include "tooltips.h" + +class Notebook; //Avoiding this circular include would lead to bloated code class Project { public: - Project(const boost::filesystem::path &file_path) : file_path(file_path) {} + Project(Notebook ¬ebook) : notebook(notebook) {} virtual ~Project() {} - boost::filesystem::path file_path; + Notebook ¬ebook; static std::unordered_map run_arguments; static std::unordered_map debug_run_arguments; @@ -23,7 +28,10 @@ public: virtual void compile_and_run() {} virtual std::pair debug_get_run_arguments() {return {"", ""};} - virtual void debug_start_continue() {} + Tooltips debug_variable_tooltips; + virtual void debug_start(std::function status_callback, + std::function stop_callback) {} + virtual void debug_continue() {} virtual void debug_stop() {} virtual void debug_kill() {} virtual void debug_step_over() {} @@ -31,25 +39,39 @@ public: virtual void debug_step_out() {} virtual void debug_backtrace() {} virtual void debug_show_variables() {} - virtual void debug_run_command() {} - virtual void debug_toggle_breakpoint() {} - virtual void debug_goto_stop() {} + virtual void debug_run_command(const std::string &command) {} + virtual void debug_delete() {} }; class ProjectClang : public Project { public: - ProjectClang(const boost::filesystem::path &file_path) : Project(file_path) {} + ProjectClang(Notebook ¬ebook) : Project(notebook) {} std::unique_ptr get_cmake(); std::pair get_run_arguments() override; void compile() override; void compile_and_run() override; + + std::pair debug_get_run_arguments() override; + std::mutex debug_start_mutex; + void debug_start(std::function status_callback, + std::function stop_callback) override; + void debug_continue() override; + void debug_stop() override; + void debug_kill() override; + void debug_step_over() override; + void debug_step_into() override; + void debug_step_out() override; + void debug_backtrace() override; + void debug_show_variables() override; + void debug_run_command(const std::string &command) override; + void debug_delete() override; }; class ProjectMarkDown : public Project { public: - ProjectMarkDown(const boost::filesystem::path &file_path) : Project(file_path) {} + ProjectMarkDown(Notebook ¬ebook) : Project(notebook) {} ~ProjectMarkDown(); boost::filesystem::path last_temp_path; diff --git a/src/window.cc b/src/window.cc index 108ea41..8495edb 100644 --- a/src/window.cc +++ b/src/window.cc @@ -24,7 +24,7 @@ namespace sigc { #endif } -Window::Window() : compiling(false), debugging(false) { +Window::Window() { JDEBUG("start"); set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK); @@ -203,22 +203,6 @@ Window::Window() : compiling(false), debugging(false) { JDEBUG("end"); } // Window constructor -std::unique_ptr Window::get_cmake() { - boost::filesystem::path path; - if(notebook.get_current_page()!=-1) - path=notebook.get_current_view()->file_path.parent_path(); - else - path=Directories::get().current_path; - if(path.empty()) - return nullptr; - auto cmake=std::unique_ptr(new CMake(path)); - if(cmake->project_path.empty()) - return nullptr; - if(!CMake::create_default_build(cmake->project_path)) - return nullptr; - return cmake; -} - void Window::configure() { Config::get().load(); auto style_context = Gtk::StyleContext::create(); @@ -672,32 +656,10 @@ void Window::set_menu_actions() { #ifdef JUCI_ENABLE_DEBUG menu.add_action("debug_set_run_arguments", [this]() { - auto cmake=get_cmake(); - if(!cmake) + project=notebook.get_project(); + auto run_arguments=std::make_shared >(project->debug_get_run_arguments()); + if(run_arguments->second.empty()) return; - - auto project_path=std::make_shared(cmake->project_path); - auto run_arguments_it=debug_run_arguments.find(project_path->string()); - std::string run_arguments; - if(run_arguments_it!=debug_run_arguments.end()) - run_arguments=run_arguments_it->second; - - if(run_arguments.empty()) { - auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); - - if(executable!="") { - auto project_path=cmake->project_path; - auto debug_build_path=CMake::get_debug_build_path(project_path); - if(!debug_build_path.empty()) { - size_t pos=executable.find(project_path.string()); - if(pos!=std::string::npos) - executable.replace(pos, project_path.string().size(), debug_build_path.string()); - } - run_arguments=filesystem::escape_argument(executable); - } - else - run_arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path)); - } entry_box.clear(); entry_box.labels.emplace_back(); @@ -706,258 +668,76 @@ void Window::set_menu_actions() { label_it->set_text("Set empty to let juCi++ deduce executable"); }; label_it->update(0, ""); - entry_box.entries.emplace_back(run_arguments, [this, project_path](const std::string& content){ - debug_run_arguments[project_path->string()]=content; + entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ + Project::debug_run_arguments[run_arguments->first]=content; entry_box.hide(); }, 50); auto entry_it=entry_box.entries.begin(); - entry_it->set_placeholder_text("Project: Set Run Arguments"); - entry_box.buttons.emplace_back("Project: set run arguments", [this, entry_it](){ + entry_it->set_placeholder_text("Debug: Set Run Arguments"); + entry_box.buttons.emplace_back("Debug: set run arguments", [this, entry_it](){ entry_it->activate(); }); entry_box.show(); }); menu.add_action("debug_start_continue", [this](){ - if(debugging) { - Debug::get().continue_debug(); + if(Project::debugging) { + project->debug_continue(); return; } if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - auto cmake=get_cmake(); - if(!cmake) - return; - auto project_path=cmake->project_path; - - auto debug_build_path=CMake::get_debug_build_path(project_path); - if(debug_build_path.empty()) - return; - if(!CMake::create_debug_build(project_path)) - return; - - auto run_arguments_it=debug_run_arguments.find(project_path.string()); - std::string run_arguments; - if(run_arguments_it!=debug_run_arguments.end()) - run_arguments=run_arguments_it->second; - - std::string command; - if(!run_arguments.empty()) { - command=run_arguments; - } - else { - command=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); - if(command.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("Solution: either use Debug Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); - return; - } - size_t pos=command.find(project_path.string()); - if(pos!=std::string::npos) - command.replace(pos, project_path.string().size(), debug_build_path.string()); - command=filesystem::escape_argument(command); - } - - auto breakpoints=std::make_shared > >(); - for(int c=0;cproject_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); - while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint")) - breakpoints->emplace_back(view->file_path, iter.get_line()+1); - } - } + project=notebook.get_project(); - debugging=true; - Terminal::get().print("Compiling and debugging "+command+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, command, debug_build_path](int exit_status){ - if(exit_status!=EXIT_SUCCESS) - debugging=false; - else { - debug_start_mutex.lock(); - Debug::get().start(command, debug_build_path, breakpoints, [this, command](int exit_status){ - debugging=false; - Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); - }, [this](const std::string &status) { - debug_status_mutex.lock(); - debug_status=status; - debug_status_mutex.unlock(); - debug_update_status(); - }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { - debug_stop_mutex.lock(); - debug_stop.first=file_path; - debug_stop.second.first=line_nr; - debug_stop.second.second=line_index; - debug_stop_mutex.unlock(); - debug_update_stop(); - //Remove debug stop source mark - }); - debug_start_mutex.unlock(); - } + project->debug_start([this](const std::string &status) { + debug_status_mutex.lock(); + debug_status=status; + debug_status_mutex.unlock(); + debug_update_status(); + }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { + debug_stop_mutex.lock(); + debug_stop.first=file_path; + debug_stop.second.first=line_nr; + debug_stop.second.second=line_index; + debug_stop_mutex.unlock(); + debug_update_stop(); }); }); menu.add_action("debug_stop", [this]() { - if(debugging) { - Debug::get().stop(); - } + if(project) + project->debug_stop(); }); menu.add_action("debug_kill", [this]() { - if(debugging) { - Debug::get().kill(); - } + if(project) + project->debug_kill(); }); menu.add_action("debug_step_over", [this]() { - if(debugging) - Debug::get().step_over(); + if(project) + project->debug_step_over(); }); menu.add_action("debug_step_into", [this]() { - if(debugging) - Debug::get().step_into(); + if(project) + project->debug_step_into(); }); menu.add_action("debug_step_out", [this]() { - if(debugging) - Debug::get().step_out(); + if(project) + project->debug_step_out(); }); menu.add_action("debug_backtrace", [this]() { - if(debugging && notebook.get_current_page()!=-1) { - auto backtrace=Debug::get().get_backtrace(); - - auto view=notebook.get_current_view(); - auto iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); - if(backtrace.size()==0) - return; - - for(auto &frame: backtrace) { - std::string row=""+frame.module_filename+""; - - //Shorten frame.function_name if it is too long - if(frame.function_name.size()>120) { - frame.function_name=frame.function_name.substr(0, 58)+"...."+frame.function_name.substr(frame.function_name.size()-58); - } - if(frame.file_path.empty()) - row+=" - "+Glib::Markup::escape_text(frame.function_name); - else { - auto file_path=boost::filesystem::path(frame.file_path).filename().string(); - row+=":"+Glib::Markup::escape_text(file_path)+":"+std::to_string(frame.line_nr)+" - "+Glib::Markup::escape_text(frame.function_name); - } - (*rows)[row]=frame; - view->selection_dialog->add_row(row); - } - - view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { - auto frame=rows->at(selected); - if(!frame.file_path.empty()) { - notebook.open(frame.file_path); - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - - Debug::get().select_frame(frame.index); - - view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(frame.line_nr-1, frame.line_index-1)); - - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); - } - } - }; - view->selection_dialog->show(); - } + if(project) + project->debug_backtrace(); }); menu.add_action("debug_show_variables", [this]() { - if(debugging && notebook.get_current_page()!=-1) { - auto variables=Debug::get().get_variables(); - - auto view=notebook.get_current_view(); - auto iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); - if(variables.size()==0) - return; - - for(auto &variable: variables) { - std::string row="#"+std::to_string(variable.thread_index_id)+":#"+std::to_string(variable.frame_index)+":"+variable.file_path.filename().string()+":"+std::to_string(variable.line_nr)+" - "+Glib::Markup::escape_text(variable.name)+""; - - (*rows)[row]=variable; - view->selection_dialog->add_row(row); - } - - view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { - auto variable=rows->at(selected); - if(!variable.file_path.empty()) { - notebook.open(variable.file_path); - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - - Debug::get().select_frame(variable.frame_index, variable.thread_index_id); - - view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(variable.line_nr-1, variable.line_index-1)); - - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); - } - } - }; - - view->selection_dialog->on_hide=[this]() { - debug_variable_tooltips.hide(); - debug_variable_tooltips.clear(); - }; - - view->selection_dialog->on_changed=[this, rows, iter](const std::string &selected) { - if(selected.empty()) { - debug_variable_tooltips.hide(); - return; - } - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - debug_variable_tooltips.clear(); - auto create_tooltip_buffer=[this, rows, view, selected]() { - auto variable=rows->at(selected); - auto tooltip_buffer=Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()); - - Glib::ustring value=variable.value; - if(!value.empty()) { - Glib::ustring::iterator iter; - while(!value.validate(iter)) { - auto next_char_iter=iter; - next_char_iter++; - value.replace(iter, next_char_iter, "?"); - } - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note"); - } - - return tooltip_buffer; - }; - - debug_variable_tooltips.emplace_back(create_tooltip_buffer, *view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter)); - - debug_variable_tooltips.show(true); - } - }; - - view->selection_dialog->show(); - } + if(project) + project->debug_show_variables(); }); menu.add_action("debug_run_command", [this]() { entry_box.clear(); entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){ if(content!="") { - if(debugging) { - auto command_return=Debug::get().run_command(content); - Terminal::get().async_print(command_return.first); - Terminal::get().async_print(command_return.second, true); - } + if(project) + project->debug_run_command(content); last_run_debug_command=content; } entry_box.hide(); @@ -993,7 +773,7 @@ void Window::set_menu_actions() { } }); menu.add_action("debug_goto_stop", [this](){ - if(debugging) { + if(project && project->debugging) { debug_stop_mutex.lock(); auto debug_stop_copy=debug_stop; debug_stop_mutex.unlock(); @@ -1119,9 +899,8 @@ bool Window::on_delete_event(GdkEventAny *event) { } Terminal::get().kill_async_processes(); #ifdef JUCI_ENABLE_DEBUG - debug_start_mutex.lock(); - Debug::get().delete_debug(); - debug_start_mutex.unlock(); + if(project) + project->debug_delete(); #endif return false; } diff --git a/src/window.h b/src/window.h index a23ad39..b0a5991 100644 --- a/src/window.h +++ b/src/window.h @@ -5,7 +5,6 @@ #include "entrybox.h" #include "notebook.h" #include "cmake.h" -#include "tooltips.h" #include "project.h" #include @@ -37,12 +36,8 @@ private: std::unique_ptr project; - std::atomic compiling; - - std::atomic debugging; Gtk::Label debug_status_label; - std::mutex debug_start_mutex; std::pair > debug_stop; boost::filesystem::path debug_last_stop_file_path; std::mutex debug_stop_mutex; @@ -50,12 +45,6 @@ private: std::string debug_status; std::mutex debug_status_mutex; Glib::Dispatcher debug_update_status; - - Tooltips debug_variable_tooltips; - - std::unique_ptr get_cmake(); - std::unordered_map project_run_arguments; - std::unordered_map debug_run_arguments; void configure(); void set_menu_actions(); From 86927153f9dd91ec0c5ed8603da5e1168a467bbf Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 9 Feb 2016 13:27:14 +0100 Subject: [PATCH 04/41] Added python and javascript projects --- src/notebook.cc | 9 ++++++--- src/project.cc | 20 ++++++++++++++++++-- src/project.h | 20 +++++++++++++++++--- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 4ecf9cc..3cb89cf 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -356,9 +356,12 @@ boost::filesystem::path Notebook::get_current_folder() { std::unique_ptr Notebook::get_project() { if(get_current_page()!=-1) { - if(get_current_view()->language->get_id()=="markdown") { - return std::unique_ptr(new ProjectMarkDown(*this)); - } + if(get_current_view()->language->get_id()=="markdown") + return std::unique_ptr(new ProjectMarkdown(*this)); + if(get_current_view()->language->get_id()=="python") + return std::unique_ptr(new ProjectPython(*this)); + if(get_current_view()->language->get_id()=="js") + return std::unique_ptr(new ProjectJavaScript(*this)); } return std::unique_ptr(new ProjectClang(*this)); diff --git a/src/project.cc b/src/project.cc index c9d8405..e3cf3ad 100644 --- a/src/project.cc +++ b/src/project.cc @@ -381,14 +381,14 @@ void ProjectClang::debug_delete() { } #endif -ProjectMarkDown::~ProjectMarkDown() { +ProjectMarkdown::~ProjectMarkdown() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); last_temp_path=boost::filesystem::path(); } } -void ProjectMarkDown::compile_and_run() { +void ProjectMarkdown::compile_and_run() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); last_temp_path=boost::filesystem::path(); @@ -412,3 +412,19 @@ void ProjectMarkDown::compile_and_run() { } } } + +void ProjectPython::compile_and_run() { + auto command="python "+notebook.get_current_view()->file_path.string(); + Terminal::get().print("Running "+command+"\n"); + Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) { + Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); + }); +} + +void ProjectJavaScript::compile_and_run() { + auto command="node "+notebook.get_current_view()->file_path.string(); + Terminal::get().print("Running "+command+"\n"); + Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) { + Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); + }); +} diff --git a/src/project.h b/src/project.h index 9cbb183..4e735ae 100644 --- a/src/project.h +++ b/src/project.h @@ -69,13 +69,27 @@ public: void debug_delete() override; }; -class ProjectMarkDown : public Project { +class ProjectMarkdown : public Project { public: - ProjectMarkDown(Notebook ¬ebook) : Project(notebook) {} - ~ProjectMarkDown(); + ProjectMarkdown(Notebook ¬ebook) : Project(notebook) {} + ~ProjectMarkdown(); boost::filesystem::path last_temp_path; void compile_and_run() override; }; +class ProjectPython : public Project { +public: + ProjectPython(Notebook ¬ebook) : Project(notebook) {} + + void compile_and_run() override; +}; + +class ProjectJavaScript : public Project { +public: + ProjectJavaScript(Notebook ¬ebook) : Project(notebook) {} + + void compile_and_run() override; +}; + #endif // JUCI_PROJECT_H_ From ad14337aeaf7b6691a16c53ce6cb780f3e91d1c9 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 9 Feb 2016 14:02:57 +0100 Subject: [PATCH 05/41] Fixed builds without lldb, added HTML project, and fixed opening web-pages on non-OS X systems --- src/notebook.cc | 2 ++ src/project.cc | 21 ++++++++++++++++++++- src/project.h | 11 ++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 3cb89cf..19c2822 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -362,6 +362,8 @@ std::unique_ptr Notebook::get_project() { return std::unique_ptr(new ProjectPython(*this)); if(get_current_view()->language->get_id()=="js") return std::unique_ptr(new ProjectJavaScript(*this)); + if(get_current_view()->language->get_id()=="html") + return std::unique_ptr(new ProjectHTML(*this)); } return std::unique_ptr(new ProjectClang(*this)); diff --git a/src/project.cc b/src/project.cc index e3cf3ad..f7d5358 100644 --- a/src/project.cc +++ b/src/project.cc @@ -407,7 +407,15 @@ void ProjectMarkdown::compile_and_run() { std::ofstream file_stream(temp_path.string(), std::fstream::binary); file_stream << stdout_stream.rdbuf(); file_stream.close(); - Terminal::get().async_process("open "+temp_path.string()); + + auto uri=temp_path.string(); +#ifdef __APPLE__ + Terminal::get().process("open \""+uri+"\""); +#else + GError* error=NULL; + gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error); + g_clear_error(&error); +#endif } } } @@ -428,3 +436,14 @@ void ProjectJavaScript::compile_and_run() { Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); }); } + +void ProjectHTML::compile_and_run() { + auto uri=notebook.get_current_view()->file_path.string(); +#ifdef __APPLE__ + Terminal::get().process("open \""+uri+"\""); +#else + GError* error=NULL; + gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error); + g_clear_error(&error); +#endif +} diff --git a/src/project.h b/src/project.h index 4e735ae..a69960b 100644 --- a/src/project.h +++ b/src/project.h @@ -53,8 +53,9 @@ public: void compile() override; void compile_and_run() override; - std::pair debug_get_run_arguments() override; std::mutex debug_start_mutex; +#ifdef JUCI_ENABLE_DEBUG + std::pair debug_get_run_arguments() override; void debug_start(std::function status_callback, std::function stop_callback) override; void debug_continue() override; @@ -67,6 +68,7 @@ public: void debug_show_variables() override; void debug_run_command(const std::string &command) override; void debug_delete() override; +#endif }; class ProjectMarkdown : public Project { @@ -92,4 +94,11 @@ public: void compile_and_run() override; }; +class ProjectHTML : public Project { +public: + ProjectHTML(Notebook ¬ebook) : Project(notebook) {} + + void compile_and_run() override; +}; + #endif // JUCI_PROJECT_H_ From 2ef81115bddbc35c1f2ec375b5d7602621b31295 Mon Sep 17 00:00:00 2001 From: Ole Christian Eidheim Date: Tue, 9 Feb 2016 14:19:32 +0100 Subject: [PATCH 06/41] Fixed show web-files on Linux --- src/project.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/project.cc b/src/project.cc index f7d5358..3f595c2 100644 --- a/src/project.cc +++ b/src/project.cc @@ -413,7 +413,7 @@ void ProjectMarkdown::compile_and_run() { Terminal::get().process("open \""+uri+"\""); #else GError* error=NULL; - gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error); + gtk_show_uri(NULL, ("file://"+uri).c_str(), GDK_CURRENT_TIME, &error); g_clear_error(&error); #endif } @@ -443,7 +443,7 @@ void ProjectHTML::compile_and_run() { Terminal::get().process("open \""+uri+"\""); #else GError* error=NULL; - gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error); + gtk_show_uri(NULL, ("file://"+uri).c_str(), GDK_CURRENT_TIME, &error); g_clear_error(&error); #endif } From 9e3b1f53c0f691dddd722ea4df67155c5c44d192 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 9 Feb 2016 14:55:14 +0100 Subject: [PATCH 07/41] Fix for MSYS2 when opening web-files --- src/project.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/project.cc b/src/project.cc index 3f595c2..61310bd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -412,8 +412,11 @@ void ProjectMarkdown::compile_and_run() { #ifdef __APPLE__ Terminal::get().process("open \""+uri+"\""); #else +#ifdef __linux + uri="file://"+uri; +#endif GError* error=NULL; - gtk_show_uri(NULL, ("file://"+uri).c_str(), GDK_CURRENT_TIME, &error); + gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error); g_clear_error(&error); #endif } @@ -442,8 +445,11 @@ void ProjectHTML::compile_and_run() { #ifdef __APPLE__ Terminal::get().process("open \""+uri+"\""); #else +#ifdef __linux + uri="file://"+uri; +#endif GError* error=NULL; - gtk_show_uri(NULL, ("file://"+uri).c_str(), GDK_CURRENT_TIME, &error); + gtk_show_uri(NULL, uri.c_str(), GDK_CURRENT_TIME, &error); g_clear_error(&error); #endif } From da0dde1d6fdf06015a140368679c824fac6c87a3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 10 Feb 2016 08:46:01 +0100 Subject: [PATCH 08/41] Slight cleanup of project --- src/notebook.cc | 15 --------------- src/notebook.h | 4 ---- src/project.h | 4 +--- src/window.cc | 26 +++++++++++++++++++++----- src/window.h | 2 ++ 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 19c2822..bcd1780 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -354,21 +354,6 @@ boost::filesystem::path Notebook::get_current_folder() { return current_path; } -std::unique_ptr Notebook::get_project() { - if(get_current_page()!=-1) { - if(get_current_view()->language->get_id()=="markdown") - return std::unique_ptr(new ProjectMarkdown(*this)); - if(get_current_view()->language->get_id()=="python") - return std::unique_ptr(new ProjectPython(*this)); - if(get_current_view()->language->get_id()=="js") - return std::unique_ptr(new ProjectJavaScript(*this)); - if(get_current_view()->language->get_id()=="html") - return std::unique_ptr(new ProjectHTML(*this)); - } - - return std::unique_ptr(new ProjectClang(*this)); -} - bool Notebook::save_modified_dialog(int page) { Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); dialog.set_default_response(Gtk::RESPONSE_YES); diff --git a/src/notebook.h b/src/notebook.h index 5f58308..1b6f2d8 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -5,13 +5,10 @@ #include "gtkmm.h" #include "source.h" #include "source_clang.h" -#include "project.h" #include #include #include -class Project; //Avoiding this would lead to bloated code - class Notebook : public Gtk::Notebook { class TabLabel : public Gtk::Box { public: @@ -33,7 +30,6 @@ public: void save_project_files(); void configure(int view_nr); boost::filesystem::path get_current_folder(); - std::unique_ptr get_project(); Gtk::Label info; Gtk::Label status; diff --git a/src/project.h b/src/project.h index a69960b..c6eded8 100644 --- a/src/project.h +++ b/src/project.h @@ -1,7 +1,7 @@ #ifndef JUCI_PROJECT_H_ #define JUCI_PROJECT_H_ -#include "notebook.h" //Avoiding this circular include would lead to bloated code +#include "notebook.h" #include "cmake.h" #include #include "directories.h" @@ -9,8 +9,6 @@ #include #include "tooltips.h" -class Notebook; //Avoiding this circular include would lead to bloated code - class Project { public: Project(Notebook ¬ebook) : notebook(notebook) {} diff --git a/src/window.cc b/src/window.cc index 8495edb..1da6258 100644 --- a/src/window.cc +++ b/src/window.cc @@ -575,7 +575,7 @@ void Window::set_menu_actions() { }); menu.add_action("project_set_run_arguments", [this]() { - project=notebook.get_project(); + project=get_project(); auto run_arguments=std::make_shared >(project->get_run_arguments()); if(run_arguments->second.empty()) return; @@ -605,7 +605,7 @@ void Window::set_menu_actions() { if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project=notebook.get_project(); + project=get_project(); project->compile_and_run(); }); menu.add_action("compile", [this]() { @@ -615,7 +615,7 @@ void Window::set_menu_actions() { if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project=notebook.get_project(); + project=get_project(); project->compile(); }); @@ -656,7 +656,7 @@ void Window::set_menu_actions() { #ifdef JUCI_ENABLE_DEBUG menu.add_action("debug_set_run_arguments", [this]() { - project=notebook.get_project(); + project=get_project(); auto run_arguments=std::make_shared >(project->debug_get_run_arguments()); if(run_arguments->second.empty()) return; @@ -688,7 +688,7 @@ void Window::set_menu_actions() { if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project=notebook.get_project(); + project=get_project(); project->debug_start([this](const std::string &status) { debug_status_mutex.lock(); @@ -1126,3 +1126,19 @@ void Window::rename_token_entry() { } } } + +std::unique_ptr Window::get_project() { + if(notebook.get_current_page()!=-1) { + auto language_id=notebook.get_current_view()->language->get_id(); + if(language_id=="markdown") + return std::unique_ptr(new ProjectMarkdown(notebook)); + if(language_id=="python") + return std::unique_ptr(new ProjectPython(notebook)); + if(language_id=="js") + return std::unique_ptr(new ProjectJavaScript(notebook)); + if(language_id=="html") + return std::unique_ptr(new ProjectHTML(notebook)); + } + + return std::unique_ptr(new ProjectClang(notebook)); +} diff --git a/src/window.h b/src/window.h index b0a5991..4fbfce5 100644 --- a/src/window.h +++ b/src/window.h @@ -60,6 +60,8 @@ private: bool case_sensitive_search=true; bool regex_search=false; bool search_entry_shown=false; + + std::unique_ptr get_project(); }; #endif // JUCI_WINDOW_H From e9cc73471d76b657771f3da33dc3b783eb05e7e3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 11 Feb 2016 16:59:29 +0100 Subject: [PATCH 09/41] More project cleanup, getting there, soon done --- src/dialogs.cc | 3 +- src/juci.cc | 3 +- src/notebook.h | 9 +- src/project.cc | 230 ++++++++++++++++++++++++++++++++++++++----------- src/project.h | 179 +++++++++++++++++++++----------------- src/window.cc | 199 ++++++++---------------------------------- src/window.h | 19 +--- 7 files changed, 333 insertions(+), 309 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index a62c9ac..32d234b 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,5 +1,6 @@ #include "dialogs.h" #include "window.h" +#include "notebook.h" #include namespace sigc { @@ -34,7 +35,7 @@ std::string Dialog::gtk_dialog(const std::string &title, dialog.set_transient_for(Window::get()); - auto current_path=Window::get().notebook.get_current_folder(); + auto current_path=Notebook::get().get_current_folder(); boost::system::error_code ec; if(current_path.empty()) current_path=boost::filesystem::current_path(ec); diff --git a/src/juci.cc b/src/juci.cc index 3c52331..db28c40 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -1,5 +1,6 @@ #include "juci.h" #include "window.h" +#include "notebook.h" #include "directories.h" #include "menu.h" #include "config.h" @@ -68,7 +69,7 @@ void Application::on_activate() { } for(auto &file: files) - Window::get().notebook.open(file); + Notebook::get().open(file); for(auto &error: errors) Terminal::get().print(error, true); diff --git a/src/notebook.h b/src/notebook.h index 1b6f2d8..17dde63 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -16,8 +16,15 @@ class Notebook : public Gtk::Notebook { Gtk::Label label; Gtk::Button button; }; -public: + +private: Notebook(); +public: + static Notebook &get() { + static Notebook singleton; + return singleton; + } + Source::View* get_view(int page); size_t get_index(int page); int size(); diff --git a/src/project.cc b/src/project.cc index 61310bd..83389e3 100644 --- a/src/project.cc +++ b/src/project.cc @@ -3,16 +3,98 @@ #include "terminal.h" #include "filesystem.h" #include +#include "menu.h" #ifdef JUCI_ENABLE_DEBUG #include "debug.h" #endif -std::unordered_map Project::run_arguments; -std::unordered_map Project::debug_run_arguments; -std::atomic Project::compiling(false); -std::atomic Project::debugging(false); +Project::Project() : notebook(Notebook::get()), compiling(false), debugging(false) { + debug_update_stop.connect([this](){ + debug_stop_mutex.lock(); + for(int c=0;cfile_path==debug_last_stop_file_path) { + view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop"); + break; + } + } + //Add debug stop source mark + for(int c=0;cfile_path==debug_stop.first) { + if(debug_stop.second.first-1get_buffer()->get_line_count()) { + view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(debug_stop.second.first-1)); + debug_last_stop_file_path=debug_stop.first; + } + break; + } + } + if(notebook.get_current_page()!=-1) + notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_insert()->get_iter()); + debug_stop_mutex.unlock(); + }); + +#ifdef JUCI_ENABLE_DEBUG + auto &menu=Menu::get(); + menu.actions["debug_stop"]->set_enabled(false); + menu.actions["debug_kill"]->set_enabled(false); + menu.actions["debug_step_over"]->set_enabled(false); + menu.actions["debug_step_into"]->set_enabled(false); + menu.actions["debug_step_out"]->set_enabled(false); + menu.actions["debug_backtrace"]->set_enabled(false); + menu.actions["debug_show_variables"]->set_enabled(false); + menu.actions["debug_run_command"]->set_enabled(false); + menu.actions["debug_goto_stop"]->set_enabled(false); +#endif + debug_update_status.connect([this](){ + debug_status_mutex.lock(); + if(debug_status.empty()) { + debug_status_label.set_text(""); + auto &menu=Menu::get(); + menu.actions["debug_stop"]->set_enabled(false); + menu.actions["debug_kill"]->set_enabled(false); + menu.actions["debug_step_over"]->set_enabled(false); + menu.actions["debug_step_into"]->set_enabled(false); + menu.actions["debug_step_out"]->set_enabled(false); + menu.actions["debug_backtrace"]->set_enabled(false); + menu.actions["debug_show_variables"]->set_enabled(false); + menu.actions["debug_run_command"]->set_enabled(false); + menu.actions["debug_goto_stop"]->set_enabled(false); + } + else { + debug_status_label.set_text("debug: "+debug_status); + auto &menu=Menu::get(); + menu.actions["debug_stop"]->set_enabled(); + menu.actions["debug_kill"]->set_enabled(); + menu.actions["debug_step_over"]->set_enabled(); + menu.actions["debug_step_into"]->set_enabled(); + menu.actions["debug_step_out"]->set_enabled(); + menu.actions["debug_backtrace"]->set_enabled(); + menu.actions["debug_show_variables"]->set_enabled(); + menu.actions["debug_run_command"]->set_enabled(); + menu.actions["debug_goto_stop"]->set_enabled(); + } + debug_status_mutex.unlock(); + }); +} -std::unique_ptr ProjectClang::get_cmake() { +std::unique_ptr Project::get_language() { + if(notebook.get_current_page()!=-1) { + auto language_id=notebook.get_current_view()->language->get_id(); + if(language_id=="markdown") + return std::unique_ptr(new Project::Markdown()); + if(language_id=="python") + return std::unique_ptr(new Project::Python()); + if(language_id=="js") + return std::unique_ptr(new Project::JavaScript()); + if(language_id=="html") + return std::unique_ptr(new Project::HTML()); + } + + return std::unique_ptr(new Project::Clang()); +} + +std::unique_ptr Project::Clang::get_cmake() { boost::filesystem::path path; if(notebook.get_current_page()!=-1) path=notebook.get_current_view()->file_path.parent_path(); @@ -28,15 +110,15 @@ std::unique_ptr ProjectClang::get_cmake() { return cmake; } -std::pair ProjectClang::get_run_arguments() { +std::pair Project::Clang::get_run_arguments() { auto cmake=get_cmake(); if(!cmake) return {"", ""}; auto project_path=cmake->project_path.string(); - auto run_arguments_it=run_arguments.find(project_path); + auto run_arguments_it=Project::get().run_arguments.find(project_path); std::string arguments; - if(run_arguments_it!=run_arguments.end()) + if(run_arguments_it!=Project::get().run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { @@ -59,7 +141,7 @@ std::pair ProjectClang::get_run_arguments() { return {project_path, arguments}; } -void ProjectClang::compile() { +void Project::Clang::compile() { auto cmake=get_cmake(); if(!cmake) return; @@ -67,14 +149,14 @@ void ProjectClang::compile() { auto default_build_path=CMake::get_default_build_path(cmake->project_path); if(default_build_path.empty()) return; - compiling=true; + Project::get().compiling=true; Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status) { - compiling=false; + Project::get().compiling=false; }); } -void ProjectClang::compile_and_run() { +void Project::Clang::compile_and_run() { auto cmake=get_cmake(); if(!cmake) return; @@ -84,9 +166,9 @@ void ProjectClang::compile_and_run() { if(default_build_path.empty()) return; - auto run_arguments_it=run_arguments.find(project_path.string()); + auto run_arguments_it=Project::get().run_arguments.find(project_path.string()); std::string arguments; - if(run_arguments_it!=run_arguments.end()) + if(run_arguments_it!=Project::get().run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { @@ -104,10 +186,10 @@ void ProjectClang::compile_and_run() { arguments=filesystem::escape_argument(arguments); } - compiling=true; + Project::get().compiling=true; Terminal::get().print("Compiling and running "+arguments+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){ - compiling=false; + Project::get().compiling=false; if(exit_status==EXIT_SUCCESS) { Terminal::get().async_process(arguments, default_build_path, [this, arguments](int exit_status){ Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n'); @@ -117,15 +199,15 @@ void ProjectClang::compile_and_run() { } #ifdef JUCI_ENABLE_DEBUG -std::pair ProjectClang::debug_get_run_arguments() { +std::pair Project::Clang::debug_get_run_arguments() { auto cmake=get_cmake(); if(!cmake) return {"", ""}; auto project_path=cmake->project_path.string(); - auto run_arguments_it=debug_run_arguments.find(project_path); + auto run_arguments_it=Project::get().debug_run_arguments.find(project_path); std::string arguments; - if(run_arguments_it!=debug_run_arguments.end()) + if(run_arguments_it!=Project::get().debug_run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { @@ -148,8 +230,7 @@ std::pair ProjectClang::debug_get_run_arguments() { return {project_path, arguments}; } -void ProjectClang::debug_start(std::function status_callback, - std::function stop_callback) { +void Project::Clang::debug_start() { auto cmake=get_cmake(); if(!cmake) return; @@ -161,9 +242,9 @@ void ProjectClang::debug_start(std::function st if(!CMake::create_debug_build(project_path)) return; - auto run_arguments_it=debug_run_arguments.find(project_path.string()); + auto run_arguments_it=Project::get().debug_run_arguments.find(project_path.string()); std::string run_arguments; - if(run_arguments_it!=debug_run_arguments.end()) + if(run_arguments_it!=Project::get().debug_run_arguments.end()) run_arguments=run_arguments_it->second; if(run_arguments.empty()) { @@ -193,53 +274,67 @@ void ProjectClang::debug_start(std::function st } } - debugging=true; + Project::get().debugging=true; Terminal::get().print("Compiling and debugging "+run_arguments+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path, status_callback, stop_callback](int exit_status){ + Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path](int exit_status){ if(exit_status!=EXIT_SUCCESS) - debugging=false; + Project::get().debugging=false; else { debug_start_mutex.lock(); Debug::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ - debugging=false; + Project::get().debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); - }, status_callback, stop_callback); + }, [this](const std::string &status) { + auto &project=Project::get(); + project.debug_status_mutex.lock(); + project.debug_status=status; + project.debug_status_mutex.unlock(); + project.debug_update_status(); + }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { + auto &project=Project::get(); + project.debug_stop_mutex.lock(); + project.debug_stop.first=file_path; + project.debug_stop.second.first=line_nr; + project.debug_stop.second.second=line_index; + project.debug_stop_mutex.unlock(); + project.debug_update_stop(); + }); debug_start_mutex.unlock(); } }); } -void ProjectClang::debug_continue() { +void Project::Clang::debug_continue() { Debug::get().continue_debug(); } -void ProjectClang::debug_stop() { - if(debugging) +void Project::Clang::debug_stop() { + if(Project::get().debugging) Debug::get().stop(); } -void ProjectClang::debug_kill() { - if(debugging) +void Project::Clang::debug_kill() { + if(Project::get().debugging) Debug::get().kill(); } -void ProjectClang::debug_step_over() { - if(debugging) +void Project::Clang::debug_step_over() { + if(Project::get().debugging) Debug::get().step_over(); } -void ProjectClang::debug_step_into() { - if(debugging) +void Project::Clang::debug_step_into() { + if(Project::get().debugging) Debug::get().step_into(); } -void ProjectClang::debug_step_out() { - if(debugging) +void Project::Clang::debug_step_out() { + if(Project::get().debugging) Debug::get().step_out(); } -void ProjectClang::debug_backtrace() { - if(debugging && notebook.get_current_page()!=-1) { +void Project::Clang::debug_backtrace() { + if(Project::get().debugging && notebook.get_current_page()!=-1) { auto backtrace=Debug::get().get_backtrace(); auto view=notebook.get_current_view(); @@ -288,8 +383,8 @@ void ProjectClang::debug_backtrace() { } } -void ProjectClang::debug_show_variables() { - if(debugging && notebook.get_current_page()!=-1) { +void Project::Clang::debug_show_variables() { + if(Project::get().debugging && notebook.get_current_page()!=-1) { auto variables=Debug::get().get_variables(); auto view=notebook.get_current_view(); @@ -366,29 +461,62 @@ void ProjectClang::debug_show_variables() { } } -void ProjectClang::debug_run_command(const std::string &command) { - if(debugging) { +void Project::Clang::debug_run_command(const std::string &command) { + if(Project::get().debugging) { auto command_return=Debug::get().run_command(command); Terminal::get().async_print(command_return.first); Terminal::get().async_print(command_return.second, true); } } -void ProjectClang::debug_delete() { +void Project::Clang::debug_goto_stop() { + if(Project::get().debugging) { + auto &project=Project::get(); + project.debug_stop_mutex.lock(); + auto debug_stop_copy=project.debug_stop; + project.debug_stop_mutex.unlock(); + if(!debug_stop_copy.first.empty()) { + notebook.open(debug_stop_copy.first); + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + + int line_nr=debug_stop_copy.second.first-1; + int line_index=debug_stop_copy.second.second-1; + if(line_nrget_buffer()->get_line_count()) { + auto iter=view->get_buffer()->get_iter_at_line(line_nr); + auto end_line_iter=iter; + while(!iter.ends_line() && iter.forward_char()) {} + auto line=view->get_buffer()->get_text(iter, end_line_iter); + if(static_cast(line_index)>=line.bytes()) + line_index=0; + view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index)); + + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); + if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } + project.debug_update_stop(); + } + } + } +} + +void Project::Clang::debug_delete() { debug_start_mutex.lock(); Debug::get().delete_debug(); debug_start_mutex.unlock(); } #endif -ProjectMarkdown::~ProjectMarkdown() { +Project::Markdown::~Markdown() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); last_temp_path=boost::filesystem::path(); } } -void ProjectMarkdown::compile_and_run() { +void Project::Markdown::compile_and_run() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); last_temp_path=boost::filesystem::path(); @@ -424,7 +552,7 @@ void ProjectMarkdown::compile_and_run() { } } -void ProjectPython::compile_and_run() { +void Project::Python::compile_and_run() { auto command="python "+notebook.get_current_view()->file_path.string(); Terminal::get().print("Running "+command+"\n"); Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) { @@ -432,7 +560,7 @@ void ProjectPython::compile_and_run() { }); } -void ProjectJavaScript::compile_and_run() { +void Project::JavaScript::compile_and_run() { auto command="node "+notebook.get_current_view()->file_path.string(); Terminal::get().print("Running "+command+"\n"); Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) { @@ -440,7 +568,7 @@ void ProjectJavaScript::compile_and_run() { }); } -void ProjectHTML::compile_and_run() { +void Project::HTML::compile_and_run() { auto uri=notebook.get_current_view()->file_path.string(); #ifdef __APPLE__ Terminal::get().process("open \""+uri+"\""); diff --git a/src/project.h b/src/project.h index c6eded8..9e2b14f 100644 --- a/src/project.h +++ b/src/project.h @@ -1,6 +1,7 @@ #ifndef JUCI_PROJECT_H_ #define JUCI_PROJECT_H_ +#include #include "notebook.h" #include "cmake.h" #include @@ -10,93 +11,115 @@ #include "tooltips.h" class Project { -public: - Project(Notebook ¬ebook) : notebook(notebook) {} - virtual ~Project() {} - - Notebook ¬ebook; - - static std::unordered_map run_arguments; - static std::unordered_map debug_run_arguments; - static std::atomic compiling; - static std::atomic debugging; - - virtual std::pair get_run_arguments() {return {"", ""};} - virtual void compile() {} - virtual void compile_and_run() {} - - virtual std::pair debug_get_run_arguments() {return {"", ""};} - Tooltips debug_variable_tooltips; - virtual void debug_start(std::function status_callback, - std::function stop_callback) {} - virtual void debug_continue() {} - virtual void debug_stop() {} - virtual void debug_kill() {} - virtual void debug_step_over() {} - virtual void debug_step_into() {} - virtual void debug_step_out() {} - virtual void debug_backtrace() {} - virtual void debug_show_variables() {} - virtual void debug_run_command(const std::string &command) {} - virtual void debug_delete() {} -}; +private: + std::pair > debug_stop; + std::mutex debug_stop_mutex; + boost::filesystem::path debug_last_stop_file_path; + Glib::Dispatcher debug_update_stop; + std::string debug_status; + std::mutex debug_status_mutex; + Glib::Dispatcher debug_update_status; -class ProjectClang : public Project { + Project(); + Notebook ¬ebook; //convenience reference public: - ProjectClang(Notebook ¬ebook) : Project(notebook) {} + static Project &get() { + static Project singleton; + return singleton; + } + + Gtk::Label debug_status_label; + std::unordered_map run_arguments; + std::unordered_map debug_run_arguments; + std::atomic compiling; + std::atomic debugging; - std::unique_ptr get_cmake(); + class Language { + protected: + Notebook ¬ebook; //convenience reference + public: + Language() : notebook(Notebook::get()) {} + virtual ~Language() {} + + virtual std::pair get_run_arguments() {return {"", ""};} + virtual void compile() {} + virtual void compile_and_run() {} + + virtual std::pair debug_get_run_arguments() {return {"", ""};} + Tooltips debug_variable_tooltips; + virtual void debug_start() {} + virtual void debug_continue() {} + virtual void debug_stop() {} + virtual void debug_kill() {} + virtual void debug_step_over() {} + virtual void debug_step_into() {} + virtual void debug_step_out() {} + virtual void debug_backtrace() {} + virtual void debug_show_variables() {} + virtual void debug_run_command(const std::string &command) {} + virtual void debug_goto_stop() {} + virtual void debug_delete() {} + }; - std::pair get_run_arguments() override; - void compile() override; - void compile_and_run() override; + class Clang : public Language { + public: + Clang() : Language() {} + + std::unique_ptr get_cmake(); + + std::pair get_run_arguments() override; + void compile() override; + void compile_and_run() override; + + std::mutex debug_start_mutex; + #ifdef JUCI_ENABLE_DEBUG + std::pair debug_get_run_arguments() override; + void debug_start() override; + void debug_continue() override; + void debug_stop() override; + void debug_kill() override; + void debug_step_over() override; + void debug_step_into() override; + void debug_step_out() override; + void debug_backtrace() override; + void debug_show_variables() override; + void debug_run_command(const std::string &command) override; + void debug_goto_stop() override; + void debug_delete() override; + #endif + }; - std::mutex debug_start_mutex; -#ifdef JUCI_ENABLE_DEBUG - std::pair debug_get_run_arguments() override; - void debug_start(std::function status_callback, - std::function stop_callback) override; - void debug_continue() override; - void debug_stop() override; - void debug_kill() override; - void debug_step_over() override; - void debug_step_into() override; - void debug_step_out() override; - void debug_backtrace() override; - void debug_show_variables() override; - void debug_run_command(const std::string &command) override; - void debug_delete() override; -#endif -}; - -class ProjectMarkdown : public Project { -public: - ProjectMarkdown(Notebook ¬ebook) : Project(notebook) {} - ~ProjectMarkdown(); + class Markdown : public Language { + public: + Markdown() : Language() {} + ~Markdown(); + + boost::filesystem::path last_temp_path; + void compile_and_run() override; + }; - boost::filesystem::path last_temp_path; - void compile_and_run() override; -}; - -class ProjectPython : public Project { -public: - ProjectPython(Notebook ¬ebook) : Project(notebook) {} + class Python : public Language { + public: + Python() : Language() {} + + void compile_and_run() override; + }; - void compile_and_run() override; -}; - -class ProjectJavaScript : public Project { -public: - ProjectJavaScript(Notebook ¬ebook) : Project(notebook) {} + class JavaScript : public Language { + public: + JavaScript() : Language() {} + + void compile_and_run() override; + }; - void compile_and_run() override; -}; - -class ProjectHTML : public Project { -public: - ProjectHTML(Notebook ¬ebook) : Project(notebook) {} + class HTML : public Language { + public: + HTML() : Language() {} + + void compile_and_run() override; + }; - void compile_and_run() override; + std::unique_ptr get_language(); }; #endif // JUCI_PROJECT_H_ diff --git a/src/window.cc b/src/window.cc index 1da6258..d583fc1 100644 --- a/src/window.cc +++ b/src/window.cc @@ -24,7 +24,7 @@ namespace sigc { #endif } -Window::Window() { +Window::Window() : notebook(Notebook::get()) { JDEBUG("start"); set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK); @@ -50,7 +50,7 @@ Window::Window() { info_and_status_hbox.pack_start(notebook.info, Gtk::PACK_SHRINK); #if GTK_VERSION_GE(3, 12) - info_and_status_hbox.set_center_widget(debug_status_label); + info_and_status_hbox.set_center_widget(Project::get().debug_status_label); #else debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); info_and_status_hbox.pack_start(debug_status_label); @@ -121,74 +121,6 @@ Window::Window() { about.hide(); }); - debug_update_stop.connect([this](){ - debug_stop_mutex.lock(); - for(int c=0;cfile_path==debug_last_stop_file_path) { - view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop"); - break; - } - } - //Add debug stop source mark - for(int c=0;cfile_path==debug_stop.first) { - if(debug_stop.second.first-1get_buffer()->get_line_count()) { - view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(debug_stop.second.first-1)); - debug_last_stop_file_path=debug_stop.first; - } - break; - } - } - if(notebook.get_current_page()!=-1) - notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_insert()->get_iter()); - debug_stop_mutex.unlock(); - }); - -#ifdef JUCI_ENABLE_DEBUG - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(false); - menu.actions["debug_kill"]->set_enabled(false); - menu.actions["debug_step_over"]->set_enabled(false); - menu.actions["debug_step_into"]->set_enabled(false); - menu.actions["debug_step_out"]->set_enabled(false); - menu.actions["debug_backtrace"]->set_enabled(false); - menu.actions["debug_show_variables"]->set_enabled(false); - menu.actions["debug_run_command"]->set_enabled(false); - menu.actions["debug_goto_stop"]->set_enabled(false); -#endif - debug_update_status.connect([this](){ - debug_status_mutex.lock(); - if(debug_status.empty()) { - debug_status_label.set_text(""); - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(false); - menu.actions["debug_kill"]->set_enabled(false); - menu.actions["debug_step_over"]->set_enabled(false); - menu.actions["debug_step_into"]->set_enabled(false); - menu.actions["debug_step_out"]->set_enabled(false); - menu.actions["debug_backtrace"]->set_enabled(false); - menu.actions["debug_show_variables"]->set_enabled(false); - menu.actions["debug_run_command"]->set_enabled(false); - menu.actions["debug_goto_stop"]->set_enabled(false); - } - else { - debug_status_label.set_text("debug: "+debug_status); - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(); - menu.actions["debug_kill"]->set_enabled(); - menu.actions["debug_step_over"]->set_enabled(); - menu.actions["debug_step_into"]->set_enabled(); - menu.actions["debug_step_out"]->set_enabled(); - menu.actions["debug_backtrace"]->set_enabled(); - menu.actions["debug_show_variables"]->set_enabled(); - menu.actions["debug_run_command"]->set_enabled(); - menu.actions["debug_goto_stop"]->set_enabled(); - } - debug_status_mutex.unlock(); - }); - about.set_version(Config::get().window.version); about.set_authors({"(in order of appearance)", "Ted Johan Kristoffersen", @@ -575,8 +507,8 @@ void Window::set_menu_actions() { }); menu.add_action("project_set_run_arguments", [this]() { - project=get_project(); - auto run_arguments=std::make_shared >(project->get_run_arguments()); + auto project_language=Project::get().get_language(); + auto run_arguments=std::make_shared >(project_language->get_run_arguments()); if(run_arguments->second.empty()) return; @@ -588,7 +520,7 @@ void Window::set_menu_actions() { }; label_it->update(0, ""); entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ - Project::run_arguments[run_arguments->first]=content; + Project::get().run_arguments[run_arguments->first]=content; entry_box.hide(); }, 50); auto entry_it=entry_box.entries.begin(); @@ -599,24 +531,24 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("compile_and_run", [this]() { - if(Project::compiling) + if(Project::get().compiling) return; if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project=get_project(); - project->compile_and_run(); + project_language=Project::get().get_language(); + project_language->compile_and_run(); }); menu.add_action("compile", [this]() { - if(Project::compiling) + if(Project::get().compiling) return; if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project=get_project(); - project->compile(); + project_language=Project::get().get_language(); + project_language->compile(); }); menu.add_action("run_command", [this]() { @@ -656,8 +588,8 @@ void Window::set_menu_actions() { #ifdef JUCI_ENABLE_DEBUG menu.add_action("debug_set_run_arguments", [this]() { - project=get_project(); - auto run_arguments=std::make_shared >(project->debug_get_run_arguments()); + auto project_language=Project::get().get_language(); + auto run_arguments=std::make_shared >(project_language->debug_get_run_arguments()); if(run_arguments->second.empty()) return; @@ -669,7 +601,7 @@ void Window::set_menu_actions() { }; label_it->update(0, ""); entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ - Project::debug_run_arguments[run_arguments->first]=content; + Project::get().debug_run_arguments[run_arguments->first]=content; entry_box.hide(); }, 50); auto entry_it=entry_box.entries.begin(); @@ -680,64 +612,52 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("debug_start_continue", [this](){ - if(Project::debugging) { - project->debug_continue(); + if(Project::get().debugging) { + project_language->debug_continue(); return; } if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project=get_project(); + project_language=Project::get().get_language(); - project->debug_start([this](const std::string &status) { - debug_status_mutex.lock(); - debug_status=status; - debug_status_mutex.unlock(); - debug_update_status(); - }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { - debug_stop_mutex.lock(); - debug_stop.first=file_path; - debug_stop.second.first=line_nr; - debug_stop.second.second=line_index; - debug_stop_mutex.unlock(); - debug_update_stop(); - }); + project_language->debug_start(); }); menu.add_action("debug_stop", [this]() { - if(project) - project->debug_stop(); + if(project_language) + project_language->debug_stop(); }); menu.add_action("debug_kill", [this]() { - if(project) - project->debug_kill(); + if(project_language) + project_language->debug_kill(); }); menu.add_action("debug_step_over", [this]() { - if(project) - project->debug_step_over(); + if(project_language) + project_language->debug_step_over(); }); menu.add_action("debug_step_into", [this]() { - if(project) - project->debug_step_into(); + if(project_language) + project_language->debug_step_into(); }); menu.add_action("debug_step_out", [this]() { - if(project) - project->debug_step_out(); + if(project_language) + project_language->debug_step_out(); }); menu.add_action("debug_backtrace", [this]() { - if(project) - project->debug_backtrace(); + if(project_language) + project_language->debug_backtrace(); }); menu.add_action("debug_show_variables", [this]() { - if(project) - project->debug_show_variables(); + if(project_language) + project_language->debug_show_variables(); }); menu.add_action("debug_run_command", [this]() { entry_box.clear(); entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){ if(content!="") { - if(project) - project->debug_run_command(content); + if(project_language) + project_language->debug_run_command(content); last_run_debug_command=content; } entry_box.hide(); @@ -773,35 +693,8 @@ void Window::set_menu_actions() { } }); menu.add_action("debug_goto_stop", [this](){ - if(project && project->debugging) { - debug_stop_mutex.lock(); - auto debug_stop_copy=debug_stop; - debug_stop_mutex.unlock(); - if(!debug_stop_copy.first.empty()) { - notebook.open(debug_stop_copy.first); - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - - int line_nr=debug_stop_copy.second.first-1; - int line_index=debug_stop_copy.second.second-1; - if(line_nrget_buffer()->get_line_count()) { - auto iter=view->get_buffer()->get_iter_at_line(line_nr); - auto end_line_iter=iter; - while(!iter.ends_line() && iter.forward_char()) {} - auto line=view->get_buffer()->get_text(iter, end_line_iter); - if(static_cast(line_index)>=line.bytes()) - line_index=0; - view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index)); - - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); - } - debug_update_stop(); - } - } - } + if(project_language) + project_language->debug_goto_stop(); }); #endif @@ -899,8 +792,8 @@ bool Window::on_delete_event(GdkEventAny *event) { } Terminal::get().kill_async_processes(); #ifdef JUCI_ENABLE_DEBUG - if(project) - project->debug_delete(); + if(project_language) + project_language->debug_delete(); #endif return false; } @@ -1126,19 +1019,3 @@ void Window::rename_token_entry() { } } } - -std::unique_ptr Window::get_project() { - if(notebook.get_current_page()!=-1) { - auto language_id=notebook.get_current_view()->language->get_id(); - if(language_id=="markdown") - return std::unique_ptr(new ProjectMarkdown(notebook)); - if(language_id=="python") - return std::unique_ptr(new ProjectPython(notebook)); - if(language_id=="js") - return std::unique_ptr(new ProjectJavaScript(notebook)); - if(language_id=="html") - return std::unique_ptr(new ProjectHTML(notebook)); - } - - return std::unique_ptr(new ProjectClang(notebook)); -} diff --git a/src/window.h b/src/window.h index 4fbfce5..191b592 100644 --- a/src/window.h +++ b/src/window.h @@ -1,7 +1,7 @@ #ifndef JUCI_WINDOW_H_ #define JUCI_WINDOW_H_ -#include "gtkmm.h" +#include #include "entrybox.h" #include "notebook.h" #include "cmake.h" @@ -11,13 +11,12 @@ class Window : public Gtk::ApplicationWindow { private: Window(); + Notebook ¬ebook; //convenience reference public: static Window &get() { static Window singleton; return singleton; } - - Notebook notebook; protected: bool on_key_press_event(GdkEventKey *event) override; @@ -34,17 +33,7 @@ private: Gtk::AboutDialog about; EntryBox entry_box; - std::unique_ptr project; - - Gtk::Label debug_status_label; - - std::pair > debug_stop; - boost::filesystem::path debug_last_stop_file_path; - std::mutex debug_stop_mutex; - Glib::Dispatcher debug_update_stop; - std::string debug_status; - std::mutex debug_status_mutex; - Glib::Dispatcher debug_update_status; + std::unique_ptr project_language; void configure(); void set_menu_actions(); @@ -60,8 +49,6 @@ private: bool case_sensitive_search=true; bool regex_search=false; bool search_entry_shown=false; - - std::unique_ptr get_project(); }; #endif // JUCI_WINDOW_H From d4e886a31d268908a42c877791419ac8c1df38fb Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 11 Feb 2016 17:15:47 +0100 Subject: [PATCH 10/41] More project cleanup, some minor things left to do --- src/project.cc | 24 ++++++++++++++++++++++++ src/project.h | 2 ++ src/window.cc | 29 ++++++----------------------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/project.cc b/src/project.cc index 83389e3..6d2cd59 100644 --- a/src/project.cc +++ b/src/project.cc @@ -469,6 +469,30 @@ void Project::Clang::debug_run_command(const std::string &command) { } } +void Project::Clang::toggle_breakpoint() { + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + bool debug_is_stopped_or_running=Debug::get().is_stopped() || Debug::get().is_running(); + if(Debug::get().is_invalid() || debug_is_stopped_or_running) { + auto line_nr=view->get_buffer()->get_insert()->get_iter().get_line(); + + if(view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) { + auto start_iter=view->get_buffer()->get_iter_at_line(line_nr); + auto end_iter=start_iter; + while(!end_iter.ends_line() && end_iter.forward_char()) {} + view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); + if(debug_is_stopped_or_running) + Debug::get().remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); + } + else { + view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); + if(debug_is_stopped_or_running) + Debug::get().add_breakpoint(view->file_path, line_nr+1); + } + } + } +} + void Project::Clang::debug_goto_stop() { if(Project::get().debugging) { auto &project=Project::get(); diff --git a/src/project.h b/src/project.h index 9e2b14f..9a9f239 100644 --- a/src/project.h +++ b/src/project.h @@ -57,6 +57,7 @@ public: virtual void debug_backtrace() {} virtual void debug_show_variables() {} virtual void debug_run_command(const std::string &command) {} + virtual void toggle_breakpoint() {} virtual void debug_goto_stop() {} virtual void debug_delete() {} }; @@ -84,6 +85,7 @@ public: void debug_backtrace() override; void debug_show_variables() override; void debug_run_command(const std::string &command) override; + void toggle_breakpoint() override; void debug_goto_stop() override; void debug_delete() override; #endif diff --git a/src/window.cc b/src/window.cc index d583fc1..0c36b56 100644 --- a/src/window.cc +++ b/src/window.cc @@ -52,8 +52,8 @@ Window::Window() : notebook(Notebook::get()) { #if GTK_VERSION_GE(3, 12) info_and_status_hbox.set_center_widget(Project::get().debug_status_label); #else - debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); - info_and_status_hbox.pack_start(debug_status_label); + Project::get().debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); + info_and_status_hbox.pack_start(Project::get().debug_status_label); #endif info_and_status_hbox.pack_end(notebook.status, Gtk::PACK_SHRINK); terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); @@ -670,27 +670,10 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("debug_toggle_breakpoint", [this](){ - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - bool debug_is_stopped_or_running=Debug::get().is_stopped() || Debug::get().is_running(); - if(Debug::get().is_invalid() || debug_is_stopped_or_running) { - auto line_nr=view->get_buffer()->get_insert()->get_iter().get_line(); - - if(view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) { - auto start_iter=view->get_buffer()->get_iter_at_line(line_nr); - auto end_iter=start_iter; - while(!end_iter.ends_line() && end_iter.forward_char()) {} - view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); - if(debug_is_stopped_or_running) - Debug::get().remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); - } - else { - view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); - if(debug_is_stopped_or_running) - Debug::get().add_breakpoint(view->file_path, line_nr+1); - } - } - } + if(Project::get().debugging) + project_language->toggle_breakpoint(); + else + Project::get().get_language()->toggle_breakpoint(); }); menu.add_action("debug_goto_stop", [this](){ if(project_language) From e1843d42ef104cd70f1d5d723f1bc82f685003e1 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 11 Feb 2016 17:34:12 +0100 Subject: [PATCH 11/41] Removed include debug.h from window.cc --- src/window.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/window.cc b/src/window.cc index 0c36b56..193a5e9 100644 --- a/src/window.cc +++ b/src/window.cc @@ -6,9 +6,6 @@ //#include "api.h" #include "dialogs.h" #include "filesystem.h" -#ifdef JUCI_ENABLE_DEBUG -#include "debug.h" -#endif namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE From edbd713280f7d93621d9360c03d5046b49f8186f Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 11 Feb 2016 19:47:30 +0100 Subject: [PATCH 12/41] Improved separation of what is performed in window and project classes --- src/project.cc | 57 ++++---------------------------------------------- src/project.h | 14 ++++++------- src/window.cc | 54 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 66 deletions(-) diff --git a/src/project.cc b/src/project.cc index 6d2cd59..9ab0f9b 100644 --- a/src/project.cc +++ b/src/project.cc @@ -469,61 +469,12 @@ void Project::Clang::debug_run_command(const std::string &command) { } } -void Project::Clang::toggle_breakpoint() { - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - bool debug_is_stopped_or_running=Debug::get().is_stopped() || Debug::get().is_running(); - if(Debug::get().is_invalid() || debug_is_stopped_or_running) { - auto line_nr=view->get_buffer()->get_insert()->get_iter().get_line(); - - if(view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) { - auto start_iter=view->get_buffer()->get_iter_at_line(line_nr); - auto end_iter=start_iter; - while(!end_iter.ends_line() && end_iter.forward_char()) {} - view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); - if(debug_is_stopped_or_running) - Debug::get().remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); - } - else { - view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); - if(debug_is_stopped_or_running) - Debug::get().add_breakpoint(view->file_path, line_nr+1); - } - } - } +void Project::Clang::debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { + Debug::get().add_breakpoint(file_path, line_nr); } -void Project::Clang::debug_goto_stop() { - if(Project::get().debugging) { - auto &project=Project::get(); - project.debug_stop_mutex.lock(); - auto debug_stop_copy=project.debug_stop; - project.debug_stop_mutex.unlock(); - if(!debug_stop_copy.first.empty()) { - notebook.open(debug_stop_copy.first); - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); - - int line_nr=debug_stop_copy.second.first-1; - int line_index=debug_stop_copy.second.second-1; - if(line_nrget_buffer()->get_line_count()) { - auto iter=view->get_buffer()->get_iter_at_line(line_nr); - auto end_line_iter=iter; - while(!iter.ends_line() && iter.forward_char()) {} - auto line=view->get_buffer()->get_text(iter, end_line_iter); - if(static_cast(line_index)>=line.bytes()) - line_index=0; - view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index)); - - while(g_main_context_pending(NULL)) - g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) - view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); - } - project.debug_update_stop(); - } - } - } +void Project::Clang::debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { + Debug::get().remove_breakpoint(file_path, line_nr, line_count); } void Project::Clang::debug_delete() { diff --git a/src/project.h b/src/project.h index 9a9f239..5370e2d 100644 --- a/src/project.h +++ b/src/project.h @@ -12,10 +12,7 @@ class Project { private: - std::pair > debug_stop; - std::mutex debug_stop_mutex; boost::filesystem::path debug_last_stop_file_path; - Glib::Dispatcher debug_update_stop; std::string debug_status; std::mutex debug_status_mutex; Glib::Dispatcher debug_update_status; @@ -29,6 +26,9 @@ public: } Gtk::Label debug_status_label; + std::pair > debug_stop; + std::mutex debug_stop_mutex; + Glib::Dispatcher debug_update_stop; std::unordered_map run_arguments; std::unordered_map debug_run_arguments; std::atomic compiling; @@ -57,8 +57,8 @@ public: virtual void debug_backtrace() {} virtual void debug_show_variables() {} virtual void debug_run_command(const std::string &command) {} - virtual void toggle_breakpoint() {} - virtual void debug_goto_stop() {} + virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {} + virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {} virtual void debug_delete() {} }; @@ -85,8 +85,8 @@ public: void debug_backtrace() override; void debug_show_variables() override; void debug_run_command(const std::string &command) override; - void toggle_breakpoint() override; - void debug_goto_stop() override; + void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override; + void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override; void debug_delete() override; #endif }; diff --git a/src/window.cc b/src/window.cc index 193a5e9..1c208c5 100644 --- a/src/window.cc +++ b/src/window.cc @@ -667,14 +667,56 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("debug_toggle_breakpoint", [this](){ - if(Project::get().debugging) - project_language->toggle_breakpoint(); - else - Project::get().get_language()->toggle_breakpoint(); + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + auto line_nr=view->get_buffer()->get_insert()->get_iter().get_line(); + + if(view->get_source_buffer()->get_source_marks_at_line(line_nr, "debug_breakpoint").size()>0) { + auto start_iter=view->get_buffer()->get_iter_at_line(line_nr); + auto end_iter=start_iter; + while(!end_iter.ends_line() && end_iter.forward_char()) {} + view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); + if(project_language) + project_language->debug_remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); + } + else { + view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); + if(project_language) + project_language->debug_add_breakpoint(view->file_path, line_nr+1); + } + } }); menu.add_action("debug_goto_stop", [this](){ - if(project_language) - project_language->debug_goto_stop(); + if(Project::get().debugging) { + auto &project=Project::get(); + project.debug_stop_mutex.lock(); + auto debug_stop_copy=project.debug_stop; + project.debug_stop_mutex.unlock(); + if(!debug_stop_copy.first.empty()) { + notebook.open(debug_stop_copy.first); + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + + int line_nr=debug_stop_copy.second.first-1; + int line_index=debug_stop_copy.second.second-1; + if(line_nrget_buffer()->get_line_count()) { + auto iter=view->get_buffer()->get_iter_at_line(line_nr); + auto end_line_iter=iter; + while(!iter.ends_line() && iter.forward_char()) {} + auto line=view->get_buffer()->get_text(iter, end_line_iter); + if(static_cast(line_index)>=line.bytes()) + line_index=0; + view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line_nr, line_index)); + + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); + if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } + project.debug_update_stop(); + } + } + } }); #endif From e667a38640d5d342874343b5f65ed78bac14ce40 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 19:37:36 +0100 Subject: [PATCH 13/41] Added Dispatcher class for simpler dispatching of functions from worker threads to gui thread. Also got rid of the Project-singleton by replacing its function with static functions --- src/CMakeLists.txt | 2 + src/dispatcher.cc | 30 ++++++ src/dispatcher.h | 20 ++++ src/project.cc | 248 ++++++++++++++++++++++----------------------- src/project.h | 41 +++----- src/terminal.cc | 59 +++-------- src/terminal.h | 12 +-- src/window.cc | 47 +++++---- 8 files changed, 230 insertions(+), 229 deletions(-) create mode 100644 src/dispatcher.cc create mode 100644 src/dispatcher.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e98ca99..ff2e207 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -86,6 +86,8 @@ set(source_files juci.h dialogs.cc project.h project.cc + dispatcher.h + dispatcher.cc ../libclangmm/src/CodeCompleteResults.cc ../libclangmm/src/CompilationDatabase.cc diff --git a/src/dispatcher.cc b/src/dispatcher.cc new file mode 100644 index 0000000..4a1d80c --- /dev/null +++ b/src/dispatcher.cc @@ -0,0 +1,30 @@ +#include "dispatcher.h" + +Dispatcher::Dispatcher() { + connection=dispatcher.connect([this] { + functions_mutex.lock(); + for(auto &function: functions) { + function(); + } + functions.clear(); + functions_mutex.unlock(); + }); +} + +Dispatcher::~Dispatcher() { + disconnect(); + functions_mutex.lock(); + functions.clear(); + functions_mutex.unlock(); +} + +void Dispatcher::add(std::function function) { + functions_mutex.lock(); + functions.emplace_back(function); + functions_mutex.unlock(); + dispatcher(); +} + +void Dispatcher::disconnect() { + connection.disconnect(); +} diff --git a/src/dispatcher.h b/src/dispatcher.h new file mode 100644 index 0000000..70312f1 --- /dev/null +++ b/src/dispatcher.h @@ -0,0 +1,20 @@ +#ifndef DISPATCHER_H_ +#define DISPATCHER_H_ +#include +#include +#include + +class Dispatcher { +private: + std::vector> functions; + std::mutex functions_mutex; + Glib::Dispatcher dispatcher; + sigc::connection connection; +public: + Dispatcher(); + ~Dispatcher(); + void add(std::function function); + void disconnect(); +}; + +#endif /* DISPATCHER_H_ */ diff --git a/src/project.cc b/src/project.cc index 9ab0f9b..a28352f 100644 --- a/src/project.cc +++ b/src/project.cc @@ -4,83 +4,74 @@ #include "filesystem.h" #include #include "menu.h" +#include "notebook.h" #ifdef JUCI_ENABLE_DEBUG #include "debug.h" #endif -Project::Project() : notebook(Notebook::get()), compiling(false), debugging(false) { - debug_update_stop.connect([this](){ - debug_stop_mutex.lock(); - for(int c=0;cfile_path==debug_last_stop_file_path) { - view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop"); - break; - } +std::unordered_map Project::run_arguments; +std::unordered_map Project::debug_run_arguments; +std::atomic Project::compiling; +std::atomic Project::debugging; +std::pair > Project::debug_stop; +boost::filesystem::path Project::debug_last_stop_file_path; +std::unique_ptr Project::debug_status_label; + +void Project::debug_update_status(const std::string &debug_status) { + if(debug_status.empty()) { + debug_status_label->set_text(""); + auto &menu=Menu::get(); + menu.actions["debug_stop"]->set_enabled(false); + menu.actions["debug_kill"]->set_enabled(false); + menu.actions["debug_step_over"]->set_enabled(false); + menu.actions["debug_step_into"]->set_enabled(false); + menu.actions["debug_step_out"]->set_enabled(false); + menu.actions["debug_backtrace"]->set_enabled(false); + menu.actions["debug_show_variables"]->set_enabled(false); + menu.actions["debug_run_command"]->set_enabled(false); + menu.actions["debug_goto_stop"]->set_enabled(false); + } + else { + debug_status_label->set_text("debug: "+debug_status); + auto &menu=Menu::get(); + menu.actions["debug_stop"]->set_enabled(); + menu.actions["debug_kill"]->set_enabled(); + menu.actions["debug_step_over"]->set_enabled(); + menu.actions["debug_step_into"]->set_enabled(); + menu.actions["debug_step_out"]->set_enabled(); + menu.actions["debug_backtrace"]->set_enabled(); + menu.actions["debug_show_variables"]->set_enabled(); + menu.actions["debug_run_command"]->set_enabled(); + menu.actions["debug_goto_stop"]->set_enabled(); + } +} + +void Project::debug_update_stop() { + for(int c=0;cfile_path==debug_last_stop_file_path) { + view->get_source_buffer()->remove_source_marks(view->get_buffer()->begin(), view->get_buffer()->end(), "debug_stop"); + break; } - //Add debug stop source mark - for(int c=0;cfile_path==debug_stop.first) { - if(debug_stop.second.first-1get_buffer()->get_line_count()) { - view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(debug_stop.second.first-1)); - debug_last_stop_file_path=debug_stop.first; - } - break; + } + //Add debug stop source mark + for(int c=0;cfile_path==debug_stop.first) { + if(debug_stop.second.first-1get_buffer()->get_line_count()) { + view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(debug_stop.second.first-1)); + debug_last_stop_file_path=debug_stop.first; } + break; } - if(notebook.get_current_page()!=-1) - notebook.get_current_view()->get_buffer()->place_cursor(notebook.get_current_view()->get_buffer()->get_insert()->get_iter()); - debug_stop_mutex.unlock(); - }); - -#ifdef JUCI_ENABLE_DEBUG - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(false); - menu.actions["debug_kill"]->set_enabled(false); - menu.actions["debug_step_over"]->set_enabled(false); - menu.actions["debug_step_into"]->set_enabled(false); - menu.actions["debug_step_out"]->set_enabled(false); - menu.actions["debug_backtrace"]->set_enabled(false); - menu.actions["debug_show_variables"]->set_enabled(false); - menu.actions["debug_run_command"]->set_enabled(false); - menu.actions["debug_goto_stop"]->set_enabled(false); -#endif - debug_update_status.connect([this](){ - debug_status_mutex.lock(); - if(debug_status.empty()) { - debug_status_label.set_text(""); - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(false); - menu.actions["debug_kill"]->set_enabled(false); - menu.actions["debug_step_over"]->set_enabled(false); - menu.actions["debug_step_into"]->set_enabled(false); - menu.actions["debug_step_out"]->set_enabled(false); - menu.actions["debug_backtrace"]->set_enabled(false); - menu.actions["debug_show_variables"]->set_enabled(false); - menu.actions["debug_run_command"]->set_enabled(false); - menu.actions["debug_goto_stop"]->set_enabled(false); - } - else { - debug_status_label.set_text("debug: "+debug_status); - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(); - menu.actions["debug_kill"]->set_enabled(); - menu.actions["debug_step_over"]->set_enabled(); - menu.actions["debug_step_into"]->set_enabled(); - menu.actions["debug_step_out"]->set_enabled(); - menu.actions["debug_backtrace"]->set_enabled(); - menu.actions["debug_show_variables"]->set_enabled(); - menu.actions["debug_run_command"]->set_enabled(); - menu.actions["debug_goto_stop"]->set_enabled(); - } - debug_status_mutex.unlock(); - }); + } + if(Notebook::get().get_current_page()!=-1) + Notebook::get().get_current_view()->get_buffer()->place_cursor(Notebook::get().get_current_view()->get_buffer()->get_insert()->get_iter()); } std::unique_ptr Project::get_language() { - if(notebook.get_current_page()!=-1) { - auto language_id=notebook.get_current_view()->language->get_id(); + if(Notebook::get().get_current_page()!=-1) { + auto language_id=Notebook::get().get_current_view()->language->get_id(); if(language_id=="markdown") return std::unique_ptr(new Project::Markdown()); if(language_id=="python") @@ -96,8 +87,8 @@ std::unique_ptr Project::get_language() { std::unique_ptr Project::Clang::get_cmake() { boost::filesystem::path path; - if(notebook.get_current_page()!=-1) - path=notebook.get_current_view()->file_path.parent_path(); + if(Notebook::get().get_current_page()!=-1) + path=Notebook::get().get_current_view()->file_path.parent_path(); else path=Directories::get().current_path; if(path.empty()) @@ -116,13 +107,13 @@ std::pair Project::Clang::get_run_arguments() { return {"", ""}; auto project_path=cmake->project_path.string(); - auto run_arguments_it=Project::get().run_arguments.find(project_path); + auto run_arguments_it=run_arguments.find(project_path); std::string arguments; - if(run_arguments_it!=Project::get().run_arguments.end()) + if(run_arguments_it!=run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { - auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { auto project_path=cmake->project_path; @@ -149,10 +140,10 @@ void Project::Clang::compile() { auto default_build_path=CMake::get_default_build_path(cmake->project_path); if(default_build_path.empty()) return; - Project::get().compiling=true; + compiling=true; Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status) { - Project::get().compiling=false; + compiling=false; }); } @@ -166,13 +157,13 @@ void Project::Clang::compile_and_run() { if(default_build_path.empty()) return; - auto run_arguments_it=Project::get().run_arguments.find(project_path.string()); + auto run_arguments_it=run_arguments.find(project_path.string()); std::string arguments; - if(run_arguments_it!=Project::get().run_arguments.end()) + if(run_arguments_it!=run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { - arguments=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + arguments=cmake->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) @@ -186,10 +177,10 @@ void Project::Clang::compile_and_run() { arguments=filesystem::escape_argument(arguments); } - Project::get().compiling=true; + compiling=true; Terminal::get().print("Compiling and running "+arguments+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){ - Project::get().compiling=false; + compiling=false; if(exit_status==EXIT_SUCCESS) { Terminal::get().async_process(arguments, default_build_path, [this, arguments](int exit_status){ Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n'); @@ -205,13 +196,13 @@ std::pair Project::Clang::debug_get_run_arguments() { return {"", ""}; auto project_path=cmake->project_path.string(); - auto run_arguments_it=Project::get().debug_run_arguments.find(project_path); + auto run_arguments_it=debug_run_arguments.find(project_path); std::string arguments; - if(run_arguments_it!=Project::get().debug_run_arguments.end()) + if(run_arguments_it!=debug_run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { - auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + auto executable=cmake->get_executable(Notebook::get().get_current_page()!=-1?Notebook::get().get_current_view()->file_path:"").string(); if(executable!="") { auto project_path=cmake->project_path; @@ -242,13 +233,13 @@ void Project::Clang::debug_start() { if(!CMake::create_debug_build(project_path)) return; - auto run_arguments_it=Project::get().debug_run_arguments.find(project_path.string()); + auto run_arguments_it=debug_run_arguments.find(project_path.string()); std::string run_arguments; - if(run_arguments_it!=Project::get().debug_run_arguments.end()) + if(run_arguments_it!=debug_run_arguments.end()) run_arguments=run_arguments_it->second; if(run_arguments.empty()) { - run_arguments=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + run_arguments=cmake->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) @@ -263,8 +254,8 @@ void Project::Clang::debug_start() { } auto breakpoints=std::make_shared > >(); - for(int c=0;cproject_path) { auto iter=view->get_buffer()->begin(); if(view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()>0) @@ -274,30 +265,29 @@ void Project::Clang::debug_start() { } } - Project::get().debugging=true; + debugging=true; Terminal::get().print("Compiling and debugging "+run_arguments+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path](int exit_status){ if(exit_status!=EXIT_SUCCESS) - Project::get().debugging=false; + debugging=false; else { debug_start_mutex.lock(); Debug::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ - Project::get().debugging=false; + debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); }, [this](const std::string &status) { - auto &project=Project::get(); - project.debug_status_mutex.lock(); - project.debug_status=status; - project.debug_status_mutex.unlock(); - project.debug_update_status(); - }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { - auto &project=Project::get(); - project.debug_stop_mutex.lock(); - project.debug_stop.first=file_path; - project.debug_stop.second.first=line_nr; - project.debug_stop.second.second=line_index; - project.debug_stop_mutex.unlock(); - project.debug_update_stop(); + dispatcher.add([this, status] { + debug_update_status(status); + }); + }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { + dispatcher.add([this, file_path, line_nr, line_index] { + Project::debug_stop.first=file_path; + Project::debug_stop.second.first=line_nr; + Project::debug_stop.second.second=line_index; + + debug_update_stop(); + }); + }); debug_start_mutex.unlock(); } @@ -309,35 +299,35 @@ void Project::Clang::debug_continue() { } void Project::Clang::debug_stop() { - if(Project::get().debugging) + if(debugging) Debug::get().stop(); } void Project::Clang::debug_kill() { - if(Project::get().debugging) + if(debugging) Debug::get().kill(); } void Project::Clang::debug_step_over() { - if(Project::get().debugging) + if(debugging) Debug::get().step_over(); } void Project::Clang::debug_step_into() { - if(Project::get().debugging) + if(debugging) Debug::get().step_into(); } void Project::Clang::debug_step_out() { - if(Project::get().debugging) + if(debugging) Debug::get().step_out(); } void Project::Clang::debug_backtrace() { - if(Project::get().debugging && notebook.get_current_page()!=-1) { + if(debugging && Notebook::get().get_current_page()!=-1) { auto backtrace=Debug::get().get_backtrace(); - auto view=notebook.get_current_view(); + auto view=Notebook::get().get_current_view(); auto iter=view->get_iter_for_dialog(); view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); auto rows=std::make_shared >(); @@ -364,9 +354,9 @@ void Project::Clang::debug_backtrace() { view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { auto frame=rows->at(selected); if(!frame.file_path.empty()) { - notebook.open(frame.file_path); - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); + Notebook::get().open(frame.file_path); + if(Notebook::get().get_current_page()!=-1) { + auto view=Notebook::get().get_current_view(); Debug::get().select_frame(frame.index); @@ -374,7 +364,7 @@ void Project::Clang::debug_backtrace() { while(g_main_context_pending(NULL)) g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + if(Notebook::get().get_current_page()!=-1 && Notebook::get().get_current_view()==view) view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); } } @@ -384,10 +374,10 @@ void Project::Clang::debug_backtrace() { } void Project::Clang::debug_show_variables() { - if(Project::get().debugging && notebook.get_current_page()!=-1) { + if(debugging && Notebook::get().get_current_page()!=-1) { auto variables=Debug::get().get_variables(); - auto view=notebook.get_current_view(); + auto view=Notebook::get().get_current_view(); auto iter=view->get_iter_for_dialog(); view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); auto rows=std::make_shared >(); @@ -404,9 +394,9 @@ void Project::Clang::debug_show_variables() { view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { auto variable=rows->at(selected); if(!variable.file_path.empty()) { - notebook.open(variable.file_path); - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); + Notebook::get().open(variable.file_path); + if(Notebook::get().get_current_page()!=-1) { + auto view=Notebook::get().get_current_view(); Debug::get().select_frame(variable.frame_index, variable.thread_index_id); @@ -414,7 +404,7 @@ void Project::Clang::debug_show_variables() { while(g_main_context_pending(NULL)) g_main_context_iteration(NULL, false); - if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + if(Notebook::get().get_current_page()!=-1 && Notebook::get().get_current_view()==view) view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); } } @@ -430,8 +420,8 @@ void Project::Clang::debug_show_variables() { debug_variable_tooltips.hide(); return; } - if(notebook.get_current_page()!=-1) { - auto view=notebook.get_current_view(); + if(Notebook::get().get_current_page()!=-1) { + auto view=Notebook::get().get_current_view(); debug_variable_tooltips.clear(); auto create_tooltip_buffer=[this, rows, view, selected]() { auto variable=rows->at(selected); @@ -462,7 +452,7 @@ void Project::Clang::debug_show_variables() { } void Project::Clang::debug_run_command(const std::string &command) { - if(Project::get().debugging) { + if(debugging) { auto command_return=Debug::get().run_command(command); Terminal::get().async_print(command_return.first); Terminal::get().async_print(command_return.second, true); @@ -498,7 +488,7 @@ void Project::Markdown::compile_and_run() { } std::stringstream stdin_stream, stdout_stream; - auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "markdown "+notebook.get_current_view()->file_path.string()); + auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "markdown "+Notebook::get().get_current_view()->file_path.string()); if(exit_status==0) { boost::system::error_code ec; auto temp_path=boost::filesystem::temp_directory_path(ec); @@ -528,23 +518,23 @@ void Project::Markdown::compile_and_run() { } void Project::Python::compile_and_run() { - auto command="python "+notebook.get_current_view()->file_path.string(); + auto command="python "+Notebook::get().get_current_view()->file_path.string(); Terminal::get().print("Running "+command+"\n"); - Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) { + Terminal::get().async_process(command, Notebook::get().get_current_view()->file_path.parent_path(), [command](int exit_status) { Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); }); } void Project::JavaScript::compile_and_run() { - auto command="node "+notebook.get_current_view()->file_path.string(); + auto command="node "+Notebook::get().get_current_view()->file_path.string(); Terminal::get().print("Running "+command+"\n"); - Terminal::get().async_process(command, notebook.get_current_view()->file_path.parent_path(), [command](int exit_status) { + Terminal::get().async_process(command, Notebook::get().get_current_view()->file_path.parent_path(), [command](int exit_status) { Terminal::get().async_print(command+" returned: "+std::to_string(exit_status)+'\n'); }); } void Project::HTML::compile_and_run() { - auto uri=notebook.get_current_view()->file_path.string(); + auto uri=Notebook::get().get_current_view()->file_path.string(); #ifdef __APPLE__ Terminal::get().process("open \""+uri+"\""); #else diff --git a/src/project.h b/src/project.h index 5370e2d..02476bb 100644 --- a/src/project.h +++ b/src/project.h @@ -2,43 +2,31 @@ #define JUCI_PROJECT_H_ #include -#include "notebook.h" #include "cmake.h" #include #include "directories.h" #include #include #include "tooltips.h" +#include "dispatcher.h" +#include class Project { private: - boost::filesystem::path debug_last_stop_file_path; - std::string debug_status; - std::mutex debug_status_mutex; - Glib::Dispatcher debug_update_status; - - Project(); - Notebook ¬ebook; //convenience reference + static boost::filesystem::path debug_last_stop_file_path; public: - static Project &get() { - static Project singleton; - return singleton; - } - - Gtk::Label debug_status_label; - std::pair > debug_stop; - std::mutex debug_stop_mutex; - Glib::Dispatcher debug_update_stop; - std::unordered_map run_arguments; - std::unordered_map debug_run_arguments; - std::atomic compiling; - std::atomic debugging; + static std::unordered_map run_arguments; + static std::unordered_map debug_run_arguments; + static std::atomic compiling; + static std::atomic debugging; + static std::pair > debug_stop; + static void debug_update_stop(); + static std::unique_ptr debug_status_label; + static void debug_update_status(const std::string &debug_status); class Language { - protected: - Notebook ¬ebook; //convenience reference public: - Language() : notebook(Notebook::get()) {} + Language() {} virtual ~Language() {} virtual std::pair get_run_arguments() {return {"", ""};} @@ -63,8 +51,11 @@ public: }; class Clang : public Language { + private: + Dispatcher dispatcher; public: Clang() : Language() {} + ~Clang() { dispatcher.disconnect(); } std::unique_ptr get_cmake(); @@ -121,7 +112,7 @@ public: void compile_and_run() override; }; - std::unique_ptr get_language(); + static std::unique_ptr get_language(); }; #endif // JUCI_PROJECT_H_ diff --git a/src/terminal.cc b/src/terminal.cc index 3738356..f3da34a 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -7,9 +7,6 @@ #endif Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) { - waiting_print.connect([this](){ - Terminal::get().async_print(line_nr-1, "."); - }); start(start_msg); } @@ -24,8 +21,11 @@ void Terminal::InProgress::start(const std::string& msg) { wait_thread=std::thread([this](){ size_t c=0; while(!stop) { - if(c%100==0) - waiting_print(); + if(c%100==0) { + dispatcher.add([this] { + Terminal::get().print(line_nr-1, "."); + }); + } std::this_thread::sleep_for(std::chrono::milliseconds(10)); c++; } @@ -35,39 +35,24 @@ void Terminal::InProgress::start(const std::string& msg) { void Terminal::InProgress::done(const std::string& msg) { if(!stop) { stop=true; - Terminal::get().async_print(line_nr-1, msg); + dispatcher.add([this, msg] { + Terminal::get().print(line_nr-1, msg); + }); } } void Terminal::InProgress::cancel(const std::string& msg) { if(!stop) { stop=true; - Terminal::get().async_print(line_nr-1, msg); + dispatcher.add([this, msg] { + Terminal::get().print(line_nr-1, msg); + }); } } Terminal::Terminal() { bold_tag=get_buffer()->create_tag(); bold_tag->property_weight()=PANGO_WEIGHT_BOLD; - - async_print_dispatcher.connect([this](){ - async_print_strings_mutex.lock(); - if(async_print_strings.size()>0) { - for(auto &string_bold: async_print_strings) - print(string_bold.first, string_bold.second); - async_print_strings.clear(); - } - async_print_strings_mutex.unlock(); - }); - async_print_on_line_dispatcher.connect([this](){ - async_print_on_line_strings_mutex.lock(); - if(async_print_on_line_strings.size()>0) { - for(auto &line_string: async_print_on_line_strings) - print(line_string.first, line_string.second); - async_print_on_line_strings.clear(); - } - async_print_on_line_strings_mutex.unlock(); - }); } int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) { @@ -251,25 +236,9 @@ std::shared_ptr Terminal::print_in_progress(std::string st } void Terminal::async_print(const std::string &message, bool bold) { - async_print_strings_mutex.lock(); - bool dispatch=true; - if(async_print_strings.size()>0) - dispatch=false; - async_print_strings.emplace_back(message, bold); - async_print_strings_mutex.unlock(); - if(dispatch) - async_print_dispatcher(); -} - -void Terminal::async_print(int line_nr, const std::string &message) { - async_print_on_line_strings_mutex.lock(); - bool dispatch=true; - if(async_print_on_line_strings.size()>0) - dispatch=false; - async_print_on_line_strings.emplace_back(line_nr, message); - async_print_on_line_strings_mutex.unlock(); - if(dispatch) - async_print_on_line_dispatcher(); + dispatcher.add([this, message, bold] { + Terminal::get().print(message, bold); + }); } bool Terminal::on_key_press_event(GdkEventKey *event) { diff --git a/src/terminal.h b/src/terminal.h index 5137510..fca6ec0 100644 --- a/src/terminal.h +++ b/src/terminal.h @@ -9,6 +9,7 @@ #include #include #include "process.hpp" +#include "dispatcher.h" class Terminal : public Gtk::TextView { public: @@ -22,7 +23,8 @@ public: void start(const std::string& msg); size_t line_nr; std::atomic stop; - Glib::Dispatcher waiting_print; + Dispatcher dispatcher; + std::thread wait_thread; }; @@ -44,16 +46,10 @@ public: void print(size_t line_nr, const std::string &message); std::shared_ptr print_in_progress(std::string start_msg); void async_print(const std::string &message, bool bold=false); - void async_print(int line_nr, const std::string &message); protected: bool on_key_press_event(GdkEventKey *event); private: - Glib::Dispatcher async_print_dispatcher; - Glib::Dispatcher async_print_on_line_dispatcher; - std::vector > async_print_strings; - std::vector > async_print_on_line_strings; - std::mutex async_print_strings_mutex; - std::mutex async_print_on_line_strings_mutex; + Dispatcher dispatcher; Glib::RefPtr bold_tag; std::vector > processes; diff --git a/src/window.cc b/src/window.cc index 1c208c5..9ca1113 100644 --- a/src/window.cc +++ b/src/window.cc @@ -25,7 +25,11 @@ Window::Window() : notebook(Notebook::get()) { JDEBUG("start"); set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK); + + Project::debug_status_label=std::unique_ptr(new Gtk::Label()); + set_menu_actions(); + configure(); set_default_size(Config::get().window.default_size.first, Config::get().window.default_size.second); @@ -46,11 +50,12 @@ Window::Window() : notebook(Notebook::get()) { terminal_vbox.pack_start(terminal_scrolled_window); info_and_status_hbox.pack_start(notebook.info, Gtk::PACK_SHRINK); + #if GTK_VERSION_GE(3, 12) - info_and_status_hbox.set_center_widget(Project::get().debug_status_label); + info_and_status_hbox.set_center_widget(*Project::debug_status_label); #else Project::get().debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); - info_and_status_hbox.pack_start(Project::get().debug_status_label); + info_and_status_hbox.pack_start(*Project::debug_status_label); #endif info_and_status_hbox.pack_end(notebook.status, Gtk::PACK_SHRINK); terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); @@ -504,7 +509,7 @@ void Window::set_menu_actions() { }); menu.add_action("project_set_run_arguments", [this]() { - auto project_language=Project::get().get_language(); + auto project_language=Project::get_language(); auto run_arguments=std::make_shared >(project_language->get_run_arguments()); if(run_arguments->second.empty()) return; @@ -517,7 +522,7 @@ void Window::set_menu_actions() { }; label_it->update(0, ""); entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ - Project::get().run_arguments[run_arguments->first]=content; + Project::run_arguments[run_arguments->first]=content; entry_box.hide(); }, 50); auto entry_it=entry_box.entries.begin(); @@ -528,23 +533,23 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("compile_and_run", [this]() { - if(Project::get().compiling) + if(Project::compiling) return; if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project_language=Project::get().get_language(); + project_language=Project::get_language(); project_language->compile_and_run(); }); menu.add_action("compile", [this]() { - if(Project::get().compiling) + if(Project::compiling) return; if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project_language=Project::get().get_language(); + project_language=Project::get_language(); project_language->compile(); }); @@ -585,7 +590,7 @@ void Window::set_menu_actions() { #ifdef JUCI_ENABLE_DEBUG menu.add_action("debug_set_run_arguments", [this]() { - auto project_language=Project::get().get_language(); + auto project_language=Project::get_language(); auto run_arguments=std::make_shared >(project_language->debug_get_run_arguments()); if(run_arguments->second.empty()) return; @@ -598,7 +603,7 @@ void Window::set_menu_actions() { }; label_it->update(0, ""); entry_box.entries.emplace_back(run_arguments->second, [this, run_arguments](const std::string& content){ - Project::get().debug_run_arguments[run_arguments->first]=content; + Project::debug_run_arguments[run_arguments->first]=content; entry_box.hide(); }, 50); auto entry_it=entry_box.entries.begin(); @@ -609,7 +614,7 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("debug_start_continue", [this](){ - if(Project::get().debugging) { + if(Project::debugging) { project_language->debug_continue(); return; } @@ -617,7 +622,7 @@ void Window::set_menu_actions() { if(Config::get().window.save_on_compile_or_run) notebook.save_project_files(); - project_language=Project::get().get_language(); + project_language=Project::get_language(); project_language->debug_start(); }); @@ -687,18 +692,14 @@ void Window::set_menu_actions() { } }); menu.add_action("debug_goto_stop", [this](){ - if(Project::get().debugging) { - auto &project=Project::get(); - project.debug_stop_mutex.lock(); - auto debug_stop_copy=project.debug_stop; - project.debug_stop_mutex.unlock(); - if(!debug_stop_copy.first.empty()) { - notebook.open(debug_stop_copy.first); + if(Project::debugging) { + if(!Project::debug_stop.first.empty()) { + notebook.open(Project::debug_stop.first); if(notebook.get_current_page()!=-1) { auto view=notebook.get_current_view(); - int line_nr=debug_stop_copy.second.first-1; - int line_index=debug_stop_copy.second.second-1; + int line_nr=Project::debug_stop.second.first-1; + int line_index=Project::debug_stop.second.second-1; if(line_nrget_buffer()->get_line_count()) { auto iter=view->get_buffer()->get_iter_at_line(line_nr); auto end_line_iter=iter; @@ -713,11 +714,13 @@ void Window::set_menu_actions() { if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); } - project.debug_update_stop(); + Project::debug_update_stop(); } } } }); + + Project::debug_update_status(""); #endif menu.add_action("next_tab", [this]() { From 9fe43c185a4bb3ec6fdd6621b689b543698b2d02 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 19:59:48 +0100 Subject: [PATCH 14/41] Minor cleanup of Terminal --- src/terminal.cc | 51 ++++++++++++++++++++++--------------------------- src/terminal.h | 3 +-- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/terminal.cc b/src/terminal.cc index f3da34a..0ca760e 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -21,11 +21,8 @@ void Terminal::InProgress::start(const std::string& msg) { wait_thread=std::thread([this](){ size_t c=0; while(!stop) { - if(c%100==0) { - dispatcher.add([this] { - Terminal::get().print(line_nr-1, "."); - }); - } + if(c%100==0) + Terminal::get().async_print(line_nr-1, "."); std::this_thread::sleep_for(std::chrono::milliseconds(10)); c++; } @@ -35,18 +32,14 @@ void Terminal::InProgress::start(const std::string& msg) { void Terminal::InProgress::done(const std::string& msg) { if(!stop) { stop=true; - dispatcher.add([this, msg] { - Terminal::get().print(line_nr-1, msg); - }); + Terminal::get().async_print(line_nr-1, msg); } } void Terminal::InProgress::cancel(const std::string& msg) { if(!stop) { stop=true; - dispatcher.add([this, msg] { - Terminal::get().print(line_nr-1, msg); - }); + Terminal::get().async_print(line_nr-1, msg); } } @@ -213,23 +206,6 @@ size_t Terminal::print(const std::string &message, bool bold){ return static_cast(get_buffer()->end().get_line())+deleted_lines; } -void Terminal::print(size_t line_nr, const std::string &message){ - if(line_nrget_iter_at_line(static_cast(line_nr-deleted_lines)); - while(!end_line_iter.ends_line() && end_line_iter.forward_char()) {} - get_buffer()->insert(end_line_iter, umessage); -} - std::shared_ptr Terminal::print_in_progress(std::string start_msg) { std::shared_ptr in_progress=std::shared_ptr(new Terminal::InProgress(start_msg)); return in_progress; @@ -241,6 +217,25 @@ void Terminal::async_print(const std::string &message, bool bold) { }); } +void Terminal::async_print(size_t line_nr, const std::string &message) { + dispatcher.add([this, line_nr, message] { + if(line_nrget_iter_at_line(static_cast(line_nr-deleted_lines)); + while(!end_line_iter.ends_line() && end_line_iter.forward_char()) {} + get_buffer()->insert(end_line_iter, umessage); + }); +} + bool Terminal::on_key_press_event(GdkEventKey *event) { processes_mutex.lock(); bool debug_is_running=false; diff --git a/src/terminal.h b/src/terminal.h index fca6ec0..dd74ad9 100644 --- a/src/terminal.h +++ b/src/terminal.h @@ -23,7 +23,6 @@ public: void start(const std::string& msg); size_t line_nr; std::atomic stop; - Dispatcher dispatcher; std::thread wait_thread; }; @@ -43,9 +42,9 @@ public: void kill_async_processes(bool force=false); size_t print(const std::string &message, bool bold=false); - void print(size_t line_nr, const std::string &message); std::shared_ptr print_in_progress(std::string start_msg); void async_print(const std::string &message, bool bold=false); + void async_print(size_t line_nr, const std::string &message); protected: bool on_key_press_event(GdkEventKey *event); private: From 29f8ef56132592e771e9623d85cfc8216e0d6188 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 20:04:31 +0100 Subject: [PATCH 15/41] Minor fix for older gtk versions --- src/window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.cc b/src/window.cc index 9ca1113..4891ec9 100644 --- a/src/window.cc +++ b/src/window.cc @@ -54,7 +54,7 @@ Window::Window() : notebook(Notebook::get()) { #if GTK_VERSION_GE(3, 12) info_and_status_hbox.set_center_widget(*Project::debug_status_label); #else - Project::get().debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); + Project::debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); info_and_status_hbox.pack_start(*Project::debug_status_label); #endif info_and_status_hbox.pack_end(notebook.status, Gtk::PACK_SHRINK); From 9be5c1bcf8bac8318b290696caa46507642f497a Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 20:08:06 +0100 Subject: [PATCH 16/41] Yet another minor fix for older gtk versions --- src/window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.cc b/src/window.cc index 4891ec9..c9ced70 100644 --- a/src/window.cc +++ b/src/window.cc @@ -54,7 +54,7 @@ Window::Window() : notebook(Notebook::get()) { #if GTK_VERSION_GE(3, 12) info_and_status_hbox.set_center_widget(*Project::debug_status_label); #else - Project::debug_status_label.set_halign(Gtk::Align::ALIGN_CENTER); + Project::debug_status_label->set_halign(Gtk::Align::ALIGN_CENTER); info_and_status_hbox.pack_start(*Project::debug_status_label); #endif info_and_status_hbox.pack_end(notebook.status, Gtk::PACK_SHRINK); From 111028956db3e5fef83c884fe31cfa01625e67b4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 20:42:04 +0100 Subject: [PATCH 17/41] Made debug_label static also --- src/project.cc | 7 +++---- src/project.h | 6 +++++- src/window.cc | 8 +++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/project.cc b/src/project.cc index a28352f..d718951 100644 --- a/src/project.cc +++ b/src/project.cc @@ -15,11 +15,10 @@ std::atomic Project::compiling; std::atomic Project::debugging; std::pair > Project::debug_stop; boost::filesystem::path Project::debug_last_stop_file_path; -std::unique_ptr Project::debug_status_label; void Project::debug_update_status(const std::string &debug_status) { if(debug_status.empty()) { - debug_status_label->set_text(""); + debug_status_label().set_text(""); auto &menu=Menu::get(); menu.actions["debug_stop"]->set_enabled(false); menu.actions["debug_kill"]->set_enabled(false); @@ -32,7 +31,7 @@ void Project::debug_update_status(const std::string &debug_status) { menu.actions["debug_goto_stop"]->set_enabled(false); } else { - debug_status_label->set_text("debug: "+debug_status); + debug_status_label().set_text("debug: "+debug_status); auto &menu=Menu::get(); menu.actions["debug_stop"]->set_enabled(); menu.actions["debug_kill"]->set_enabled(); @@ -279,7 +278,7 @@ void Project::Clang::debug_start() { dispatcher.add([this, status] { debug_update_status(status); }); - }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { + }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { dispatcher.add([this, file_path, line_nr, line_index] { Project::debug_stop.first=file_path; Project::debug_stop.second.first=line_nr; diff --git a/src/project.h b/src/project.h index 02476bb..d255bee 100644 --- a/src/project.h +++ b/src/project.h @@ -21,9 +21,13 @@ public: static std::atomic debugging; static std::pair > debug_stop; static void debug_update_stop(); - static std::unique_ptr debug_status_label; static void debug_update_status(const std::string &debug_status); + static Gtk::Label &debug_status_label() { + static Gtk::Label label; + return label; + } + class Language { public: Language() {} diff --git a/src/window.cc b/src/window.cc index c9ced70..78ac55b 100644 --- a/src/window.cc +++ b/src/window.cc @@ -26,8 +26,6 @@ Window::Window() : notebook(Notebook::get()) { set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK); - Project::debug_status_label=std::unique_ptr(new Gtk::Label()); - set_menu_actions(); configure(); @@ -52,10 +50,10 @@ Window::Window() : notebook(Notebook::get()) { info_and_status_hbox.pack_start(notebook.info, Gtk::PACK_SHRINK); #if GTK_VERSION_GE(3, 12) - info_and_status_hbox.set_center_widget(*Project::debug_status_label); + info_and_status_hbox.set_center_widget(Project::debug_status_label()); #else - Project::debug_status_label->set_halign(Gtk::Align::ALIGN_CENTER); - info_and_status_hbox.pack_start(*Project::debug_status_label); + Project::debug_status_label().set_halign(Gtk::Align::ALIGN_CENTER); + info_and_status_hbox.pack_start(Project::debug_status_label()); #endif info_and_status_hbox.pack_end(notebook.status, Gtk::PACK_SHRINK); terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); From 7ab2211f45a8444423861076884720998e13d144 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 20:54:14 +0100 Subject: [PATCH 18/41] Fixed crash when trying to debug and compile at the same time --- src/project.cc | 1 - src/window.cc | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/project.cc b/src/project.cc index d718951..2bd9dcb 100644 --- a/src/project.cc +++ b/src/project.cc @@ -286,7 +286,6 @@ void Project::Clang::debug_start() { debug_update_stop(); }); - }); debug_start_mutex.unlock(); } diff --git a/src/window.cc b/src/window.cc index 78ac55b..eab641a 100644 --- a/src/window.cc +++ b/src/window.cc @@ -531,7 +531,7 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("compile_and_run", [this]() { - if(Project::compiling) + if(Project::compiling || Project::debugging) return; if(Config::get().window.save_on_compile_or_run) @@ -541,7 +541,7 @@ void Window::set_menu_actions() { project_language->compile_and_run(); }); menu.add_action("compile", [this]() { - if(Project::compiling) + if(Project::compiling || Project::debugging) return; if(Config::get().window.save_on_compile_or_run) @@ -612,7 +612,9 @@ void Window::set_menu_actions() { entry_box.show(); }); menu.add_action("debug_start_continue", [this](){ - if(Project::debugging) { + if(Project::compiling) + return; + else if(Project::debugging) { project_language->debug_continue(); return; } From 7722e7eee5fae41f0faa5ed46b402c12a81ee1dc Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 23:09:10 +0100 Subject: [PATCH 19/41] Dispatcher cleanup --- src/directories.cc | 26 +++--- src/directories.h | 3 +- src/source_clang.cc | 202 ++++++++++++++++++++------------------------ src/source_clang.h | 19 +---- 4 files changed, 110 insertions(+), 140 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index 7301030..977e3f7 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -77,17 +77,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { child->set_value(column_record.color, rgba); } }); - - update_dispatcher.connect([this](){ - update_mutex.lock(); - for(auto &path: update_paths) { - if(last_write_times.count(path)>0) - add_path(path, last_write_times.at(path).first); - } - update_paths.clear(); - update_mutex.unlock(); - }); - + update_thread=std::thread([this](){ while(!stop_update_thread) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); @@ -105,8 +95,17 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { else it=last_write_times.erase(it); } - if(update_paths.size()>0) - update_dispatcher(); + if(update_paths.size()>0) { + dispatcher.add([this] { + update_mutex.lock(); + for(auto &path: update_paths) { + if(last_write_times.count(path)>0) + add_path(path, last_write_times.at(path).first); + } + update_paths.clear(); + update_mutex.unlock(); + }); + } } update_mutex.unlock(); } @@ -116,6 +115,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { Directories::~Directories() { stop_update_thread=true; update_thread.join(); + dispatcher.disconnect(); } void Directories::open(const boost::filesystem::path& dir_path) { diff --git a/src/directories.h b/src/directories.h index 9314605..5e5e374 100644 --- a/src/directories.h +++ b/src/directories.h @@ -9,6 +9,7 @@ #include #include #include +#include "dispatcher.h" class Directories : public Gtk::TreeView { public: @@ -51,7 +52,7 @@ private: std::mutex update_mutex; std::thread update_thread; std::atomic stop_update_thread; - Glib::Dispatcher update_dispatcher; + Dispatcher dispatcher; std::vector update_paths; }; diff --git a/src/source_clang.cc b/src/source_clang.cc index 7c6e12d..27345ca 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -35,36 +35,6 @@ Source::View(file_path, project_path, language) { configure(); parsing_in_progress=Terminal::get().print_in_progress("Parsing "+file_path.string()); - //GTK-calls must happen in main thread, so the parse_thread - //sends signals to the main thread that it is to call the following functions: - parse_preprocess_connection=parse_preprocess.connect([this]{ - auto expected=ParseProcessState::PREPROCESSING; - if(parse_mutex.try_lock()) { - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) - parse_thread_buffer=get_buffer()->get_text(); - parse_mutex.unlock(); - } - else - parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING); - }); - parse_postprocess_connection=parse_postprocess.connect([this](){ - if(parse_mutex.try_lock()) { - auto expected=ParseProcessState::POSTPROCESSING; - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { - update_syntax(); - update_diagnostics(); - parsed=true; - set_status(""); - } - parse_mutex.unlock(); - } - }); - parse_error_connection=parse_error.connect([this](){ - Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); - set_status(""); - set_info(""); - parsing_in_progress->cancel("failed"); - }); parse_initialize(); get_buffer()->signal_changed().connect([this]() { @@ -140,8 +110,18 @@ void Source::ClangViewParse::parse_initialize() { if(parse_state!=ParseState::PROCESSING) break; auto expected=ParseProcessState::STARTING; - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) - parse_preprocess(); + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { + dispatcher.add([this] { + auto expected=ParseProcessState::PREPROCESSING; + if(parse_mutex.try_lock()) { + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) + parse_thread_buffer=get_buffer()->get_text(); + parse_mutex.unlock(); + } + else + parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING); + }); + } else if (parse_process_state==ParseProcessState::PROCESSING && parse_mutex.try_lock()) { auto status=clang_tu->ReparseTranslationUnit(parse_thread_buffer.raw()); parsing_in_progress->done("done"); @@ -150,7 +130,18 @@ void Source::ClangViewParse::parse_initialize() { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); parse_mutex.unlock(); - parse_postprocess(); + dispatcher.add([this] { + if(parse_mutex.try_lock()) { + auto expected=ParseProcessState::POSTPROCESSING; + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { + update_syntax(); + update_diagnostics(); + parsed=true; + set_status(""); + } + parse_mutex.unlock(); + } + }); } else parse_mutex.unlock(); @@ -158,7 +149,12 @@ void Source::ClangViewParse::parse_initialize() { else { parse_state=ParseState::STOP; parse_mutex.unlock(); - parse_error(); + dispatcher.add([this] { + Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); + set_status(""); + set_info(""); + parsing_in_progress->cancel("failed"); + }); } } } @@ -713,70 +709,11 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_state(Au return false; }); - autocomplete_done_connection=autocomplete_done.connect([this](){ - if(autocomplete_state==AutocompleteState::CANCELED) { - set_status(""); - soft_reparse(); - autocomplete_state=AutocompleteState::IDLE; - } - else if(autocomplete_state==AutocompleteState::RESTARTING) { - set_status(""); - soft_reparse(); - autocomplete_state=AutocompleteState::IDLE; - autocomplete_restart(); - } - else { - autocomplete_dialog_setup(); - - for (auto &data : autocomplete_data) { - std::string row; - std::string return_value; - for (auto &chunk : data.chunks) { - if(chunk.kind==clang::CompletionChunk_ResultType) - return_value=chunk.chunk; - else if(chunk.kind!=clang::CompletionChunk_Informative) - row+=chunk.chunk; - } - data.chunks.clear(); - if (!row.empty()) { - auto row_insert_on_selection=row; - if(!return_value.empty()) - row+=" --> " + return_value; - autocomplete_dialog_rows[row] = std::pair(std::move(row_insert_on_selection), std::move(data.brief_comments)); - autocomplete_dialog->add_row(row); - } - } - autocomplete_data.clear(); - set_status(""); - autocomplete_state=AutocompleteState::IDLE; - if (!autocomplete_dialog_rows.empty()) { - get_source_buffer()->begin_user_action(); - autocomplete_dialog->show(); - } - else - soft_reparse(); - } - }); - - autocomplete_restart_connection=autocomplete_restart.connect([this]() { - autocomplete_check(); - }); - autocomplete_error_connection=autocomplete_error.connect([this]() { - Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); - autocomplete_state=AutocompleteState::CANCELED; - full_reparse(); - }); - - do_delete_object_connection=do_delete_object.connect([this](){ + do_delete_object.connect([this](){ if(delete_thread.joinable()) delete_thread.join(); - do_delete_object_connection.disconnect(); delete this; }); - do_full_reparse.connect([this](){ - parse_initialize(); - full_reparse_running=false; - }); } bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { @@ -847,7 +784,7 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { //new autocomplete after for instance when selecting "std::" auto iter=get_buffer()->get_insert()->get_iter(); if(iter.backward_char() && *iter==':') - autocomplete_restart(); + autocomplete_check(); } } }; @@ -918,8 +855,6 @@ void Source::ClangViewAutocomplete::autocomplete() { autocomplete_state=AutocompleteState::STARTING; - autocomplete_data.clear(); - set_status("autocomplete..."); if(autocomplete_thread.joinable()) autocomplete_thread.join(); @@ -938,12 +873,62 @@ void Source::ClangViewAutocomplete::autocomplete() { parse_mutex.lock(); if(parse_state==ParseState::PROCESSING) { parse_process_state=ParseProcessState::IDLE; - autocomplete_data=autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr); + auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); + + if(parse_state==ParseState::PROCESSING) + dispatcher.add([this, autocomplete_data] { + if(autocomplete_state==AutocompleteState::CANCELED) { + set_status(""); + soft_reparse(); + autocomplete_state=AutocompleteState::IDLE; + } + else if(autocomplete_state==AutocompleteState::RESTARTING) { + set_status(""); + soft_reparse(); + autocomplete_state=AutocompleteState::IDLE; + dispatcher.add([this] { + autocomplete_check(); + }); + } + else { + autocomplete_dialog_setup(); + + for (auto &data : *autocomplete_data) { + std::string row; + std::string return_value; + for (auto &chunk : data.chunks) { + if(chunk.kind==clang::CompletionChunk_ResultType) + return_value=chunk.chunk; + else if(chunk.kind!=clang::CompletionChunk_Informative) + row+=chunk.chunk; + } + data.chunks.clear(); + if (!row.empty()) { + auto row_insert_on_selection=row; + if(!return_value.empty()) + row+=" --> " + return_value; + autocomplete_dialog_rows[row] = std::pair(std::move(row_insert_on_selection), std::move(data.brief_comments)); + autocomplete_dialog->add_row(row); + } + } + set_status(""); + autocomplete_state=AutocompleteState::IDLE; + if (!autocomplete_dialog_rows.empty()) { + get_source_buffer()->begin_user_action(); + autocomplete_dialog->show(); + } + else + soft_reparse(); + } + }); + else { + dispatcher.add([this] { + Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); + autocomplete_state=AutocompleteState::CANCELED; + full_reparse(); + }); + } } - if(parse_state==ParseState::PROCESSING) - autocomplete_done(); - else - autocomplete_error(); parse_mutex.unlock(); }); } @@ -1017,7 +1002,10 @@ bool Source::ClangViewAutocomplete::full_reparse() { parse_thread.join(); if(autocomplete_thread.joinable()) autocomplete_thread.join(); - do_full_reparse(); + dispatcher.add([this] { + parse_initialize(); + full_reparse_running=false; + }); }); return true; } @@ -1479,14 +1467,8 @@ Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boo } void Source::ClangView::async_delete() { + dispatcher.disconnect(); delayed_reparse_connection.disconnect(); - parse_postprocess_connection.disconnect(); - parse_preprocess_connection.disconnect(); - parse_error_connection.disconnect(); - autocomplete_done_connection.disconnect(); - autocomplete_restart_connection.disconnect(); - autocomplete_error_connection.disconnect(); - do_restart_parse_connection.disconnect(); delayed_tag_similar_tokens_connection.disconnect(); ClangViewAutocomplete::async_delete(); } diff --git a/src/source_clang.h b/src/source_clang.h index 93b226d..cda1cbe 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -9,6 +9,7 @@ #include "clangmm.h" #include "source.h" #include "terminal.h" +#include "dispatcher.h" namespace Source { class ClangViewParse : public View { @@ -25,11 +26,13 @@ namespace Source { }; ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + ~ClangViewParse() { dispatcher.disconnect(); } void configure() override; void soft_reparse() override; protected: + Dispatcher dispatcher; void parse_initialize(); std::unique_ptr clang_tu; std::unique_ptr clang_tokens; @@ -53,13 +56,7 @@ namespace Source { std::mutex parse_mutex; std::atomic parse_state; std::atomic parse_process_state; - sigc::connection parse_preprocess_connection; - sigc::connection parse_postprocess_connection; - sigc::connection parse_error_connection; private: - Glib::Dispatcher parse_preprocess; - Glib::Dispatcher parse_postprocess; - Glib::Dispatcher parse_error; Glib::ustring parse_thread_buffer; void update_syntax(); @@ -90,29 +87,19 @@ namespace Source { bool on_key_press_event(GdkEventKey* key) override; std::thread autocomplete_thread; - sigc::connection autocomplete_done_connection; - sigc::connection autocomplete_restart_connection; - sigc::connection autocomplete_error_connection; - sigc::connection do_delete_object_connection; - sigc::connection do_restart_parse_connection; private: std::atomic autocomplete_state; void autocomplete_dialog_setup(); void autocomplete_check(); void autocomplete(); - std::vector autocomplete_data; std::unordered_map > autocomplete_dialog_rows; std::vector autocomplete_get_suggestions(const std::string &buffer, int line_number, int column); Tooltips autocomplete_tooltips; - Glib::Dispatcher autocomplete_done; - Glib::Dispatcher autocomplete_restart; - Glib::Dispatcher autocomplete_error; guint last_keyval=0; std::string prefix; std::mutex prefix_mutex; Glib::Dispatcher do_delete_object; - Glib::Dispatcher do_full_reparse; std::thread delete_thread; std::thread full_reparse_thread; bool full_reparse_running=false; From 3718aac5b3643a0c56fe1a426aa1f12e943c231d Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 23:20:27 +0100 Subject: [PATCH 20/41] Minor autocomplete revert fix --- src/source_clang.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 27345ca..1d42086 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -875,7 +875,7 @@ void Source::ClangViewAutocomplete::autocomplete() { parse_process_state=ParseProcessState::IDLE; auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); - if(parse_state==ParseState::PROCESSING) + if(parse_state==ParseState::PROCESSING) { dispatcher.add([this, autocomplete_data] { if(autocomplete_state==AutocompleteState::CANCELED) { set_status(""); @@ -911,6 +911,7 @@ void Source::ClangViewAutocomplete::autocomplete() { autocomplete_dialog->add_row(row); } } + autocomplete_data->clear(); set_status(""); autocomplete_state=AutocompleteState::IDLE; if (!autocomplete_dialog_rows.empty()) { @@ -921,6 +922,7 @@ void Source::ClangViewAutocomplete::autocomplete() { soft_reparse(); } }); + } else { dispatcher.add([this] { Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); From 48c4ac141f7fa7a1e1d966b620a6b6d970e7bb87 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 23:25:56 +0100 Subject: [PATCH 21/41] Fixed autocomplete freeze within the new dispatch system --- src/source_clang.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 1d42086..9eeeaaa 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -886,9 +886,7 @@ void Source::ClangViewAutocomplete::autocomplete() { set_status(""); soft_reparse(); autocomplete_state=AutocompleteState::IDLE; - dispatcher.add([this] { - autocomplete_check(); - }); + autocomplete_check(); } else { autocomplete_dialog_setup(); From f71acaf7737bf2b667293a08cdefd962ef39812e Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 23:33:06 +0100 Subject: [PATCH 22/41] Removed redundant Dispatcher::disconnect --- src/source_clang.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/source_clang.h b/src/source_clang.h index cda1cbe..c29d863 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -26,7 +26,6 @@ namespace Source { }; ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); - ~ClangViewParse() { dispatcher.disconnect(); } void configure() override; From 26b5cab268c05e39e308ae2128340cf3e4a4962e Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 15 Feb 2016 08:17:34 +0100 Subject: [PATCH 23/41] Dispatcher cleanup --- src/directories.cc | 2 +- src/dispatcher.cc | 2 +- src/dispatcher.h | 2 +- src/project.cc | 4 ++-- src/source_clang.cc | 12 ++++++------ src/terminal.cc | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index 977e3f7..20c8041 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -96,7 +96,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { it=last_write_times.erase(it); } if(update_paths.size()>0) { - dispatcher.add([this] { + dispatcher.push([this] { update_mutex.lock(); for(auto &path: update_paths) { if(last_write_times.count(path)>0) diff --git a/src/dispatcher.cc b/src/dispatcher.cc index 4a1d80c..bc862f2 100644 --- a/src/dispatcher.cc +++ b/src/dispatcher.cc @@ -18,7 +18,7 @@ Dispatcher::~Dispatcher() { functions_mutex.unlock(); } -void Dispatcher::add(std::function function) { +void Dispatcher::push(std::function &&function) { functions_mutex.lock(); functions.emplace_back(function); functions_mutex.unlock(); diff --git a/src/dispatcher.h b/src/dispatcher.h index 70312f1..5a326e4 100644 --- a/src/dispatcher.h +++ b/src/dispatcher.h @@ -13,7 +13,7 @@ private: public: Dispatcher(); ~Dispatcher(); - void add(std::function function); + void push(std::function &&function); void disconnect(); }; diff --git a/src/project.cc b/src/project.cc index 2bd9dcb..306fbbc 100644 --- a/src/project.cc +++ b/src/project.cc @@ -275,11 +275,11 @@ void Project::Clang::debug_start() { debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); }, [this](const std::string &status) { - dispatcher.add([this, status] { + dispatcher.push([this, status] { debug_update_status(status); }); }, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { - dispatcher.add([this, file_path, line_nr, line_index] { + dispatcher.push([this, file_path, line_nr, line_index] { Project::debug_stop.first=file_path; Project::debug_stop.second.first=line_nr; Project::debug_stop.second.second=line_index; diff --git a/src/source_clang.cc b/src/source_clang.cc index 9eeeaaa..5ccd484 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -111,7 +111,7 @@ void Source::ClangViewParse::parse_initialize() { break; auto expected=ParseProcessState::STARTING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { - dispatcher.add([this] { + dispatcher.push([this] { auto expected=ParseProcessState::PREPROCESSING; if(parse_mutex.try_lock()) { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) @@ -130,7 +130,7 @@ void Source::ClangViewParse::parse_initialize() { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); parse_mutex.unlock(); - dispatcher.add([this] { + dispatcher.push([this] { if(parse_mutex.try_lock()) { auto expected=ParseProcessState::POSTPROCESSING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { @@ -149,7 +149,7 @@ void Source::ClangViewParse::parse_initialize() { else { parse_state=ParseState::STOP; parse_mutex.unlock(); - dispatcher.add([this] { + dispatcher.push([this] { Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); set_status(""); set_info(""); @@ -876,7 +876,7 @@ void Source::ClangViewAutocomplete::autocomplete() { auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); if(parse_state==ParseState::PROCESSING) { - dispatcher.add([this, autocomplete_data] { + dispatcher.push([this, autocomplete_data] { if(autocomplete_state==AutocompleteState::CANCELED) { set_status(""); soft_reparse(); @@ -922,7 +922,7 @@ void Source::ClangViewAutocomplete::autocomplete() { }); } else { - dispatcher.add([this] { + dispatcher.push([this] { Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); autocomplete_state=AutocompleteState::CANCELED; full_reparse(); @@ -1002,7 +1002,7 @@ bool Source::ClangViewAutocomplete::full_reparse() { parse_thread.join(); if(autocomplete_thread.joinable()) autocomplete_thread.join(); - dispatcher.add([this] { + dispatcher.push([this] { parse_initialize(); full_reparse_running=false; }); diff --git a/src/terminal.cc b/src/terminal.cc index 0ca760e..66dd536 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -212,13 +212,13 @@ std::shared_ptr Terminal::print_in_progress(std::string st } void Terminal::async_print(const std::string &message, bool bold) { - dispatcher.add([this, message, bold] { + dispatcher.push([this, message, bold] { Terminal::get().print(message, bold); }); } void Terminal::async_print(size_t line_nr, const std::string &message) { - dispatcher.add([this, line_nr, message] { + dispatcher.push([this, line_nr, message] { if(line_nr Date: Mon, 15 Feb 2016 09:01:13 +0100 Subject: [PATCH 24/41] Moved project configs to Config::project --- src/cmake.cc | 10 +++++----- src/config.cc | 14 +++++++------- src/config.h | 11 ++++++++--- src/project.cc | 6 +++--- src/window.cc | 6 +++--- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index f5d1260..cff8f1b 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -36,7 +36,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 default_build_path=Config::get().terminal.default_build_path; + boost::filesystem::path default_build_path=Config::get().project.default_build_path; const std::string path_variable_project_directory_name=""; size_t pos=0; @@ -56,7 +56,7 @@ boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::p } boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::path &project_path) { - boost::filesystem::path debug_build_path=Config::get().terminal.debug_build_path; + boost::filesystem::path debug_build_path=Config::get().project.debug_build_path; const std::string path_variable_project_directory_name=""; size_t pos=0; @@ -72,7 +72,7 @@ boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::pat const std::string path_variable_default_build_path=""; pos=0; debug_build_path_string=debug_build_path.string(); - auto default_build_path=Config::get().terminal.default_build_path; + auto default_build_path=Config::get().project.default_build_path; while((pos=debug_build_path_string.find(path_variable_default_build_path, pos))!=std::string::npos) { debug_build_path_string.replace(pos, path_variable_default_build_path.size(), default_build_path); pos+=default_build_path.size(); @@ -112,7 +112,7 @@ bool CMake::create_default_build(const boost::filesystem::path &project_path, bo auto compile_commands_path=default_build_path/"compile_commands.json"; Dialog::Message message("Creating/updating default build"); - auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ + auto exit_status=Terminal::get().process(Config::get().project.cmake_command+" "+ filesystem::escape_argument(project_path)+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path); message.hide(); if(exit_status==EXIT_SUCCESS) { @@ -162,7 +162,7 @@ bool CMake::create_debug_build(const boost::filesystem::path &project_path) { std::unique_ptr message; message=std::unique_ptr(new Dialog::Message("Creating/updating debug build")); - auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ + auto exit_status=Terminal::get().process(Config::get().project.cmake_command+" "+ filesystem::escape_argument(project_path)+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path); if(message) message->hide(); diff --git a/src/config.cc b/src/config.cc index 1d79e39..23ab06b 100644 --- a/src/config.cc +++ b/src/config.cc @@ -84,15 +84,15 @@ void Config::retrieve_config() { window.theme_variant=cfg.get("gtk_theme.variant"); window.version = cfg.get("version"); window.default_size = {cfg.get("default_window_size.width"), cfg.get("default_window_size.height")}; - window.save_on_compile_or_run=cfg.get("project.save_on_compile_or_run"); - terminal.default_build_path=cfg.get("project.default_build_path"); - terminal.debug_build_path=cfg.get("project.debug_build_path"); - terminal.make_command=cfg.get("project.make_command"); - terminal.cmake_command=cfg.get("project.cmake_command"); - terminal.history_size=cfg.get("terminal_history_size"); + project.save_on_compile_or_run=cfg.get("project.save_on_compile_or_run"); + project.default_build_path=cfg.get("project.default_build_path"); + project.debug_build_path=cfg.get("project.debug_build_path"); + project.make_command=cfg.get("project.make_command"); + project.cmake_command=cfg.get("project.cmake_command"); - terminal.clang_format_command=cfg.get("project.clang_format_command", "clang-format"); + terminal.history_size=cfg.get("terminal_history_size"); + terminal.clang_format_command="clang-format"; #ifdef __linux if(terminal.clang_format_command=="clang-format" && !boost::filesystem::exists("/usr/bin/clang-format") && !boost::filesystem::exists("/usr/local/bin/clang-format")) { diff --git a/src/config.h b/src/config.h index 7e6069b..e7ce328 100644 --- a/src/config.h +++ b/src/config.h @@ -20,17 +20,21 @@ public: std::string theme_variant; std::string version; std::pair default_size; - bool save_on_compile_or_run; }; class Terminal { + public: + std::string clang_format_command; + int history_size; + }; + + class Project { public: std::string default_build_path; std::string debug_build_path; std::string cmake_command; std::string make_command; - std::string clang_format_command; - int history_size; + bool save_on_compile_or_run; }; class Source { @@ -74,6 +78,7 @@ public: Menu menu; Window window; Terminal terminal; + Project project; Source source; const boost::filesystem::path& juci_home_path() const { return home; } diff --git a/src/project.cc b/src/project.cc index 306fbbc..e5f5cdb 100644 --- a/src/project.cc +++ b/src/project.cc @@ -141,7 +141,7 @@ void Project::Clang::compile() { return; compiling=true; Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status) { + Terminal::get().async_process(Config::get().project.make_command, default_build_path, [this](int exit_status) { compiling=false; }); } @@ -178,7 +178,7 @@ void Project::Clang::compile_and_run() { compiling=true; Terminal::get().print("Compiling and running "+arguments+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){ + Terminal::get().async_process(Config::get().project.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){ compiling=false; if(exit_status==EXIT_SUCCESS) { Terminal::get().async_process(arguments, default_build_path, [this, arguments](int exit_status){ @@ -266,7 +266,7 @@ void Project::Clang::debug_start() { debugging=true; Terminal::get().print("Compiling and debugging "+run_arguments+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path](int exit_status){ + Terminal::get().async_process(Config::get().project.make_command, debug_build_path, [this, breakpoints, run_arguments, debug_build_path](int exit_status){ if(exit_status!=EXIT_SUCCESS) debugging=false; else { diff --git a/src/window.cc b/src/window.cc index eab641a..9857b1f 100644 --- a/src/window.cc +++ b/src/window.cc @@ -534,7 +534,7 @@ void Window::set_menu_actions() { if(Project::compiling || Project::debugging) return; - if(Config::get().window.save_on_compile_or_run) + if(Config::get().project.save_on_compile_or_run) notebook.save_project_files(); project_language=Project::get_language(); @@ -544,7 +544,7 @@ void Window::set_menu_actions() { if(Project::compiling || Project::debugging) return; - if(Config::get().window.save_on_compile_or_run) + if(Config::get().project.save_on_compile_or_run) notebook.save_project_files(); project_language=Project::get_language(); @@ -619,7 +619,7 @@ void Window::set_menu_actions() { return; } - if(Config::get().window.save_on_compile_or_run) + if(Config::get().project.save_on_compile_or_run) notebook.save_project_files(); project_language=Project::get_language(); From f1bfcb44022b81ddf3d1aa5c5d2cbc70546b3e1b Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 15 Feb 2016 09:09:46 +0100 Subject: [PATCH 25/41] Renamed debug/Debug to debug_clang/DebugClang --- src/CMakeLists.txt | 2 +- src/{debug.cc => debug_clang.cc} | 48 ++++++++++++++++---------------- src/{debug.h => debug_clang.h} | 12 ++++---- src/project.cc | 36 ++++++++++++------------ src/source_clang.cc | 8 +++--- src/terminal.cc | 6 ++-- 6 files changed, 56 insertions(+), 56 deletions(-) rename src/{debug.cc => debug_clang.cc} (92%) rename src/{debug.h => debug_clang.h} (93%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff2e207..6ec044c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,7 +107,7 @@ set(source_files juci.h ../tiny-process-library/process.cpp) if(LIBLLDB_FOUND) - list(APPEND source_files debug.h debug.cc) + list(APPEND source_files debug_clang.h debug_clang.cc) endif() if(MSYS) diff --git a/src/debug.cc b/src/debug_clang.cc similarity index 92% rename from src/debug.cc rename to src/debug_clang.cc index 6289da1..565eddf 100644 --- a/src/debug.cc +++ b/src/debug_clang.cc @@ -1,4 +1,4 @@ -#include "debug.h" +#include "debug_clang.h" #include #ifdef __APPLE__ #include @@ -27,7 +27,7 @@ void log(const char *msg, void *) { std::cout << "debugger log: " << msg << std::endl; } -Debug::Debug(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { +DebugClang::DebugClang(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { #ifdef __APPLE__ auto debugserver_path=boost::filesystem::path("/usr/local/opt/llvm/bin/debugserver"); if(boost::filesystem::exists(debugserver_path)) @@ -35,7 +35,7 @@ Debug::Debug(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { #endif } -void Debug::start(const std::string &command, const boost::filesystem::path &path, +void DebugClang::start(const std::string &command, const boost::filesystem::path &path, const std::vector > &breakpoints, std::function callback, std::function status_callback, @@ -214,14 +214,14 @@ void Debug::start(const std::string &command, const boost::filesystem::path &pat }); } -void Debug::continue_debug() { +void DebugClang::continue_debug() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) process->Continue(); event_mutex.unlock(); } -void Debug::stop() { +void DebugClang::stop() { event_mutex.lock(); if(state==lldb::StateType::eStateRunning) { auto error=process->Stop(); @@ -231,7 +231,7 @@ void Debug::stop() { event_mutex.unlock(); } -void Debug::kill() { +void DebugClang::kill() { event_mutex.lock(); if(process) { auto error=process->Kill(); @@ -241,7 +241,7 @@ void Debug::kill() { event_mutex.unlock(); } -void Debug::step_over() { +void DebugClang::step_over() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOver(); @@ -249,7 +249,7 @@ void Debug::step_over() { event_mutex.unlock(); } -void Debug::step_into() { +void DebugClang::step_into() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepInto(); @@ -257,7 +257,7 @@ void Debug::step_into() { event_mutex.unlock(); } -void Debug::step_out() { +void DebugClang::step_out() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOut(); @@ -265,7 +265,7 @@ void Debug::step_out() { event_mutex.unlock(); } -std::pair Debug::run_command(const std::string &command) { +std::pair DebugClang::run_command(const std::string &command) { std::pair command_return; event_mutex.lock(); if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) { @@ -278,7 +278,7 @@ std::pair Debug::run_command(const std::string &comman return command_return; } -std::vector Debug::get_backtrace() { +std::vector DebugClang::get_backtrace() { std::vector backtrace; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { @@ -315,8 +315,8 @@ std::vector Debug::get_backtrace() { return backtrace; } -std::vector Debug::get_variables() { - std::vector variables; +std::vector DebugClang::get_variables() { + std::vector variables; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { for(uint32_t c_t=0;c_tGetNumThreads();c_t++) { @@ -330,7 +330,7 @@ std::vector Debug::get_variables() { auto declaration=value.GetDeclaration(); if(declaration.IsValid()) { - Debug::Variable variable; + DebugClang::Variable variable; variable.thread_index_id=thread.GetIndexID(); variable.frame_index=c_f; @@ -359,7 +359,7 @@ std::vector Debug::get_variables() { return variables; } -void Debug::select_frame(uint32_t frame_index, uint32_t thread_index_id) { +void DebugClang::select_frame(uint32_t frame_index, uint32_t thread_index_id) { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { if(thread_index_id!=0) @@ -369,13 +369,13 @@ void Debug::select_frame(uint32_t frame_index, uint32_t thread_index_id) { event_mutex.unlock(); } -void Debug::delete_debug() { +void DebugClang::delete_debug() { kill(); if(debug_thread.joinable()) debug_thread.join(); } -std::string Debug::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { +std::string DebugClang::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string variable_value; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { @@ -417,7 +417,7 @@ std::string Debug::get_value(const std::string &variable, const boost::filesyste return variable_value; } -std::string Debug::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { +std::string DebugClang::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string return_value; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { @@ -441,7 +441,7 @@ std::string Debug::get_return_value(const boost::filesystem::path &file_path, un return return_value; } -bool Debug::is_invalid() { +bool DebugClang::is_invalid() { bool invalid; event_mutex.lock(); invalid=state==lldb::StateType::eStateInvalid; @@ -449,7 +449,7 @@ bool Debug::is_invalid() { return invalid; } -bool Debug::is_stopped() { +bool DebugClang::is_stopped() { bool stopped; event_mutex.lock(); stopped=state==lldb::StateType::eStateStopped; @@ -457,7 +457,7 @@ bool Debug::is_stopped() { return stopped; } -bool Debug::is_running() { +bool DebugClang::is_running() { bool running; event_mutex.lock(); running=state==lldb::StateType::eStateRunning; @@ -465,7 +465,7 @@ bool Debug::is_running() { return running; } -void Debug::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { +void DebugClang::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { event_mutex.lock(); if(state==lldb::eStateStopped || state==lldb::eStateRunning) { if(!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid()) @@ -474,7 +474,7 @@ void Debug::add_breakpoint(const boost::filesystem::path &file_path, int line_nr event_mutex.unlock(); } -void Debug::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { +void DebugClang::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { event_mutex.lock(); if(state==lldb::eStateStopped || state==lldb::eStateRunning) { auto target=process->GetTarget(); @@ -501,7 +501,7 @@ void Debug::remove_breakpoint(const boost::filesystem::path &file_path, int line event_mutex.unlock(); } -void Debug::write(const std::string &buffer) { +void DebugClang::write(const std::string &buffer) { event_mutex.lock(); if(state==lldb::StateType::eStateRunning) { process->PutSTDIN(buffer.c_str(), buffer.size()); diff --git a/src/debug.h b/src/debug_clang.h similarity index 93% rename from src/debug.h rename to src/debug_clang.h index 2d4471d..57c1008 100644 --- a/src/debug.h +++ b/src/debug_clang.h @@ -1,5 +1,5 @@ -#ifndef JUCI_DEBUG_H_ -#define JUCI_DEBUG_H_ +#ifndef JUCI_DEBUG_CLANG_H_ +#define JUCI_DEBUG_CLANG_H_ #include #include @@ -9,7 +9,7 @@ #include #include -class Debug { +class DebugClang { public: class Frame { public: @@ -31,10 +31,10 @@ public: int line_index; }; private: - Debug(); + DebugClang(); public: - static Debug &get() { - static Debug singleton; + static DebugClang &get() { + static DebugClang singleton; return singleton; } diff --git a/src/project.cc b/src/project.cc index e5f5cdb..8d631df 100644 --- a/src/project.cc +++ b/src/project.cc @@ -6,7 +6,7 @@ #include "menu.h" #include "notebook.h" #ifdef JUCI_ENABLE_DEBUG -#include "debug.h" +#include "debug_clang.h" #endif std::unordered_map Project::run_arguments; @@ -271,7 +271,7 @@ void Project::Clang::debug_start() { debugging=false; else { debug_start_mutex.lock(); - Debug::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ + DebugClang::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); }, [this](const std::string &status) { @@ -293,42 +293,42 @@ void Project::Clang::debug_start() { } void Project::Clang::debug_continue() { - Debug::get().continue_debug(); + DebugClang::get().continue_debug(); } void Project::Clang::debug_stop() { if(debugging) - Debug::get().stop(); + DebugClang::get().stop(); } void Project::Clang::debug_kill() { if(debugging) - Debug::get().kill(); + DebugClang::get().kill(); } void Project::Clang::debug_step_over() { if(debugging) - Debug::get().step_over(); + DebugClang::get().step_over(); } void Project::Clang::debug_step_into() { if(debugging) - Debug::get().step_into(); + DebugClang::get().step_into(); } void Project::Clang::debug_step_out() { if(debugging) - Debug::get().step_out(); + DebugClang::get().step_out(); } void Project::Clang::debug_backtrace() { if(debugging && Notebook::get().get_current_page()!=-1) { - auto backtrace=Debug::get().get_backtrace(); + auto backtrace=DebugClang::get().get_backtrace(); auto view=Notebook::get().get_current_view(); auto iter=view->get_iter_for_dialog(); view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); + auto rows=std::make_shared >(); if(backtrace.size()==0) return; @@ -356,7 +356,7 @@ void Project::Clang::debug_backtrace() { if(Notebook::get().get_current_page()!=-1) { auto view=Notebook::get().get_current_view(); - Debug::get().select_frame(frame.index); + DebugClang::get().select_frame(frame.index); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(frame.line_nr-1, frame.line_index-1)); @@ -373,12 +373,12 @@ void Project::Clang::debug_backtrace() { void Project::Clang::debug_show_variables() { if(debugging && Notebook::get().get_current_page()!=-1) { - auto variables=Debug::get().get_variables(); + auto variables=DebugClang::get().get_variables(); auto view=Notebook::get().get_current_view(); auto iter=view->get_iter_for_dialog(); view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); + auto rows=std::make_shared >(); if(variables.size()==0) return; @@ -396,7 +396,7 @@ void Project::Clang::debug_show_variables() { if(Notebook::get().get_current_page()!=-1) { auto view=Notebook::get().get_current_view(); - Debug::get().select_frame(variable.frame_index, variable.thread_index_id); + DebugClang::get().select_frame(variable.frame_index, variable.thread_index_id); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(variable.line_nr-1, variable.line_index-1)); @@ -451,23 +451,23 @@ void Project::Clang::debug_show_variables() { void Project::Clang::debug_run_command(const std::string &command) { if(debugging) { - auto command_return=Debug::get().run_command(command); + auto command_return=DebugClang::get().run_command(command); Terminal::get().async_print(command_return.first); Terminal::get().async_print(command_return.second, true); } } void Project::Clang::debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { - Debug::get().add_breakpoint(file_path, line_nr); + DebugClang::get().add_breakpoint(file_path, line_nr); } void Project::Clang::debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { - Debug::get().remove_breakpoint(file_path, line_nr, line_count); + DebugClang::get().remove_breakpoint(file_path, line_nr, line_count); } void Project::Clang::debug_delete() { debug_start_mutex.lock(); - Debug::get().delete_debug(); + DebugClang::get().delete_debug(); debug_start_mutex.unlock(); } #endif diff --git a/src/source_clang.cc b/src/source_clang.cc index 5ccd484..97365b6 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -3,7 +3,7 @@ #include "terminal.h" #include "cmake.h" #ifdef JUCI_ENABLE_DEBUG -#include "debug.h" +#include "debug_clang.h" #endif namespace sigc { @@ -414,15 +414,15 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), "\n\n"+brief_comment, "def:note"); #ifdef JUCI_ENABLE_DEBUG - if(Debug::get().is_stopped()) { + if(DebugClang::get().is_stopped()) { auto location=token.get_cursor().get_referenced().get_source_location(); Glib::ustring value_type="Value"; - Glib::ustring debug_value=Debug::get().get_value(token.get_spelling(), location.get_path(), location.get_offset().line, location.get_offset().index); + Glib::ustring debug_value=DebugClang::get().get_value(token.get_spelling(), location.get_path(), location.get_offset().line, location.get_offset().index); if(debug_value.empty()) { value_type="Return value"; auto cursor=token.get_cursor(); auto offsets=cursor.get_source_range().get_offsets(); - debug_value=Debug::get().get_return_value(cursor.get_source_location().get_path(), offsets.first.line, offsets.first.index); + debug_value=DebugClang::get().get_return_value(cursor.get_source_location().get_path(), offsets.first.line, offsets.first.index); } if(!debug_value.empty()) { size_t pos=debug_value.find(" = "); diff --git a/src/terminal.cc b/src/terminal.cc index 66dd536..7ed75f9 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -3,7 +3,7 @@ #include "logging.h" #include "config.h" #ifdef JUCI_ENABLE_DEBUG -#include "debug.h" +#include "debug_clang.h" #endif Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) { @@ -240,7 +240,7 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { processes_mutex.lock(); bool debug_is_running=false; #ifdef JUCI_ENABLE_DEBUG - debug_is_running=Debug::get().is_running(); + debug_is_running=DebugClang::get().is_running(); #endif if(processes.size()>0 || debug_is_running) { get_buffer()->place_cursor(get_buffer()->end()); @@ -262,7 +262,7 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { stdin_buffer+='\n'; if(debug_is_running) { #ifdef JUCI_ENABLE_DEBUG - Debug::get().write(stdin_buffer); + DebugClang::get().write(stdin_buffer); #endif } else From a717fe7b39bebb9a150c3259b3e71f4894ff13f2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 15 Feb 2016 09:36:59 +0100 Subject: [PATCH 26/41] Removed hard DebugClang dependency in Terminal --- src/project.cc | 10 +++++++++ src/project.h | 5 +++++ src/terminal.cc | 8 +++---- src/window.cc | 60 ++++++++++++++++++++++++------------------------- src/window.h | 2 -- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/project.cc b/src/project.cc index 8d631df..8b2a945 100644 --- a/src/project.cc +++ b/src/project.cc @@ -16,6 +16,8 @@ std::atomic Project::debugging; std::pair > Project::debug_stop; boost::filesystem::path Project::debug_last_stop_file_path; +std::unique_ptr Project::current_language; + void Project::debug_update_status(const std::string &debug_status) { if(debug_status.empty()) { debug_status_label().set_text(""); @@ -465,6 +467,14 @@ void Project::Clang::debug_remove_breakpoint(const boost::filesystem::path &file DebugClang::get().remove_breakpoint(file_path, line_nr, line_count); } +bool Project::Clang::debug_is_running() { + return DebugClang::get().is_running(); +} + +void Project::Clang::debug_write(const std::string &buffer) { + DebugClang::get().write(buffer); +} + void Project::Clang::debug_delete() { debug_start_mutex.lock(); DebugClang::get().delete_debug(); diff --git a/src/project.h b/src/project.h index d255bee..e3f1fc7 100644 --- a/src/project.h +++ b/src/project.h @@ -51,6 +51,8 @@ public: virtual void debug_run_command(const std::string &command) {} virtual void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {} virtual void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {} + virtual bool debug_is_running() { return false; } + virtual void debug_write(const std::string &buffer) {} virtual void debug_delete() {} }; @@ -82,6 +84,8 @@ public: void debug_run_command(const std::string &command) override; void debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) override; void debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) override; + bool debug_is_running() override; + void debug_write(const std::string &buffer) override; void debug_delete() override; #endif }; @@ -117,6 +121,7 @@ public: }; static std::unique_ptr get_language(); + static std::unique_ptr current_language; }; #endif // JUCI_PROJECT_H_ diff --git a/src/terminal.cc b/src/terminal.cc index 7ed75f9..cbd8739 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -2,9 +2,7 @@ #include #include "logging.h" #include "config.h" -#ifdef JUCI_ENABLE_DEBUG -#include "debug_clang.h" -#endif +#include "project.h" Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) { start(start_msg); @@ -240,7 +238,7 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { processes_mutex.lock(); bool debug_is_running=false; #ifdef JUCI_ENABLE_DEBUG - debug_is_running=DebugClang::get().is_running(); + debug_is_running=Project::current_language?Project::current_language->debug_is_running():false; #endif if(processes.size()>0 || debug_is_running) { get_buffer()->place_cursor(get_buffer()->end()); @@ -262,7 +260,7 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { stdin_buffer+='\n'; if(debug_is_running) { #ifdef JUCI_ENABLE_DEBUG - DebugClang::get().write(stdin_buffer); + Project::current_language->debug_write(stdin_buffer); #endif } else diff --git a/src/window.cc b/src/window.cc index 9857b1f..425fad3 100644 --- a/src/window.cc +++ b/src/window.cc @@ -536,9 +536,9 @@ void Window::set_menu_actions() { if(Config::get().project.save_on_compile_or_run) notebook.save_project_files(); - - project_language=Project::get_language(); - project_language->compile_and_run(); + + Project::current_language=Project::get_language(); + Project::current_language->compile_and_run(); }); menu.add_action("compile", [this]() { if(Project::compiling || Project::debugging) @@ -547,8 +547,8 @@ void Window::set_menu_actions() { if(Config::get().project.save_on_compile_or_run) notebook.save_project_files(); - project_language=Project::get_language(); - project_language->compile(); + Project::current_language=Project::get_language(); + Project::current_language->compile(); }); menu.add_action("run_command", [this]() { @@ -615,51 +615,51 @@ void Window::set_menu_actions() { if(Project::compiling) return; else if(Project::debugging) { - project_language->debug_continue(); + Project::current_language->debug_continue(); return; } if(Config::get().project.save_on_compile_or_run) notebook.save_project_files(); - project_language=Project::get_language(); + Project::current_language=Project::get_language(); - project_language->debug_start(); + Project::current_language->debug_start(); }); menu.add_action("debug_stop", [this]() { - if(project_language) - project_language->debug_stop(); + if(Project::current_language) + Project::current_language->debug_stop(); }); menu.add_action("debug_kill", [this]() { - if(project_language) - project_language->debug_kill(); + if(Project::current_language) + Project::current_language->debug_kill(); }); menu.add_action("debug_step_over", [this]() { - if(project_language) - project_language->debug_step_over(); + if(Project::current_language) + Project::current_language->debug_step_over(); }); menu.add_action("debug_step_into", [this]() { - if(project_language) - project_language->debug_step_into(); + if(Project::current_language) + Project::current_language->debug_step_into(); }); menu.add_action("debug_step_out", [this]() { - if(project_language) - project_language->debug_step_out(); + if(Project::current_language) + Project::current_language->debug_step_out(); }); menu.add_action("debug_backtrace", [this]() { - if(project_language) - project_language->debug_backtrace(); + if(Project::current_language) + Project::current_language->debug_backtrace(); }); menu.add_action("debug_show_variables", [this]() { - if(project_language) - project_language->debug_show_variables(); + if(Project::current_language) + Project::current_language->debug_show_variables(); }); menu.add_action("debug_run_command", [this]() { entry_box.clear(); entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){ if(content!="") { - if(project_language) - project_language->debug_run_command(content); + if(Project::current_language) + Project::current_language->debug_run_command(content); last_run_debug_command=content; } entry_box.hide(); @@ -681,13 +681,13 @@ void Window::set_menu_actions() { auto end_iter=start_iter; while(!end_iter.ends_line() && end_iter.forward_char()) {} view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); - if(project_language) - project_language->debug_remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); + if(Project::current_language) + Project::current_language->debug_remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); } else { view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); - if(project_language) - project_language->debug_add_breakpoint(view->file_path, line_nr+1); + if(Project::current_language) + Project::current_language->debug_add_breakpoint(view->file_path, line_nr+1); } } }); @@ -817,8 +817,8 @@ bool Window::on_delete_event(GdkEventAny *event) { } Terminal::get().kill_async_processes(); #ifdef JUCI_ENABLE_DEBUG - if(project_language) - project_language->debug_delete(); + if(Project::current_language) + Project::current_language->debug_delete(); #endif return false; } diff --git a/src/window.h b/src/window.h index 191b592..c2ad3ba 100644 --- a/src/window.h +++ b/src/window.h @@ -32,8 +32,6 @@ private: Gtk::HBox info_and_status_hbox; Gtk::AboutDialog about; EntryBox entry_box; - - std::unique_ptr project_language; void configure(); void set_menu_actions(); From 2770463c091f6550cec4731a77546114c1610b13 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 15 Feb 2016 10:15:38 +0100 Subject: [PATCH 27/41] Renamed DebugClang to Clang in namespace Debug (Debug::Clang) --- src/debug_clang.cc | 46 +++++++-------- src/debug_clang.h | 136 ++++++++++++++++++++++---------------------- src/project.cc | 38 ++++++------- src/source_clang.cc | 6 +- 4 files changed, 114 insertions(+), 112 deletions(-) diff --git a/src/debug_clang.cc b/src/debug_clang.cc index 565eddf..54f0d45 100644 --- a/src/debug_clang.cc +++ b/src/debug_clang.cc @@ -27,7 +27,7 @@ void log(const char *msg, void *) { std::cout << "debugger log: " << msg << std::endl; } -DebugClang::DebugClang(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { +Debug::Clang::Clang(): state(lldb::StateType::eStateInvalid), buffer_size(131072) { #ifdef __APPLE__ auto debugserver_path=boost::filesystem::path("/usr/local/opt/llvm/bin/debugserver"); if(boost::filesystem::exists(debugserver_path)) @@ -35,7 +35,7 @@ DebugClang::DebugClang(): state(lldb::StateType::eStateInvalid), buffer_size(131 #endif } -void DebugClang::start(const std::string &command, const boost::filesystem::path &path, +void Debug::Clang::start(const std::string &command, const boost::filesystem::path &path, const std::vector > &breakpoints, std::function callback, std::function status_callback, @@ -214,14 +214,14 @@ void DebugClang::start(const std::string &command, const boost::filesystem::path }); } -void DebugClang::continue_debug() { +void Debug::Clang::continue_debug() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) process->Continue(); event_mutex.unlock(); } -void DebugClang::stop() { +void Debug::Clang::stop() { event_mutex.lock(); if(state==lldb::StateType::eStateRunning) { auto error=process->Stop(); @@ -231,7 +231,7 @@ void DebugClang::stop() { event_mutex.unlock(); } -void DebugClang::kill() { +void Debug::Clang::kill() { event_mutex.lock(); if(process) { auto error=process->Kill(); @@ -241,7 +241,7 @@ void DebugClang::kill() { event_mutex.unlock(); } -void DebugClang::step_over() { +void Debug::Clang::step_over() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOver(); @@ -249,7 +249,7 @@ void DebugClang::step_over() { event_mutex.unlock(); } -void DebugClang::step_into() { +void Debug::Clang::step_into() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepInto(); @@ -257,7 +257,7 @@ void DebugClang::step_into() { event_mutex.unlock(); } -void DebugClang::step_out() { +void Debug::Clang::step_out() { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOut(); @@ -265,7 +265,7 @@ void DebugClang::step_out() { event_mutex.unlock(); } -std::pair DebugClang::run_command(const std::string &command) { +std::pair Debug::Clang::run_command(const std::string &command) { std::pair command_return; event_mutex.lock(); if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) { @@ -278,7 +278,7 @@ std::pair DebugClang::run_command(const std::string &c return command_return; } -std::vector DebugClang::get_backtrace() { +std::vector Debug::Clang::get_backtrace() { std::vector backtrace; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { @@ -315,8 +315,8 @@ std::vector DebugClang::get_backtrace() { return backtrace; } -std::vector DebugClang::get_variables() { - std::vector variables; +std::vector Debug::Clang::get_variables() { + std::vector variables; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { for(uint32_t c_t=0;c_tGetNumThreads();c_t++) { @@ -330,7 +330,7 @@ std::vector DebugClang::get_variables() { auto declaration=value.GetDeclaration(); if(declaration.IsValid()) { - DebugClang::Variable variable; + Debug::Clang::Variable variable; variable.thread_index_id=thread.GetIndexID(); variable.frame_index=c_f; @@ -359,7 +359,7 @@ std::vector DebugClang::get_variables() { return variables; } -void DebugClang::select_frame(uint32_t frame_index, uint32_t thread_index_id) { +void Debug::Clang::select_frame(uint32_t frame_index, uint32_t thread_index_id) { event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { if(thread_index_id!=0) @@ -369,13 +369,13 @@ void DebugClang::select_frame(uint32_t frame_index, uint32_t thread_index_id) { event_mutex.unlock(); } -void DebugClang::delete_debug() { +void Debug::Clang::delete_debug() { kill(); if(debug_thread.joinable()) debug_thread.join(); } -std::string DebugClang::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { +std::string Debug::Clang::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string variable_value; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { @@ -417,7 +417,7 @@ std::string DebugClang::get_value(const std::string &variable, const boost::file return variable_value; } -std::string DebugClang::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { +std::string Debug::Clang::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string return_value; event_mutex.lock(); if(state==lldb::StateType::eStateStopped) { @@ -441,7 +441,7 @@ std::string DebugClang::get_return_value(const boost::filesystem::path &file_pat return return_value; } -bool DebugClang::is_invalid() { +bool Debug::Clang::is_invalid() { bool invalid; event_mutex.lock(); invalid=state==lldb::StateType::eStateInvalid; @@ -449,7 +449,7 @@ bool DebugClang::is_invalid() { return invalid; } -bool DebugClang::is_stopped() { +bool Debug::Clang::is_stopped() { bool stopped; event_mutex.lock(); stopped=state==lldb::StateType::eStateStopped; @@ -457,7 +457,7 @@ bool DebugClang::is_stopped() { return stopped; } -bool DebugClang::is_running() { +bool Debug::Clang::is_running() { bool running; event_mutex.lock(); running=state==lldb::StateType::eStateRunning; @@ -465,7 +465,7 @@ bool DebugClang::is_running() { return running; } -void DebugClang::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { +void Debug::Clang::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { event_mutex.lock(); if(state==lldb::eStateStopped || state==lldb::eStateRunning) { if(!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid()) @@ -474,7 +474,7 @@ void DebugClang::add_breakpoint(const boost::filesystem::path &file_path, int li event_mutex.unlock(); } -void DebugClang::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { +void Debug::Clang::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { event_mutex.lock(); if(state==lldb::eStateStopped || state==lldb::eStateRunning) { auto target=process->GetTarget(); @@ -501,7 +501,7 @@ void DebugClang::remove_breakpoint(const boost::filesystem::path &file_path, int event_mutex.unlock(); } -void DebugClang::write(const std::string &buffer) { +void Debug::Clang::write(const std::string &buffer) { event_mutex.lock(); if(state==lldb::StateType::eStateRunning) { process->PutSTDIN(buffer.c_str(), buffer.size()); diff --git a/src/debug_clang.h b/src/debug_clang.h index 57c1008..0e9001a 100644 --- a/src/debug_clang.h +++ b/src/debug_clang.h @@ -9,75 +9,77 @@ #include #include -class DebugClang { -public: - class Frame { +namespace Debug { + class Clang { public: - uint32_t index; - std::string module_filename; - std::string file_path; - std::string function_name; - int line_nr; - int line_index; - }; - class Variable { + class Frame { + public: + uint32_t index; + std::string module_filename; + std::string file_path; + std::string function_name; + int line_nr; + int line_index; + }; + class Variable { + public: + uint32_t thread_index_id; + uint32_t frame_index; + std::string name; + std::string value; + boost::filesystem::path file_path; + int line_nr; + int line_index; + }; + private: + Clang(); public: - uint32_t thread_index_id; - uint32_t frame_index; - std::string name; - std::string value; - boost::filesystem::path file_path; - int line_nr; - int line_index; - }; -private: - DebugClang(); -public: - static DebugClang &get() { - static DebugClang singleton; - return singleton; - } - - void start(const std::string &command, const boost::filesystem::path &path="", - const std::vector > &breakpoints={}, - std::function callback=nullptr, - std::function status_callback=nullptr, - std::function stop_callback=nullptr); - void continue_debug(); //can't use continue as function name - void stop(); - void kill(); - void step_over(); - void step_into(); - void step_out(); - std::pair run_command(const std::string &command); - std::vector get_backtrace(); - std::vector get_variables(); - void select_frame(uint32_t frame_index, uint32_t thread_index_id=0); - - void delete_debug(); //can't use delete as function name - - std::string get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index); - std::string get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index); - - bool is_invalid(); - bool is_stopped(); - bool is_running(); - - void add_breakpoint(const boost::filesystem::path &file_path, int line_nr); - void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count); - - void write(const std::string &buffer); + static Clang &get() { + static Clang singleton; + return singleton; + } + + void start(const std::string &command, const boost::filesystem::path &path="", + const std::vector > &breakpoints={}, + std::function callback=nullptr, + std::function status_callback=nullptr, + std::function stop_callback=nullptr); + void continue_debug(); //can't use continue as function name + void stop(); + void kill(); + void step_over(); + void step_into(); + void step_out(); + std::pair run_command(const std::string &command); + std::vector get_backtrace(); + std::vector get_variables(); + void select_frame(uint32_t frame_index, uint32_t thread_index_id=0); + + void delete_debug(); //can't use delete as function name + + std::string get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index); + std::string get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index); -private: - std::unique_ptr debugger; - std::unique_ptr listener; - std::unique_ptr process; - std::thread debug_thread; - - lldb::StateType state; - std::mutex event_mutex; - - size_t buffer_size; -}; + bool is_invalid(); + bool is_stopped(); + bool is_running(); + + void add_breakpoint(const boost::filesystem::path &file_path, int line_nr); + void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count); + + void write(const std::string &buffer); + + private: + std::unique_ptr debugger; + std::unique_ptr listener; + std::unique_ptr process; + std::thread debug_thread; + + lldb::StateType state; + std::mutex event_mutex; + + size_t buffer_size; + }; +} #endif diff --git a/src/project.cc b/src/project.cc index 8b2a945..fea8312 100644 --- a/src/project.cc +++ b/src/project.cc @@ -273,7 +273,7 @@ void Project::Clang::debug_start() { debugging=false; else { debug_start_mutex.lock(); - DebugClang::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ + Debug::Clang::get().start(run_arguments, debug_build_path, *breakpoints, [this, run_arguments](int exit_status){ debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); }, [this](const std::string &status) { @@ -295,42 +295,42 @@ void Project::Clang::debug_start() { } void Project::Clang::debug_continue() { - DebugClang::get().continue_debug(); + Debug::Clang::get().continue_debug(); } void Project::Clang::debug_stop() { if(debugging) - DebugClang::get().stop(); + Debug::Clang::get().stop(); } void Project::Clang::debug_kill() { if(debugging) - DebugClang::get().kill(); + Debug::Clang::get().kill(); } void Project::Clang::debug_step_over() { if(debugging) - DebugClang::get().step_over(); + Debug::Clang::get().step_over(); } void Project::Clang::debug_step_into() { if(debugging) - DebugClang::get().step_into(); + Debug::Clang::get().step_into(); } void Project::Clang::debug_step_out() { if(debugging) - DebugClang::get().step_out(); + Debug::Clang::get().step_out(); } void Project::Clang::debug_backtrace() { if(debugging && Notebook::get().get_current_page()!=-1) { - auto backtrace=DebugClang::get().get_backtrace(); + auto backtrace=Debug::Clang::get().get_backtrace(); auto view=Notebook::get().get_current_view(); auto iter=view->get_iter_for_dialog(); view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); + auto rows=std::make_shared >(); if(backtrace.size()==0) return; @@ -358,7 +358,7 @@ void Project::Clang::debug_backtrace() { if(Notebook::get().get_current_page()!=-1) { auto view=Notebook::get().get_current_view(); - DebugClang::get().select_frame(frame.index); + Debug::Clang::get().select_frame(frame.index); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(frame.line_nr-1, frame.line_index-1)); @@ -375,12 +375,12 @@ void Project::Clang::debug_backtrace() { void Project::Clang::debug_show_variables() { if(debugging && Notebook::get().get_current_page()!=-1) { - auto variables=DebugClang::get().get_variables(); + auto variables=Debug::Clang::get().get_variables(); auto view=Notebook::get().get_current_view(); auto iter=view->get_iter_for_dialog(); view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); - auto rows=std::make_shared >(); + auto rows=std::make_shared >(); if(variables.size()==0) return; @@ -398,7 +398,7 @@ void Project::Clang::debug_show_variables() { if(Notebook::get().get_current_page()!=-1) { auto view=Notebook::get().get_current_view(); - DebugClang::get().select_frame(variable.frame_index, variable.thread_index_id); + Debug::Clang::get().select_frame(variable.frame_index, variable.thread_index_id); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(variable.line_nr-1, variable.line_index-1)); @@ -453,31 +453,31 @@ void Project::Clang::debug_show_variables() { void Project::Clang::debug_run_command(const std::string &command) { if(debugging) { - auto command_return=DebugClang::get().run_command(command); + auto command_return=Debug::Clang::get().run_command(command); Terminal::get().async_print(command_return.first); Terminal::get().async_print(command_return.second, true); } } void Project::Clang::debug_add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { - DebugClang::get().add_breakpoint(file_path, line_nr); + Debug::Clang::get().add_breakpoint(file_path, line_nr); } void Project::Clang::debug_remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { - DebugClang::get().remove_breakpoint(file_path, line_nr, line_count); + Debug::Clang::get().remove_breakpoint(file_path, line_nr, line_count); } bool Project::Clang::debug_is_running() { - return DebugClang::get().is_running(); + return Debug::Clang::get().is_running(); } void Project::Clang::debug_write(const std::string &buffer) { - DebugClang::get().write(buffer); + Debug::Clang::get().write(buffer); } void Project::Clang::debug_delete() { debug_start_mutex.lock(); - DebugClang::get().delete_debug(); + Debug::Clang::get().delete_debug(); debug_start_mutex.unlock(); } #endif diff --git a/src/source_clang.cc b/src/source_clang.cc index 97365b6..3007ef1 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -414,15 +414,15 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), "\n\n"+brief_comment, "def:note"); #ifdef JUCI_ENABLE_DEBUG - if(DebugClang::get().is_stopped()) { + if(Debug::Clang::get().is_stopped()) { auto location=token.get_cursor().get_referenced().get_source_location(); Glib::ustring value_type="Value"; - Glib::ustring debug_value=DebugClang::get().get_value(token.get_spelling(), location.get_path(), location.get_offset().line, location.get_offset().index); + Glib::ustring debug_value=Debug::Clang::get().get_value(token.get_spelling(), location.get_path(), location.get_offset().line, location.get_offset().index); if(debug_value.empty()) { value_type="Return value"; auto cursor=token.get_cursor(); auto offsets=cursor.get_source_range().get_offsets(); - debug_value=DebugClang::get().get_return_value(cursor.get_source_location().get_path(), offsets.first.line, offsets.first.index); + debug_value=Debug::Clang::get().get_return_value(cursor.get_source_location().get_path(), offsets.first.line, offsets.first.index); } if(!debug_value.empty()) { size_t pos=debug_value.find(" = "); From 93b226c64241b7a38f93226ab1fc628bdfed746b Mon Sep 17 00:00:00 2001 From: "U-olece-PC\\olece" Date: Wed, 17 Feb 2016 09:49:04 +0100 Subject: [PATCH 28/41] Got rid of absolute build path variables in MSYS2. juCi++ can now safely be installed through a MSYS2 package --- docs/install.md | 2 +- src/CMakeLists.txt | 4 ---- src/config.cc | 8 ++++++++ src/config.h | 4 ++++ src/files.h | 2 +- src/source_clang.cc | 5 +---- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/install.md b/docs/install.md index cf0744b..256527b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -86,7 +86,7 @@ make install ``` ##Windows with MSYS2 (https://msys2.github.io/) -**MSYS2 does not yet support lldb, but you can still compile juCi++ without debug support. Also for the time being, MSYS2 must be installed in the default MSYS2 folder (C:\msys64 or C:\msys32).** +**MSYS2 does not yet support lldb, but you can still compile juCi++ without debug support.** Note that juCi++ must be run in a MinGW Shell (for instance MinGW-w64 Win64 Shell). diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ec044c..9307767 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,10 +21,6 @@ if(UNIX) #Checking if compiling on Ubuntu that has a buggy menu system endif() endif() -if(MSYS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSYS_PROCESS_USE_SH -DJUCI_CMAKE_INSTALL_PREFIX=\\\"${CMAKE_INSTALL_PREFIX}\\\"") -endif() - INCLUDE(FindPkgConfig) find_package(LibClang REQUIRED) diff --git a/src/config.cc b/src/config.cc index 23ab06b..212ec56 100644 --- a/src/config.cc +++ b/src/config.cc @@ -5,6 +5,7 @@ #include #include "filesystem.h" #include "terminal.h" +#include Config::Config() { std::vector environment_variables = {"JUCI_HOME", "HOME", "AppData"}; @@ -25,6 +26,13 @@ Config::Config() { searched_envs+="]"; throw std::runtime_error("One of these environment variables needs to point to a writable directory to save configuration: " + searched_envs); } + +#ifdef _WIN32 + terminal.msys2_mingw_path=boost::filesystem::path(std::getenv("WD")).parent_path().parent_path().parent_path(); + std::string msystem=std::getenv("MSYSTEM"); + std::transform(msystem.begin(), msystem.end(), msystem.begin(), ::tolower); + terminal.msys2_mingw_path/=msystem; +#endif } void Config::load() { diff --git a/src/config.h b/src/config.h index e7ce328..1add042 100644 --- a/src/config.h +++ b/src/config.h @@ -26,6 +26,10 @@ public: public: std::string clang_format_command; int history_size; + +#ifdef _WIN32 + boost::filesystem::path msys2_mingw_path; +#endif }; class Project { diff --git a/src/files.h b/src/files.h index 75941a1..1a7debb 100644 --- a/src/files.h +++ b/src/files.h @@ -125,7 +125,7 @@ const std::string configjson = " \"debug_build_path_comment\": \"Use to insert the project top level directory name, and to insert your default_build_path setting.\",\n" " \"debug_build_path\": \"/debug\",\n" #ifdef _WIN32 -" \"cmake_command\": \"cmake -G\\\"MSYS Makefiles\\\" -DCMAKE_INSTALL_PREFIX="+JUCI_CMAKE_INSTALL_PREFIX+"\",\n" +" \"cmake_command\": \"cmake -G\\\"MSYS Makefiles\\\"\",\n" #else " \"cmake_command\": \"cmake\",\n" #endif diff --git a/src/source_clang.cc b/src/source_clang.cc index 3007ef1..a8397b6 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -200,10 +200,7 @@ std::vector Source::ClangViewParse::get_compilation_commands() { arguments.emplace_back("-I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1"); //Added for OS X 10.11 #endif #ifdef _WIN32 - arguments.emplace_back("-IC:/msys32/mingw32/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-IC:/msys32/mingw64/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-IC:/msys64/mingw32/lib/clang/"+clang_version+"/include"); - arguments.emplace_back("-IC:/msys64/mingw64/lib/clang/"+clang_version+"/include"); + arguments.emplace_back("-I"+(Config::get().terminal.msys2_mingw_path/"lib/clang"/clang_version/"include").string()); #endif } arguments.emplace_back("-fretain-comments-from-system-headers"); From 47318febd5e82f54963eb9207b786d44cf713343 Mon Sep 17 00:00:00 2001 From: "U-olece-PC\\olece" Date: Wed, 17 Feb 2016 10:07:06 +0100 Subject: [PATCH 29/41] Added NULL check for getenv in MSYS2 --- src/config.cc | 12 ++++++++---- src/source_clang.cc | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/config.cc b/src/config.cc index 212ec56..aa5c7c1 100644 --- a/src/config.cc +++ b/src/config.cc @@ -28,10 +28,14 @@ Config::Config() { } #ifdef _WIN32 - terminal.msys2_mingw_path=boost::filesystem::path(std::getenv("WD")).parent_path().parent_path().parent_path(); - std::string msystem=std::getenv("MSYSTEM"); - std::transform(msystem.begin(), msystem.end(), msystem.begin(), ::tolower); - terminal.msys2_mingw_path/=msystem; + auto env_WD=std::getenv("WD"); + auto env_MSYSTEM=std::getenv("MSYSTEM"); + if(env_WD!=NULL && env_MSYSTEM!=NULL) { + terminal.msys2_mingw_path=boost::filesystem::path(env_WD).parent_path().parent_path().parent_path(); + std::string msystem=env_MSYSTEM; + std::transform(msystem.begin(), msystem.end(), msystem.begin(), ::tolower); + terminal.msys2_mingw_path/=msystem; + } #endif } diff --git a/src/source_clang.cc b/src/source_clang.cc index a8397b6..2130993 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -200,7 +200,8 @@ std::vector Source::ClangViewParse::get_compilation_commands() { arguments.emplace_back("-I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1"); //Added for OS X 10.11 #endif #ifdef _WIN32 - arguments.emplace_back("-I"+(Config::get().terminal.msys2_mingw_path/"lib/clang"/clang_version/"include").string()); + if(!Config::get().terminal.msys2_mingw_path.empty()) + arguments.emplace_back("-I"+(Config::get().terminal.msys2_mingw_path/"lib/clang"/clang_version/"include").string()); #endif } arguments.emplace_back("-fretain-comments-from-system-headers"); From 866f5e76146f82d1d736cdd7fc9a55ad88ead609 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 20 Feb 2016 09:15:27 +0100 Subject: [PATCH 30/41] Minor project cleanup in window.cc --- src/window.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/window.cc b/src/window.cc index 425fad3..76081ff 100644 --- a/src/window.cc +++ b/src/window.cc @@ -681,12 +681,12 @@ void Window::set_menu_actions() { auto end_iter=start_iter; while(!end_iter.ends_line() && end_iter.forward_char()) {} view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); - if(Project::current_language) + if(Project::current_language && Project::debugging) Project::current_language->debug_remove_breakpoint(view->file_path, line_nr+1, view->get_buffer()->get_line_count()+1); } else { view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); - if(Project::current_language) + if(Project::current_language && Project::debugging) Project::current_language->debug_add_breakpoint(view->file_path, line_nr+1); } } From 75cc29def5f9095bdadc04ad727a46279e264921 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 11:08:41 +0100 Subject: [PATCH 31/41] Finally found a way to make the notebook tabs smaller --- src/notebook.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/notebook.cc b/src/notebook.cc index bcd1780..1672311 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -52,6 +52,13 @@ Notebook::TabLabel::TabLabel(const std::string &title) : Gtk::Box(Gtk::ORIENTATI Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { Gsv::init(); + std::string data = ".notebook {\n" + "padding: 4px;\n" + "}"; + auto provider = Gtk::CssProvider::create(); + provider->load_from_data(data); + get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) { last_index=-1; }); From 5cc66d257caa7213d8e89d1c2e2e583b10f5b760 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 12:09:00 +0100 Subject: [PATCH 32/41] More fixes to tabs, solves #161 --- src/notebook.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/notebook.cc b/src/notebook.cc index 1672311..da65512 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -54,6 +54,8 @@ Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { std::string data = ".notebook {\n" "padding: 4px;\n" + "-GtkNotebook-tab-overlap: 0px;\n" + "-GtkNotebook-show-border: 0;\n" "}"; auto provider = Gtk::CssProvider::create(); provider->load_from_data(data); From a8a48a4991cc94b759f7e995ab15de5361d25463 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 12:37:23 +0100 Subject: [PATCH 33/41] Added tab-style exception for Ubuntu --- src/CMakeLists.txt | 4 ++-- src/menu.cc | 2 +- src/notebook.cc | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9307767..07885da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,13 +10,13 @@ if(APPLE) set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig") endif() -if(UNIX) #Checking if compiling on Ubuntu that has a buggy menu system +if(UNIX) #Checking if compiling on Ubuntu that for instance has a buggy menu system find_program(LSB_RELEASE_BIN lsb_release) if(LSB_RELEASE_BIN) execute_process(COMMAND ${LSB_RELEASE_BIN} -is OUTPUT_VARIABLE DISTRIBUTION OUTPUT_STRIP_TRAILING_WHITESPACE) if((DISTRIBUTION STREQUAL Ubuntu) OR (DISTRIBUTION STREQUAL LinuxMint)) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJUCI_UBUNTU_BUGGED_MENU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJUCI_UBUNTU") endif() endif() endif() diff --git a/src/menu.cc b/src/menu.cc index 3627947..e546484 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -7,7 +7,7 @@ Menu::Menu() { auto accels=Config::get().menu.keys; for(auto &accel: accels) { -#ifdef JUCI_UBUNTU_BUGGED_MENU +#ifdef JUCI_UBUNTU size_t pos=0; std::string second=accel.second; while((pos=second.find('<', pos))!=std::string::npos) { diff --git a/src/notebook.cc b/src/notebook.cc index da65512..052a65a 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -52,8 +52,13 @@ Notebook::TabLabel::TabLabel(const std::string &title) : Gtk::Box(Gtk::ORIENTATI Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { Gsv::init(); + //Ubuntu forces its own theme std::string data = ".notebook {\n" +#ifdef JUCI_UBUNTU + "padding: 1px;\n" +#else "padding: 4px;\n" +#endif "-GtkNotebook-tab-overlap: 0px;\n" "-GtkNotebook-show-border: 0;\n" "}"; From 140068f7402a2086158fd63c69f1d58d4c170944 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 13:10:42 +0100 Subject: [PATCH 34/41] Added tree lines to directory view --- src/directories.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/directories.cc b/src/directories.cc index 20c8041..be1d779 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -22,6 +22,8 @@ namespace sigc { } Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { + this->set_enable_tree_lines(true); + tree_store = Gtk::TreeStore::create(column_record); set_model(tree_store); append_column("", column_record.name); From 20a69d15dfaeaa920ab7cbef49f92e8b62858162 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 16:38:55 +0100 Subject: [PATCH 35/41] Improved padding styles --- src/notebook.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 052a65a..753c802 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -32,6 +32,7 @@ Notebook::TabLabel::TabLabel(const std::string &title) : Gtk::Box(Gtk::ORIENTATI button.set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU); button.set_can_focus(false); button.set_relief(Gtk::ReliefStyle::RELIEF_NONE); + //Based on http://www.micahcarrick.com/gtk-notebook-tabs-with-close-button.html std::string data = ".button {\n" "-GtkButton-default-border : 0px;\n" @@ -41,11 +42,17 @@ Notebook::TabLabel::TabLabel(const std::string &title) : Gtk::Box(Gtk::ORIENTATI "-GtkWidget-focus-padding : 0px;\n" "padding: 0px;\n" "}"; - auto provider = Gtk::CssProvider::create(); - provider->load_from_data(data); - button.get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + auto provider_button = Gtk::CssProvider::create(); + provider_button->load_from_data(data); + button.get_style_context()->add_provider(provider_button, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + auto provider_label = Gtk::CssProvider::create(); + provider_label->load_from_data(".label {padding: 7px;}"); + label.get_style_context()->add_provider(provider_label, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + pack_start(label, Gtk::PACK_SHRINK); pack_end(button, Gtk::PACK_SHRINK); + show_all(); } @@ -54,11 +61,7 @@ Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { //Ubuntu forces its own theme std::string data = ".notebook {\n" -#ifdef JUCI_UBUNTU - "padding: 1px;\n" -#else - "padding: 4px;\n" -#endif + "padding: 0px;\n" "-GtkNotebook-tab-overlap: 0px;\n" "-GtkNotebook-show-border: 0;\n" "}"; From 5eda6bf50675460d1bde02574196a3297208218b Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 18:47:28 +0100 Subject: [PATCH 36/41] Further improvements to notebook padding --- src/notebook.cc | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 753c802..70e63a6 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -27,29 +27,17 @@ namespace sigc { Notebook::TabLabel::TabLabel(const std::string &title) : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) { set_can_focus(false); - label.set_text(title); + label.set_text(title+' '); label.set_can_focus(false); button.set_image_from_icon_name("window-close-symbolic", Gtk::ICON_SIZE_MENU); button.set_can_focus(false); button.set_relief(Gtk::ReliefStyle::RELIEF_NONE); //Based on http://www.micahcarrick.com/gtk-notebook-tabs-with-close-button.html - std::string data = ".button {\n" - "-GtkButton-default-border : 0px;\n" - "-GtkButton-default-outside-border : 0px;\n" - "-GtkButton-inner-border: 0px;\n" - "-GtkWidget-focus-line-width : 0px;\n" - "-GtkWidget-focus-padding : 0px;\n" - "padding: 0px;\n" - "}"; - auto provider_button = Gtk::CssProvider::create(); - provider_button->load_from_data(data); - button.get_style_context()->add_provider(provider_button, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - - auto provider_label = Gtk::CssProvider::create(); - provider_label->load_from_data(".label {padding: 7px;}"); - label.get_style_context()->add_provider(provider_label, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - + auto provider = Gtk::CssProvider::create(); + provider->load_from_data(".button {border: 0px; outline-width: 0px; margin: 0px; padding: 0px;}"); + button.get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + pack_start(label, Gtk::PACK_SHRINK); pack_end(button, Gtk::PACK_SHRINK); @@ -60,13 +48,8 @@ Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { Gsv::init(); //Ubuntu forces its own theme - std::string data = ".notebook {\n" - "padding: 0px;\n" - "-GtkNotebook-tab-overlap: 0px;\n" - "-GtkNotebook-show-border: 0;\n" - "}"; auto provider = Gtk::CssProvider::create(); - provider->load_from_data(data); + provider->load_from_data(".notebook {padding: 0px; -GtkNotebook-tab-overlap: 0px;} .notebook tab {padding: 4px;}"); get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) { @@ -183,7 +166,9 @@ void Notebook::open(const boost::filesystem::path &file_path) { get_current_view()->get_buffer()->signal_modified_changed().connect([this, source_view]() { std::string title=source_view->file_path.filename().string(); if(source_view->get_buffer()->get_modified()) - title+="*"; + title+='*'; + else + title+=' '; int page=-1; for(int c=0;c Date: Sun, 21 Feb 2016 19:58:22 +0100 Subject: [PATCH 37/41] Removed a comment --- src/notebook.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/notebook.cc b/src/notebook.cc index 70e63a6..2dc798c 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -47,7 +47,6 @@ Notebook::TabLabel::TabLabel(const std::string &title) : Gtk::Box(Gtk::ORIENTATI Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { Gsv::init(); - //Ubuntu forces its own theme auto provider = Gtk::CssProvider::create(); provider->load_from_data(".notebook {padding: 0px; -GtkNotebook-tab-overlap: 0px;} .notebook tab {padding: 4px;}"); get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); From 5d0f9a19e5388b490e569cebc40358836d37bea5 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 21 Feb 2016 20:55:15 +0100 Subject: [PATCH 38/41] Added rounded top corners on notebook tabs --- src/notebook.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/notebook.cc b/src/notebook.cc index 2dc798c..f973961 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -48,8 +48,9 @@ Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { Gsv::init(); auto provider = Gtk::CssProvider::create(); - provider->load_from_data(".notebook {padding: 0px; -GtkNotebook-tab-overlap: 0px;} .notebook tab {padding: 4px;}"); + provider->load_from_data(".notebook {padding: 0px; -GtkNotebook-tab-overlap: 0px;} .notebook tab {border-radius: 5px;padding: 4px;}"); get_style_context()->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + get_style_context()->set_junction_sides(Gtk::JunctionSides::JUNCTION_BOTTOM); signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) { last_index=-1; From 827c69a425c6d598444da9a6a179fd6bd29920e0 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 22 Feb 2016 09:48:48 +0100 Subject: [PATCH 39/41] Added possibility to modify menus at runtime --- src/juci.cc | 10 +++------- src/menu.cc | 4 ++++ src/menu.h | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/juci.cc b/src/juci.cc index db28c40..14e95a1 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -80,16 +80,12 @@ void Application::on_startup() { Menu::get().build(); - auto object = Menu::get().builder->get_object("juci-menu"); - auto juci_menu = Glib::RefPtr::cast_dynamic(object); - object = Menu::get().builder->get_object("window-menu"); - auto window_menu = Glib::RefPtr::cast_dynamic(object); - if (!juci_menu || !window_menu) { + if (!Menu::get().juci_menu || !Menu::get().window_menu) { std::cerr << "Menu not found." << std::endl; } else { - set_app_menu(juci_menu); - set_menubar(window_menu); + set_app_menu(Menu::get().juci_menu); + set_menubar(Menu::get().window_menu); } } diff --git a/src/menu.cc b/src/menu.cc index e546484..bc00538 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -404,6 +404,10 @@ void Menu::build() { try { builder->add_from_string(ui_xml); + auto object = Menu::get().builder->get_object("juci-menu"); + juci_menu = Glib::RefPtr::cast_dynamic(object); + object = Menu::get().builder->get_object("window-menu"); + window_menu = Glib::RefPtr::cast_dynamic(object); } catch (const Glib::Error &ex) { std::cerr << "building menu failed: " << ex.what(); diff --git a/src/menu.h b/src/menu.h index 1018eeb..9e3fc56 100644 --- a/src/menu.h +++ b/src/menu.h @@ -19,8 +19,12 @@ public: void set_keys(); void build(); - Glib::RefPtr builder; + Glib::RefPtr juci_menu; + Glib::RefPtr window_menu; + +private: + Glib::RefPtr builder; std::string ui_xml; }; #endif // JUCI_MENU_H_ From 52f99efd91ed56823ef8ea22871be12cfb43ef25 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 22 Feb 2016 10:18:45 +0100 Subject: [PATCH 40/41] Fixed autocomplete freeze when clearing a large number of rows --- src/selectiondialog.cc | 5 ----- src/selectiondialog.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/selectiondialog.cc b/src/selectiondialog.cc index 842072e..445f4d1 100644 --- a/src/selectiondialog.cc +++ b/src/selectiondialog.cc @@ -38,10 +38,6 @@ void ListViewText::append(const std::string& value) { new_row->set_value(column_record.text, value); } -void ListViewText::clear() { - list_store->clear(); -} - SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup): text_view(text_view), list_view_text(use_markup), start_mark(start_mark), show_search_entry(show_search_entry) { if(!show_search_entry) @@ -121,7 +117,6 @@ void SelectionDialogBase::hide() { window->hide(); if(on_hide) on_hide(); - list_view_text.clear(); } void SelectionDialogBase::move() { diff --git a/src/selectiondialog.h b/src/selectiondialog.h index 732652f..8223918 100644 --- a/src/selectiondialog.h +++ b/src/selectiondialog.h @@ -17,7 +17,6 @@ public: bool use_markup; ListViewText(bool use_markup); void append(const std::string& value); - void clear(); private: Glib::RefPtr list_store; ColumnRecord column_record; From 1600addd5cbee9b282ed61439b6f8e69604f4ec3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 22 Feb 2016 19:24:18 +0100 Subject: [PATCH 41/41] Simplified Project::debug_update_status as suggested by @zalox --- src/project.cc | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/project.cc b/src/project.cc index fea8312..3b937dd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -19,32 +19,20 @@ boost::filesystem::path Project::debug_last_stop_file_path; std::unique_ptr Project::current_language; void Project::debug_update_status(const std::string &debug_status) { - if(debug_status.empty()) { + if(debug_status.empty()) debug_status_label().set_text(""); - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(false); - menu.actions["debug_kill"]->set_enabled(false); - menu.actions["debug_step_over"]->set_enabled(false); - menu.actions["debug_step_into"]->set_enabled(false); - menu.actions["debug_step_out"]->set_enabled(false); - menu.actions["debug_backtrace"]->set_enabled(false); - menu.actions["debug_show_variables"]->set_enabled(false); - menu.actions["debug_run_command"]->set_enabled(false); - menu.actions["debug_goto_stop"]->set_enabled(false); - } - else { + else debug_status_label().set_text("debug: "+debug_status); - auto &menu=Menu::get(); - menu.actions["debug_stop"]->set_enabled(); - menu.actions["debug_kill"]->set_enabled(); - menu.actions["debug_step_over"]->set_enabled(); - menu.actions["debug_step_into"]->set_enabled(); - menu.actions["debug_step_out"]->set_enabled(); - menu.actions["debug_backtrace"]->set_enabled(); - menu.actions["debug_show_variables"]->set_enabled(); - menu.actions["debug_run_command"]->set_enabled(); - menu.actions["debug_goto_stop"]->set_enabled(); - } + auto &menu=Menu::get(); + menu.actions["debug_stop"]->set_enabled(!debug_status.empty()); + menu.actions["debug_kill"]->set_enabled(!debug_status.empty()); + menu.actions["debug_step_over"]->set_enabled(!debug_status.empty()); + menu.actions["debug_step_into"]->set_enabled(!debug_status.empty()); + menu.actions["debug_step_out"]->set_enabled(!debug_status.empty()); + menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty()); + menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty()); + menu.actions["debug_run_command"]->set_enabled(!debug_status.empty()); + menu.actions["debug_goto_stop"]->set_enabled(!debug_status.empty()); } void Project::debug_update_stop() {