From 606db580d53dd516095016d3fd3a0d1c2889d0d0 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 19 Dec 2015 10:51:39 +0100 Subject: [PATCH 1/9] Fixes #121, #131 and #132. More testing needed, except bugfix commits soon. --- src/cmake.cc | 39 ++++++++++++++++++++++++++++++++++++--- src/cmake.h | 2 ++ src/config.cc | 2 ++ src/config.h | 1 + src/files.h | 4 +++- src/notebook.cc | 2 +- src/source_clang.cc | 3 ++- src/window.cc | 15 +++++++++++---- 8 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 620575f..3665cae 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -33,14 +33,47 @@ CMake::CMake(const boost::filesystem::path &path) { } if(!project_path.empty()) { - if(boost::filesystem::exists(project_path/"CMakeLists.txt") && !boost::filesystem::exists(project_path/"compile_commands.json")) + if(!boost::filesystem::exists(get_default_build_path(project_path)/"compile_commands.json")) create_compile_commands(project_path); } } +boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &path) { + boost::filesystem::path default_build_path=Config::get().terminal.default_build_path; + + const std::string path_variable_project_directory_name=""; + size_t pos=0; + auto default_build_path_string=default_build_path.string(); + auto path_filename_string=path.filename().string(); + while((pos=default_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) { + default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string); + pos+=path_filename_string.size(); + } + if(pos!=0) + default_build_path=default_build_path_string; + + if(default_build_path.is_relative()) + default_build_path=path/default_build_path; + + if(!boost::filesystem::exists(default_build_path)) { + boost::system::error_code ec; + boost::filesystem::create_directories(default_build_path, ec); + if(ec) { + Terminal::get().print("Could not create "+default_build_path.string()+": "+ec.message(), true); + return boost::filesystem::path(); + } + } + + return default_build_path; +} + bool CMake::create_compile_commands(const boost::filesystem::path &path) { - Dialog::Message message("Creating "+path.string()+"/compile_commands.json"); - auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path); + auto default_build_path=get_default_build_path(path); + if(default_build_path.empty()) + return false; + Dialog::Message message("Creating "+default_build_path.string()+"/compile_commands.json"); + auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ + path.string()+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path); message.hide(); if(exit_status==EXIT_SUCCESS) { #ifdef _WIN32 //Temporary fix to MSYS2's libclang diff --git a/src/cmake.h b/src/cmake.h index 8be9d13..e995b23 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -8,6 +8,7 @@ class CMake { public: CMake(const boost::filesystem::path &path); std::vector > > get_functions_parameters(const std::string &name); + static boost::filesystem::path get_default_build_path(const boost::filesystem::path &path); static bool create_compile_commands(const boost::filesystem::path &path); std::vector paths; @@ -15,6 +16,7 @@ public: boost::filesystem::path project_path; std::unordered_map variables; private: + void read_files(); void remove_tabs(); void remove_comments(); diff --git a/src/config.cc b/src/config.cc index 8663e64..aa583fd 100644 --- a/src/config.cc +++ b/src/config.cc @@ -84,6 +84,8 @@ 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")}; + + terminal.default_build_path=cfg.get("project.default_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"); diff --git a/src/config.h b/src/config.h index d86f1d2..6599c3a 100644 --- a/src/config.h +++ b/src/config.h @@ -24,6 +24,7 @@ public: class Terminal { public: + std::string default_build_path; std::string cmake_command; std::string make_command; std::string clang_format_command; diff --git a/src/files.h b/src/files.h index c896e74..1400e0f 100644 --- a/src/files.h +++ b/src/files.h @@ -2,7 +2,7 @@ #define JUCI_FILES_H_ #include -#define JUCI_VERSION "1.0.0" +#define JUCI_VERSION "1.0.1" const std::string configjson = "{\n" @@ -107,6 +107,8 @@ const std::string configjson = " \"close_tab\": \"w\"\n" " },\n" " \"project\": {\n" +" \"default_build_path_comment\": \"Use to insert the project top level directory name\",\n" +" \"default_build_path\": \"./build\",\n" #ifdef _WIN32 " \"cmake_command\": \"cmake -G\\\"MSYS Makefiles\\\" -DCMAKE_INSTALL_PREFIX="+JUCI_CMAKE_INSTALL_PREFIX+"\",\n" #else diff --git a/src/notebook.cc b/src/notebook.cc index 2c62395..0308bc3 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -110,7 +110,7 @@ void Notebook::open(const boost::filesystem::path &file_path) { } } if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { - if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json")) + if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(CMake::get_default_build_path(project_path)/"compile_commands.json")) CMake::create_compile_commands(project_path); source_views.emplace_back(new Source::ClangView(file_path, project_path, language)); } diff --git a/src/source_clang.cc b/src/source_clang.cc index 864f318..10e226e 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1,6 +1,7 @@ #include "source_clang.h" #include "config.h" #include "terminal.h" +#include "cmake.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -178,7 +179,7 @@ void Source::ClangViewParse::soft_reparse() { } std::vector Source::ClangViewParse::get_compilation_commands() { - clang::CompilationDatabase db(project_path.string()); + clang::CompilationDatabase db(CMake::get_default_build_path(project_path).string()); clang::CompileCommands commands(file_path.string(), db); std::vector cmds = commands.get_commands(); std::vector arguments; diff --git a/src/window.cc b/src/window.cc index acc4024..041a164 100644 --- a/src/window.cc +++ b/src/window.cc @@ -540,9 +540,16 @@ void Window::set_menu_actions() { if(cmake.project_path!="") { if(executable_path!="") { compiling=true; - Terminal::get().print("Compiling and running "+executable_path.string()+"\n"); auto project_path=cmake.project_path; - Terminal::get().async_process(Config::get().terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_status){ + auto default_build_path=CMake::get_default_build_path(project_path); + auto executable_path_string=executable_path.string(); + size_t pos=executable_path_string.find(project_path.string()); + if(pos!=std::string::npos) { + executable_path_string.replace(pos, project_path.string().size(), default_build_path.string()); + executable_path=executable_path_string; + } + Terminal::get().print("Compiling and running "+executable_path.string()+"\n"); + Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, executable_path, default_build_path](int exit_status){ compiling=false; if(exit_status==EXIT_SUCCESS) { auto executable_path_spaces_fixed=executable_path.string(); @@ -554,7 +561,7 @@ void Window::set_menu_actions() { } last_char=executable_path_spaces_fixed[c]; } - Terminal::get().async_process(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_status){ + Terminal::get().async_process(executable_path_spaces_fixed, default_build_path, [this, executable_path](int exit_status){ Terminal::get().async_print(executable_path.string()+" returned: "+std::to_string(exit_status)+'\n'); }); } @@ -581,7 +588,7 @@ void Window::set_menu_actions() { if(cmake.project_path!="") { compiling=true; Terminal::get().print("Compiling project "+cmake.project_path.string()+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, cmake.project_path, [this](int exit_status){ + Terminal::get().async_process(Config::get().terminal.make_command, CMake::get_default_build_path(cmake.project_path), [this](int exit_status){ compiling=false; }); } From 1d332bbe6fa856cc002af2b2de782962dad94d71 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 19 Dec 2015 11:32:19 +0100 Subject: [PATCH 2/9] Added cmake cleanup to installation document --- docs/install.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/install.md b/docs/install.md index 1505777..86623d5 100644 --- a/docs/install.md +++ b/docs/install.md @@ -98,6 +98,11 @@ make install Note that we are currently working on a Windows-version without the need of an X-server. --> +## Cleanup CMake cache files (in case you want to try out juCi++ on its source files) +```sh +rm -r CMakeFiles CMakeCache.txt +``` + ## Run ```sh juci From 7cd81a9747a300ea10c01207ee227cc5635fa81a Mon Sep 17 00:00:00 2001 From: "U-ole-PC\\ole" Date: Sat, 19 Dec 2015 12:00:40 +0100 Subject: [PATCH 3/9] Now fixes compile_commands.json on Windows correctly --- src/cmake.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 3665cae..e33bde2 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -71,14 +71,13 @@ bool CMake::create_compile_commands(const boost::filesystem::path &path) { auto default_build_path=get_default_build_path(path); if(default_build_path.empty()) return false; - Dialog::Message message("Creating "+default_build_path.string()+"/compile_commands.json"); + auto compile_commands_path=default_build_path/"compile_commands.json"; + Dialog::Message message("Creating "+compile_commands_path.string()); auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ path.string()+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path); message.hide(); if(exit_status==EXIT_SUCCESS) { #ifdef _WIN32 //Temporary fix to MSYS2's libclang - auto compile_commands_path=path; - compile_commands_path+="/compile_commands.json"; auto compile_commands_file=filesystem::read(compile_commands_path); size_t pos=0; while((pos=compile_commands_file.find("-I/", pos))!=std::string::npos) { From 0dfdf6616a67b397f083760fb70778e0c882854f Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 19 Dec 2015 12:44:18 +0100 Subject: [PATCH 4/9] Updated install docs with respect to default build settings --- docs/install.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/install.md b/docs/install.md index 86623d5..8d2d726 100644 --- a/docs/install.md +++ b/docs/install.md @@ -10,8 +10,9 @@ sudo apt-get install clang-format-3.6 || sudo apt-get install clang-format-3.5 Get juCi++ source, compile and install: ```sh git clone --recursive https://github.com/cppit/jucipp -cd jucipp -cmake . +mkdir jucipp/build +cd jucipp/build +cmake .. make sudo make install ``` @@ -25,8 +26,9 @@ sudo apt-get install git cmake make g++ libclang-3.6-dev clang-format-3.6 pkg-co Get juCi++ source, compile and install: ```sh git clone --recursive https://github.com/cppit/jucipp -cd jucipp -cmake . +mkdir jucipp/build +cd jucipp/build +cmake .. make sudo make install ``` @@ -41,8 +43,9 @@ pacman -S git cmake make clang gtksourceviewmm boost aspell aspell-en Get juCi++ source, compile and install: ```sh git clone --recursive https://github.com/cppit/jucipp -cd jucipp -cmake . +mkdir jucipp/build +cd jucipp/build +cmake .. make # as root make install @@ -57,8 +60,9 @@ brew install cmake --with-clang llvm pkg-config boost homebrew/x11/gtksourceview Get juCi++ source, compile and install: ```sh git clone --recursive https://github.com/cppit/jucipp -cd jucipp -cmake . +mkdir jucipp/build +cd jucipp/build +cmake .. make make install ``` @@ -72,8 +76,9 @@ pacman -S git mingw-w64-x86_64-cmake make mingw-w64-x86_64-toolchain mingw-w64-x Get juCi++ source, compile and install (replace `mingw64` with `mingw32` for 32-bit MSYS2 installs): ```sh git clone --recursive https://github.com/cppit/jucipp -cd jucipp -cmake -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64 . +mkdir jucipp/build +cd jucipp/build +cmake -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64 .. make make install ``` @@ -98,11 +103,6 @@ make install Note that we are currently working on a Windows-version without the need of an X-server. --> -## Cleanup CMake cache files (in case you want to try out juCi++ on its source files) -```sh -rm -r CMakeFiles CMakeCache.txt -``` - ## Run ```sh juci From 7a229a2e64ac6350a9655689cd2957e80319f57f Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Dec 2015 08:23:20 +0100 Subject: [PATCH 5/9] More consistant error messages --- src/cmake.cc | 2 +- src/config.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index e33bde2..51f0b60 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -59,7 +59,7 @@ boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::p boost::system::error_code ec; boost::filesystem::create_directories(default_build_path, ec); if(ec) { - Terminal::get().print("Could not create "+default_build_path.string()+": "+ec.message(), true); + Terminal::get().print("Error: could not create "+default_build_path.string()+": "+ec.message(), true); return boost::filesystem::path(); } } diff --git a/src/config.cc b/src/config.cc index aa583fd..732344f 100644 --- a/src/config.cc +++ b/src/config.cc @@ -36,7 +36,7 @@ void Config::load() { retrieve_config(); } catch(const std::exception &e) { - ::Terminal::get().print("Error reading "+config_json+": "+e.what()+"\n"); + ::Terminal::get().print("Error: could not parse "+config_json+": "+e.what()+"\n", true); std::stringstream ss; ss << configjson; boost::property_tree::read_json(ss, cfg); From 4a6d92c893e7651e3e9014fc69974a90561e9b2f Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Dec 2015 08:28:08 +0100 Subject: [PATCH 6/9] cmake error messages no longer appear twice when saving CMakeLists.txt --- src/notebook.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 0308bc3..f42f022 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -248,14 +248,14 @@ bool Notebook::save(int page) { boost::filesystem::path project_path; if(view->file_path.filename()=="CMakeLists.txt") { auto &directories=Directories::get(); - if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories.cmake->project_path)) { - project_path=directories.cmake->project_path; + if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') { + if(CMake::create_compile_commands(directories.cmake->project_path)) + project_path=directories.cmake->project_path; } else { CMake cmake(view->file_path.parent_path()); - if(cmake.project_path!="" && CMake::create_compile_commands(cmake.project_path)) { + if(cmake.project_path!="" && CMake::create_compile_commands(cmake.project_path)) project_path=cmake.project_path; - } } if(project_path!="") { for(auto source_view: source_views) { From ea0d65e17807247004bc5671b3a89aec77beafbe Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 20 Dec 2015 09:04:25 +0100 Subject: [PATCH 7/9] Fixes #133 --- src/source_clang.cc | 46 +++++++++++++++++++++++++++++++-------------- src/terminal.cc | 6 +++--- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 10e226e..51080ab 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -960,26 +960,44 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { auto_indent=[this]() { auto command=Config::get().terminal.clang_format_command; - unsigned indent_width; - std::string tab_style; - if(tab_char=='\t') { - indent_width=tab_size*8; - tab_style="UseTab: Always"; + bool use_style_file=false; + + auto style_file_search_path=this->file_path.parent_path(); + while(true) { + auto style_file=style_file_search_path/"CMakeLists.txt"; + if(boost::filesystem::exists(style_file_search_path/".clang-format") || boost::filesystem::exists(style_file_search_path/"_clang-format")) { + use_style_file=true; + break; + } + if(style_file_search_path==style_file_search_path.root_directory()) + break; + style_file_search_path=style_file_search_path.parent_path(); } + + if(use_style_file) + command+=" -style=file"; else { - indent_width=tab_size; - tab_style="UseTab: Never"; + unsigned indent_width; + std::string tab_style; + if(tab_char=='\t') { + indent_width=tab_size*8; + tab_style="UseTab: Always"; + } + else { + indent_width=tab_size; + tab_style="UseTab: Never"; + } + command+=" -style=\"{IndentWidth: "+std::to_string(indent_width); + command+=", "+tab_style; + command+=", "+std::string("AccessModifierOffset: -")+std::to_string(indent_width); + if(Config::get().source.clang_format_style!="") + command+=", "+Config::get().source.clang_format_style; + command+="}\""; } - command+=" -style=\"{IndentWidth: "+std::to_string(indent_width); - command+=", "+tab_style; - command+=", "+std::string("AccessModifierOffset: -")+std::to_string(indent_width); - if(Config::get().source.clang_format_style!="") - command+=", "+Config::get().source.clang_format_style; - command+="}\""; std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream; - auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command); + auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path()); if(exit_status==0) { get_source_buffer()->begin_user_action(); auto iter=get_buffer()->get_insert()->get_iter(); diff --git a/src/terminal.cc b/src/terminal.cc index d1236f8..546328c 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -79,7 +79,7 @@ int Terminal::process(const std::string &command, const boost::filesystem::path process=std::unique_ptr(new Process(command, path.string())); if(process->get_id()<=0) { - async_print("Error: Failed to run command: " + command + "\n", true); + async_print("Error: failed to run command: " + command + "\n", true); return -1; } @@ -101,7 +101,7 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c }, true); if(process.get_id()<=0) { - async_print("Error: Failed to run command: " + command + "\n", true); + async_print("Error: failed to run command: " + command + "\n", true); return -1; } @@ -132,7 +132,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem auto pid=process->get_id(); if (pid<=0) { processes_mutex.unlock(); - async_print("Error: Failed to run command: " + command + "\n", true); + async_print("Error: failed to run command: " + command + "\n", true); if(callback) callback(-1); return; From 7e7589efacfe0f084fe03e1a618cc58f00aeb337 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 21 Dec 2015 15:14:41 +0100 Subject: [PATCH 8/9] Minor fixes to build path error handling --- src/cmake.cc | 2 +- src/window.cc | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 51f0b60..2e99f83 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -59,7 +59,7 @@ boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::p boost::system::error_code ec; boost::filesystem::create_directories(default_build_path, ec); if(ec) { - Terminal::get().print("Error: could not create "+default_build_path.string()+": "+ec.message(), true); + Terminal::get().print("Error: could not create "+default_build_path.string()+": "+ec.message()+"\n", true); return boost::filesystem::path(); } } diff --git a/src/window.cc b/src/window.cc index 041a164..38896f4 100644 --- a/src/window.cc +++ b/src/window.cc @@ -539,9 +539,11 @@ void Window::set_menu_actions() { if(cmake.project_path!="") { if(executable_path!="") { - compiling=true; auto project_path=cmake.project_path; auto default_build_path=CMake::get_default_build_path(project_path); + if(default_build_path.empty()) + return; + compiling=true; auto executable_path_string=executable_path.string(); size_t pos=executable_path_string.find(project_path.string()); if(pos!=std::string::npos) { @@ -586,9 +588,12 @@ void Window::set_menu_actions() { return; CMake cmake(cmake_path); if(cmake.project_path!="") { + 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, CMake::get_default_build_path(cmake.project_path), [this](int exit_status){ + Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status){ compiling=false; }); } From 006d7890f68a3534ef695a6a522b1dc03b54f749 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 21 Dec 2015 15:30:30 +0100 Subject: [PATCH 9/9] Another minor fix to build path error handling --- src/cmake.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cmake.cc b/src/cmake.cc index 2e99f83..0d8ab02 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -33,7 +33,8 @@ CMake::CMake(const boost::filesystem::path &path) { } if(!project_path.empty()) { - if(!boost::filesystem::exists(get_default_build_path(project_path)/"compile_commands.json")) + auto default_build_path=get_default_build_path(project_path); + if(!default_build_path.empty() && !boost::filesystem::exists(default_build_path/"compile_commands.json")) create_compile_commands(project_path); } }