From d7b60adc62fbd1ca7234ea36bfc34d5b7323365d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 15 Feb 2019 14:23:30 +0100 Subject: [PATCH 01/63] find and include python plugin dependencies --- .appveyor.yml | 2 +- .gitmodules | 3 +++ CMakeLists.txt | 63 +++++++++++++++++++++++++++++++++++++++++++- docs/install.md | 2 +- lib/pybind11 | 1 + src/CMakeLists.txt | 41 +++++++++++++++++----------- tests/CMakeLists.txt | 7 ++++- 7 files changed, 100 insertions(+), 19 deletions(-) create mode 160000 lib/pybind11 diff --git a/.appveyor.yml b/.appveyor.yml index d370363..6dd147e 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,7 +12,7 @@ cache: before_build: - git submodule update --init --recursive # - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syyuu" - - C:\msys64\usr\bin\bash -lc "pacman --noconfirm --needed -S make mingw-w64-x86_64-{cmake,toolchain,clang,gtkmm3,gtksourceviewmm3,boost,aspell,aspell-en,libgit2,universal-ctags-git,libffi}" + - C:\msys64\usr\bin\bash -lc "pacman --noconfirm --needed -S make mingw-w64-x86_64-{cmake,toolchain,clang,gtkmm3,gtksourceviewmm3,boost,aspell,aspell-en,libgit2,universal-ctags-git,libffi,pygobject-devel}" build_script: - C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER && mkdir build && cd build && cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=/mingw64 -DBUILD_TESTING=1 .. && make -j$(nproc) && make test" diff --git a/.gitmodules b/.gitmodules index a963aaa..b67fd67 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/libclangmm"] path = lib/libclangmm url = https://gitlab.com/cppit/libclangmm +[submodule "lib/pybind11"] + path = lib/pybind11 + url = https://github.com/pybind/pybind11 diff --git a/CMakeLists.txt b/CMakeLists.txt index d0882b7..8dec029 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,9 +48,68 @@ option(BUILD_FUZZING "Build tests") option(LIBCLANG_PATH "Use custom path for libclang") option(LIBLLDB_PATH "Use custom path for liblldb") +if(${CMAKE_VERSION} VERSION_GREATER 3.11.4) + if (${CMAKE_HOST_WIN32}) + if("$ENV{APPVEYOR}" STREQUAL "True") + set(MINGW_PATH "C:/msys64/mingw64") + else() + set(MINGW_PATH "$ENV{MSYSTEM_PREFIX}") + endif() + set(MINGW_PYTHON_VERSION 3.7) + set(MINGW_LIBRARY_DIR "${MINGW_PATH}/lib") + set(MINGW_INCLUDE_DIR "${MINGW_PATH}/include") + find_file(Python3_LIBRARIES "libpython${MINGW_PYTHON_VERSION}m.dll.a" HINTS ${MINGW_LIBRARY_DIR} NO_DEFAULT_PATH) + find_path(Python3_INCLUDE_DIRS "Python.h" HINTS "${MINGW_INCLUDE_DIR}/python${MINGW_PYTHON_VERSION}m" NO_DEFAULT_PATH) + if (EXISTS ${Python3_LIBRARIES} AND EXISTS ${Python3_INCLUDE_DIRS}) + set(Python3_FOUND True) + set(Python3_LIBRARY_DIRS "${MINGW_LIBRARY_DIR}/python${MINGW_PYTHON_VERSION}") + set(Python3_VERSION_MAJOR 3) + set(Python3_VERSION_MINOR 7) + endif() + else() + find_package(Python3 COMPONENTS Development) + endif() +else() + find_package(PythonLibs 3) + message(${PYTHONLIBS_VERSION_STRING}) +endif() + +if(${Python3_FOUND}) + if(${CMAKE_HOST_WIN32}) + set(PYTHONLIBS_FOUND True) + set(PYTHON_MODULE_EXTENSION True) + endif() + set(PYTHONLIBS_FOUND ${Python3_FOUND}) + set(PYTHON_LIBRARIES ${Python3_LIBRARIES}) + set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) + set(PYTHON_LIBRARY_DIR ${Python3_LIBRARY_DIRS}/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) +endif() + +include(FindPkgConfig) + +set(PYGOBJECT_FOUND False) + +if(${PYTHONLIBS_FOUND}) + add_subdirectory(lib/pybind11) + pkg_check_modules(PYGOBJECT pygobject-3.0) + if("${PYGOBJECT_FOUND}" STREQUAL "") + set(PYGOBJECT_FOUND False) + endif() +endif() + +if(${PYGOBJECT_FOUND}) + add_definitions(-DJUCI_ENABLE_PLUGINS) +else() + message(STATUS "Python or pygobject not found. Building juCi++ without plugin support.") +endif() + +set(BUILD_TESTING_SAVED ${BUILD_TESTING}) +set(BUILD_TESTING OFF CACHE BOOL "Disable sub-project tests" FORCE) +add_subdirectory(lib/libclangmm) +add_subdirectory(lib/tiny-process-library) +set(BUILD_TESTING ${BUILD_TESTING_SAVED} CACHE BOOL "Set to previous value" FORCE) find_package(Boost 1.54 COMPONENTS REQUIRED filesystem serialization) find_package(ASPELL REQUIRED) -include(FindPkgConfig) pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED) pkg_check_modules(GTKSVMM gtksourceviewmm-3.0 REQUIRED) pkg_check_modules(LIBGIT2 libgit2 REQUIRED) @@ -112,6 +171,8 @@ include_directories( ${LIBCLANG_INCLUDE_DIRS} ${ASPELL_INCLUDE_DIR} ${LIBGIT2_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIRS} + ${PYGOBJECT_INCLUDE_DIRS} ) add_subdirectory("src") diff --git a/docs/install.md b/docs/install.md index 45a2239..baa4d53 100644 --- a/docs/install.md +++ b/docs/install.md @@ -143,7 +143,7 @@ make install Install dependencies (replace `x86_64` with `i686` for 32-bit MSYS2 installs): ```sh -pacman -S git mingw-w64-x86_64-cmake make mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang mingw-w64-x86_64-gtkmm3 mingw-w64-x86_64-gtksourceviewmm3 mingw-w64-x86_64-boost mingw-w64-x86_64-aspell mingw-w64-x86_64-aspell-en mingw-w64-x86_64-libgit2 mingw-w64-x86_64-universal-ctags-git +pacman -S git make mingw-w64-x86_64-{cmake,toolchain,clang,gtkmm3,gtksourceviewmm3,boost,aspell,aspell-en,libgit2,universal-ctags-git,pygobject-devel} ``` Note that juCi++ must be built and run in a MinGW Shell (for instance MinGW-w64 Win64 Shell). diff --git a/lib/pybind11 b/lib/pybind11 new file mode 160000 index 0000000..9a19306 --- /dev/null +++ b/lib/pybind11 @@ -0,0 +1 @@ +Subproject commit 9a19306fbf30642ca331d0ec88e7da54a96860f9 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86eadb9..9a41714 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,25 +41,36 @@ target_link_libraries(juci_shared tiny-process-library ) -set(JUCI_FILES - config.cpp - dialogs.cpp - dialogs_unix.cpp - directories.cpp - entrybox.cpp - info.cpp - juci.cpp - notebook.cpp - project.cpp - selection_dialog.cpp - window.cpp +set(JUCI_SOURCES + config.cc + dialogs.cc + dialogs_unix.cc + directories.cc + entrybox.cc + info.cc + juci.cc + notebook.cc + project.cc + selection_dialog.cc + tooltips.cc + window.cc ) + if(APPLE) - list(APPEND JUCI_FILES window_macos.m) + list(APPEND JUCI_SOURCES window_macos.m) +endif() + + +set(JUCI_TARGET_LIBRARIES + juci_shared +) + +if(${PYTHONLIBS_FOUND}) + list(APPEND JUCI_TARGET_LIBRARIES pybind11 ${PYTHON_LIBRARIES} ${PYGOBJECT_LIBRARIES}) endif() -add_executable(juci ${JUCI_FILES}) -target_link_libraries(juci juci_shared) +add_executable(juci ${JUCI_SOURCES}) +target_link_libraries(juci ${JUCI_TARGET_LIBRARIES}) if(APPLE) target_link_libraries(juci "-framework Foundation -framework AppKit") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5428c91..00322dc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,7 +5,12 @@ endif() add_definitions(-DJUCI_BUILD_PATH="${CMAKE_BINARY_DIR}" -DJUCI_TESTS_PATH="${CMAKE_CURRENT_SOURCE_DIR}") -include_directories(${CMAKE_SOURCE_DIR}/src) +include_directories( + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/libclangmm/src + ${CMAKE_SOURCE_DIR}/tiny-process-library + ${CMAKE_SOURCE_DIR}/pybind11 +) add_library(test_stubs OBJECT stubs/config.cpp From 63c822c887a9a19202c5ae31f49b8badcfd0c0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 25 Feb 2019 21:57:26 +0100 Subject: [PATCH 02/63] bind terminal and add type caster for filesystem path --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/config.cpp | 9 ++++++ src/config.hpp | 7 +++++ src/files.hpp | 5 ++++ src/juci.cpp | 13 ++++---- src/juci.hpp | 13 ++++++-- src/plugins.h | 55 ++++++++++++++++++++++++++++++++++ src/python_bind.h | 3 ++ src/python_interpreter.cc | 31 ++++++++++++++++++++ src/python_interpreter.h | 13 ++++++++ src/python_module.h | 62 +++++++++++++++++++++++++++++++++++++++ src/window.cpp | 18 +++++++----- src/window.hpp | 11 +++---- tests/CMakeLists.txt | 1 - 15 files changed, 218 insertions(+), 25 deletions(-) create mode 100644 src/plugins.h create mode 100644 src/python_bind.h create mode 100644 src/python_interpreter.cc create mode 100644 src/python_interpreter.h create mode 100644 src/python_module.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dec029..74b2a17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ include_directories( ${LIBGIT2_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} ${PYGOBJECT_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib/pybind11/include ) add_subdirectory("src") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9a41714..24f1462 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -54,6 +54,7 @@ set(JUCI_SOURCES selection_dialog.cc tooltips.cc window.cc + python_interpreter.cc ) if(APPLE) diff --git a/src/config.cpp b/src/config.cpp index da9a25e..941f77e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -3,6 +3,7 @@ #include "filesystem.hpp" #include "terminal.hpp" #include +#include #include #include @@ -212,4 +213,12 @@ void Config::read(const boost::property_tree::ptree &cfg) { log.libclang = cfg.get("log.libclang"); log.language_server = cfg.get("log.language_server"); + + auto plugins_path = cfg.get("plugins.path"); + boost::replace_all(plugins_path, "", home_juci_path.string()); + plugins.path = plugins_path; + plugins.enabled = cfg.get("plugins.enabled"); + if (plugins.enabled) { + std::cout << "Plugins enabled" << std::endl; + } } diff --git a/src/config.hpp b/src/config.hpp index c954a78..629314d 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -113,6 +113,12 @@ public: bool language_server; }; + class Plugins { + public: + bool enabled; + std::string path; + }; + private: Config(); @@ -131,6 +137,7 @@ public: Project project; Source source; Log log; + Plugins plugins; boost::filesystem::path home_path; boost::filesystem::path home_juci_path; diff --git a/src/files.hpp b/src/files.hpp index e1f08c9..0c325ea 100644 --- a/src/files.hpp +++ b/src/files.hpp @@ -233,6 +233,11 @@ const std::string default_config_file = R"RAW({ "libclang_comment": "Outputs diagnostics for new C/C++ buffers", "libclang": false, "language_server": false + }, + "plugins": { + "enabled": true, + "path_comment": "Directory where plugins are loaded from.", + "path": "/plugins" } } )RAW"; diff --git a/src/juci.cpp b/src/juci.cpp index 41d31f1..ad0da2b 100644 --- a/src/juci.cpp +++ b/src/juci.cpp @@ -55,12 +55,11 @@ int Application::on_command_line(const Glib::RefPtr void Application::on_activate() { std::vector> file_offsets; std::string current_file; - Window::get().load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty()); - - Window::get().add_widgets(); - - add_window(Window::get()); - Window::get().show(); + window.init(); + window.load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty()); + window.add_widgets(); + add_window(window); + window.show(); bool first_directory = true; for(auto &directory : directories) { @@ -132,7 +131,7 @@ void Application::on_startup() { } } -Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) { +Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE), window(plugins) { Glib::set_application_name("juCi++"); //Gtk::MessageDialog without buttons caused text to be selected, this prevents that diff --git a/src/juci.hpp b/src/juci.hpp index fc20fbe..45b36c1 100644 --- a/src/juci.hpp +++ b/src/juci.hpp @@ -1,4 +1,10 @@ #pragma once +#include +#include +#include "window.h" +#ifdef JUCI_ENABLE_PLUGINS +#include "plugins.h" +#endif /** \mainpage juCi++ is a lightweight C++ IDE written in C++ @@ -25,9 +31,6 @@ [juCi++] --> [tiny-process-library] : use \enduml */ -#include -#include - class Application : public Gtk::Application { public: Application(); @@ -39,4 +42,8 @@ private: std::vector directories; std::vector> files; std::vector errors; + Window window; +#ifdef JUCI_ENABLE_PLUGINS + Plugins plugins; +#endif }; diff --git a/src/plugins.h b/src/plugins.h new file mode 100644 index 0000000..98a0d5e --- /dev/null +++ b/src/plugins.h @@ -0,0 +1,55 @@ +#pragma once + +#include "config.h" +#include "menu.h" +#include "python_interpreter.h" +#include "python_module.h" +#include +#include + +class __attribute__((visibility("default"))) +Plugins { +public: + Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { + auto &config = Config::get(); + config.load(); + auto sys = py::module::import("sys"); + sys.attr("path").cast().append(config.plugins.path); + // sys.attr("excepthook") = py::cpp_function([](py::object type, py::object value, py::object traceback) { + // Terminal::get().print("const std::string &message\n"); + // }); + } + void load() { + boost::filesystem::directory_iterator end_it; + for(boost::filesystem::directory_iterator it(Config::get().plugins.path); it != end_it; it++) { + auto module_name = it->path().stem().string(); + if(module_name.empty()) + continue; + const auto is_directory = boost::filesystem::is_directory(it->path()); + const auto has_py_extension = it->path().extension() == ".py"; + const auto is_pycache = module_name == "__pycache__"; + if((is_directory && !is_pycache) || has_py_extension) { + try { + auto module = interpreter.add_module(module_name); + if (module) { + Terminal::get().print("Reloading plugin ´" + module_name + "´\n"); + interpreter.reload_module(module); + } else { + Terminal::get().print("Loading plugin ´" + module_name + "´\n"); + py::module::import(module_name.c_str()); + } + + } + catch(py::error_already_set &error) { + Terminal::get().print("Error loading plugin `" + module_name + "`:\n" + error.what() + "\n"); + } + } + if(interpreter.error()) + std::cerr << py::error_already_set().what() << std::endl; + } + } + +private: + py::detail::embedded_module jucipp_module; + Python::Interpreter interpreter; +}; diff --git a/src/python_bind.h b/src/python_bind.h new file mode 100644 index 0000000..4ece974 --- /dev/null +++ b/src/python_bind.h @@ -0,0 +1,3 @@ +#pragma once +#include +namespace py = pybind11; diff --git a/src/python_interpreter.cc b/src/python_interpreter.cc new file mode 100644 index 0000000..bc03174 --- /dev/null +++ b/src/python_interpreter.cc @@ -0,0 +1,31 @@ +#include "python_interpreter.h" + +pybind11::module Python::Interpreter::add_module(const std::string &module_name) { + return pybind11::reinterpret_borrow(PyImport_AddModule(module_name.c_str())); +} + +pybind11::object Python::Interpreter::error() { + return pybind11::reinterpret_borrow(PyErr_Occurred()); +} + +pybind11::module Python::Interpreter::reload_module(pybind11::module &module) { + auto reload = pybind11::reinterpret_steal(PyImport_ReloadModule(module.ptr())); + if(!reload) { + throw pybind11::error_already_set(); + } + return reload; +} + +#include +#include + +Python::Interpreter::~Interpreter() { + if (error()){ + std::cout << py::error_already_set().what() << std::endl; + } + py::finalize_interpreter(); +} + +Python::Interpreter::Interpreter() { + py::initialize_interpreter(); +} diff --git a/src/python_interpreter.h b/src/python_interpreter.h new file mode 100644 index 0000000..1986ab0 --- /dev/null +++ b/src/python_interpreter.h @@ -0,0 +1,13 @@ +#pragma once +#include "python_bind.h" + +namespace Python { + class Interpreter { + public: + pybind11::module static add_module(const std::string &module_name); + pybind11::module static reload_module(pybind11::module &module); + pybind11::object static error(); + ~Interpreter(); + Interpreter(); + }; +}; // namespace Python diff --git a/src/python_module.h b/src/python_module.h new file mode 100644 index 0000000..8d7b853 --- /dev/null +++ b/src/python_module.h @@ -0,0 +1,62 @@ +#pragma once +#include "python_bind.h" +#include "terminal.h" +#include +#include + +namespace pybind11 { + namespace detail { + template <> + struct type_caster { + public: + PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); + bool load(handle src, bool) { + const std::string path = pybind11::str(src); + value = path; + return !PyErr_Occurred(); + } + + static handle cast(boost::filesystem::path src, return_value_policy, handle) { + return pybind11::str(src.string()); + } + }; + } +} + +class Module { + static void init_terminal_module(pybind11::module &api) { + py::class_>(api, "Terminal") + .def(py::init([]() { return &(Terminal::get()); })) + .def("process", (int (Terminal::*)(const std::string &, const boost::filesystem::path &, bool)) & Terminal::process, + py::arg("command"), + py::arg("path") = "", + py::arg("use_pipes") = false) + .def("async_process", (void (Terminal::*)(const std::string &, const boost::filesystem::path &, const std::function &, bool)) & Terminal::async_process, + py::arg("command"), + py::arg("path") = "", + py::arg("callback") = nullptr, + py::arg("quiet") = false) + .def("kill_last_async_process", &Terminal::kill_last_async_process, + py::arg("force") = false) + .def("kill_async_processes", &Terminal::kill_async_processes, + py::arg("force") = false) + .def("print", &Terminal::print, + py::arg("message"), + py::arg("bold") = false) + .def("async_print", (void (Terminal::*)(const std::string &, bool)) & Terminal::async_print, + py::arg("message"), + py::arg("bold") = false) + .def("async_print", (void (Terminal::*)(size_t, const std::string &)) & Terminal::async_print, + py::arg("line_nr"), + py::arg("message")) + .def("configure", &Terminal::configure) + .def("clear", &Terminal::clear); + }; + +public: + static auto init_jucipp_module() { + auto api = py::module("Jucipp", "API"); + Module::init_terminal_module(api); + return api.ptr(); + }; +}; diff --git a/src/window.cpp b/src/window.cpp index 3d69dcc..f4a1057 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -16,24 +16,24 @@ #include "selection_dialog.hpp" #include "terminal.hpp" -Window::Window() { +Window::Window(Plugins &i) : plugins(i) { Gsv::init(); - set_title("juCi++"); get_style_context()->add_class("juci_window"); set_events(Gdk::POINTER_MOTION_MASK | Gdk::FOCUS_CHANGE_MASK | Gdk::SCROLL_MASK | Gdk::LEAVE_NOTIFY_MASK); +} +void Window::init() { auto visual = get_screen()->get_rgba_visual(); if(visual) gtk_widget_set_visual(reinterpret_cast(gobj()), visual->gobj()); - auto provider = Gtk::CssProvider::create(); auto screen = get_screen(); std::string border_radius_style; if(screen->get_rgba_visual()) border_radius_style = "border-radius: 5px; "; #if GTK_VERSION_GE(3, 20) - std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}"); +n std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}"); #else std::string notebook_style(".juci_notebook {-GtkNotebook-tab-overlap: 0px;} .juci_notebook tab {border-radius: 5px 5px 0 0; padding: 4px 4px;}"); #endif @@ -160,7 +160,10 @@ Window::Window() { about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy"); about.set_license_type(Gtk::License::LICENSE_MIT_X11); about.set_transient_for(*this); -} // Window constructor + if(Config::get().plugins.enabled) { + plugins.load(); + } +} void Window::configure() { Config::get().load(); @@ -274,8 +277,9 @@ void Window::set_menu_actions() { auto &menu = Menu::get(); menu.add_action("about", [this]() { - about.show(); - about.present(); + plugins.load(); + // about.show(); + // about.present(); }); menu.add_action("preferences", []() { Notebook::get().open(Config::get().home_juci_path / "config" / "config.json"); diff --git a/src/window.hpp b/src/window.hpp index 20b37a0..ad3c3ba 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -3,24 +3,21 @@ #include #include #include +#include "plugins.h" class Window : public Gtk::ApplicationWindow { - Window(); - public: - static Window &get() { - static Window singleton; - return singleton; - } + Window(Plugins &p); void add_widgets(); void save_session(); void load_session(std::vector &directories, std::vector> &files, std::vector> &file_offsets, std::string ¤t_file, bool read_directories_and_files); - + void init(); protected: bool on_key_press_event(GdkEventKey *event) override; bool on_delete_event(GdkEventAny *event) override; private: + Plugins& plugins; Gtk::AboutDialog about; Gtk::ScrolledWindow directories_scrolled_window, terminal_scrolled_window; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 00322dc..f41cd14 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,7 +9,6 @@ include_directories( ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/libclangmm/src ${CMAKE_SOURCE_DIR}/tiny-process-library - ${CMAKE_SOURCE_DIR}/pybind11 ) add_library(test_stubs OBJECT From 0be5d31d13ecc0e2ecb030b2f37ef8cce8d92903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 7 Mar 2019 16:00:14 +0100 Subject: [PATCH 03/63] add test for terminal bindings --- src/CMakeLists.txt | 26 +++---- tests/CMakeLists.txt | 9 +++ tests/python_interpreter_test.cc | 76 +++++++++++++++++++ .../basic_test.py | 1 + .../exception_test.py | 1 + .../ls/hello_world.txt | 0 .../terminal_test.py | 15 ++++ 7 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 tests/python_interpreter_test.cc create mode 100644 tests/python_interpreter_test_files/basic_test.py create mode 100644 tests/python_interpreter_test_files/exception_test.py create mode 100644 tests/python_interpreter_test_files/ls/hello_world.txt create mode 100644 tests/python_interpreter_test_files/terminal_test.py diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24f1462..bc07f4e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(JUCI_SHARED_FILES menu.cpp meson.cpp project_build.cpp + python_interpreter.cc snippets.cpp source.cpp source_base.cpp @@ -42,19 +43,18 @@ target_link_libraries(juci_shared ) set(JUCI_SOURCES - config.cc - dialogs.cc - dialogs_unix.cc - directories.cc - entrybox.cc - info.cc - juci.cc - notebook.cc - project.cc - selection_dialog.cc - tooltips.cc - window.cc - python_interpreter.cc + config.cpp + dialogs.cpp + dialogs_unix.cpp + directories.cpp + entrybox.cpp + info.cpp + juci.cpp + notebook.cpp + project.cpp + selection_dialog.cpp + tooltips.cpp + window.cpp ) if(APPLE) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f41cd14..2999a72 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -121,3 +121,12 @@ if(BUILD_FUZZING) target_link_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_libraries(markdown_fuzzer juci_shared) endif() + +add_executable(git_test git_test.cc $) +target_link_libraries(git_test juci_shared) +add_test(git_test git_test) + +add_executable(python_interpreter_test python_interpreter_test.cc $) +target_link_libraries(python_interpreter_test juci_shared ${PYTHON_LIBRARIES}) +add_test(python_interpreter_test python_interpreter_test) + diff --git a/tests/python_interpreter_test.cc b/tests/python_interpreter_test.cc new file mode 100644 index 0000000..ed877ae --- /dev/null +++ b/tests/python_interpreter_test.cc @@ -0,0 +1,76 @@ +#include "config.h" +#include "plugins.h" +#include "python_interpreter.h" +#include "python_module.h" +#include "terminal.h" + + +class __attribute__((visibility("default"))) +suite { +public: + Glib::RefPtr app = Gtk::Application::create(); + py::detail::embedded_module jucipp = py::detail::embedded_module("Jucipp", Module::init_jucipp_module); + Python::Interpreter interpreter; + Terminal &terminal = Terminal::get(); + Config &config = Config::get(); + boost::filesystem::path test_file_path = boost::filesystem::canonical(std::string(JUCI_TESTS_PATH) + "/python_interpreter_test_files"); + bool has_assertion = false; + suite() { + auto sys = interpreter.add_module("sys"); + sys.attr("path").cast().append(test_file_path.string()); + config.terminal.history_size = 100; + } + ~suite() { + g_assert_true(has_assertion); + } +}; + +int main() { + { + suite test_suite; + { + py::module::import("basic_test"); + try { + py::module::import("exception_test"); + } + catch(const py::error_already_set &error) { + test_suite.has_assertion = true; + } + } + } + + { + suite test_suite; + { + auto connection = test_suite.terminal.get_buffer()->signal_insert().connect([&](const Gtk::TextBuffer::iterator &, const Glib::ustring &msg, int) { + g_assert_cmpstr(msg.c_str(), ==, "Hello, World!\n"); + test_suite.has_assertion = true; + }); + auto module = py::module::import("terminal_test"); + module.attr("hello_world")(); + connection.disconnect(); + } + } + { + suite test_suite; + { + auto connection = test_suite.terminal.get_buffer()->signal_insert().connect([&](const Gtk::TextBuffer::iterator &, const Glib::ustring &msg, int) { + g_assert_cmpstr(msg.c_str(), ==, "hello_world.txt\n"); + test_suite.has_assertion = true; + test_suite.app->release(); + }); + test_suite.app->hold(); + std::thread thread([&] { + const auto ls_dir = test_suite.test_file_path / "ls"; + auto module = py::module::import("terminal_test"); + auto res = module.attr("process")(ls_dir).cast(); + g_assert_cmpint(res, ==, 0); + }); + test_suite.app->run(); + thread.join(); + connection.disconnect(); + } + } + + return 0; +} diff --git a/tests/python_interpreter_test_files/basic_test.py b/tests/python_interpreter_test_files/basic_test.py new file mode 100644 index 0000000..200f1f5 --- /dev/null +++ b/tests/python_interpreter_test_files/basic_test.py @@ -0,0 +1 @@ +import Jucipp diff --git a/tests/python_interpreter_test_files/exception_test.py b/tests/python_interpreter_test_files/exception_test.py new file mode 100644 index 0000000..618a16e --- /dev/null +++ b/tests/python_interpreter_test_files/exception_test.py @@ -0,0 +1 @@ +invalid code diff --git a/tests/python_interpreter_test_files/ls/hello_world.txt b/tests/python_interpreter_test_files/ls/hello_world.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/python_interpreter_test_files/terminal_test.py b/tests/python_interpreter_test_files/terminal_test.py new file mode 100644 index 0000000..e2d3736 --- /dev/null +++ b/tests/python_interpreter_test_files/terminal_test.py @@ -0,0 +1,15 @@ +from Jucipp import Terminal + +t = Terminal(); + +def hello_world(): + t.print("Hello, World!\n") + +def clear(): + t.clear() + +def process(path): + return t.process("ls", path, True) + +def async_print(): + return t.async_print("Hello, World!") From 1244f1a32fc62dcb28c49fbb1129e6cb3efdf880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 10 Mar 2019 16:54:55 +0100 Subject: [PATCH 04/63] fix python home and path on windows --- CMakeLists.txt | 4 ++-- src/python_interpreter.cc | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74b2a17..f133543 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ if(${CMAKE_VERSION} VERSION_GREATER 3.11.4) find_path(Python3_INCLUDE_DIRS "Python.h" HINTS "${MINGW_INCLUDE_DIR}/python${MINGW_PYTHON_VERSION}m" NO_DEFAULT_PATH) if (EXISTS ${Python3_LIBRARIES} AND EXISTS ${Python3_INCLUDE_DIRS}) set(Python3_FOUND True) - set(Python3_LIBRARY_DIRS "${MINGW_LIBRARY_DIR}/python${MINGW_PYTHON_VERSION}") + set(Python3_LIBRARY_DIRS ${MINGW_LIBRARY_DIR}) set(Python3_VERSION_MAJOR 3) set(Python3_VERSION_MINOR 7) endif() @@ -76,7 +76,6 @@ endif() if(${Python3_FOUND}) if(${CMAKE_HOST_WIN32}) - set(PYTHONLIBS_FOUND True) set(PYTHON_MODULE_EXTENSION True) endif() set(PYTHONLIBS_FOUND ${Python3_FOUND}) @@ -99,6 +98,7 @@ endif() if(${PYGOBJECT_FOUND}) add_definitions(-DJUCI_ENABLE_PLUGINS) + add_definitions(-DPYTHON_HOME_DIR=L"${PYTHON_LIBRARY_DIR}") else() message(STATUS "Python or pygobject not found. Building juCi++ without plugin support.") endif() diff --git a/src/python_interpreter.cc b/src/python_interpreter.cc index bc03174..5d5d2e0 100644 --- a/src/python_interpreter.cc +++ b/src/python_interpreter.cc @@ -27,5 +27,13 @@ Python::Interpreter::~Interpreter() { } Python::Interpreter::Interpreter() { +#ifdef PYTHON_HOME_DIR +#ifdef _WIN32 + const std::wstring python_home(PYTHON_HOME_DIR); + const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages" ); + Py_SetPythonHome(python_home.c_str()); + Py_SetPath(python_path.c_str()); +#endif +#endif py::initialize_interpreter(); } From 22bf01be448a27dd675e5f1af545d31f6a5c486e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 10 Mar 2019 16:55:35 +0100 Subject: [PATCH 05/63] move plugin implementation to own file --- src/CMakeLists.txt | 2 +- src/plugins.cc | 41 ++++++++++++++++++++++++++++ src/plugins.h | 47 ++------------------------------ tests/python_interpreter_test.cc | 2 ++ 4 files changed, 47 insertions(+), 45 deletions(-) create mode 100644 src/plugins.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc07f4e..fcce2b4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(JUCI_SHARED_FILES menu.cpp meson.cpp project_build.cpp + plugins.cc python_interpreter.cc snippets.cpp source.cpp @@ -61,7 +62,6 @@ if(APPLE) list(APPEND JUCI_SOURCES window_macos.m) endif() - set(JUCI_TARGET_LIBRARIES juci_shared ) diff --git a/src/plugins.cc b/src/plugins.cc new file mode 100644 index 0000000..96f27b3 --- /dev/null +++ b/src/plugins.cc @@ -0,0 +1,41 @@ +#include "plugins.h" +#include "config.h" +#include "python_module.h" + +Plugins::Plugins(): jucipp_module("Jucipp", Module::init_jucipp_module) { + auto &config = Config::get(); + config.load(); + const auto sys = py::module::import("sys"); + sys.attr("path").cast().append(config.plugins.path); + } + +void Plugins::load() { + std::cout << Config::get().plugins.path << std::endl; + boost::filesystem::directory_iterator end_it; + for(boost::filesystem::directory_iterator it(Config::get().plugins.path); it != end_it; it++) { + auto module_name = it->path().stem().string(); + if(module_name.empty()) + continue; + const auto is_directory = boost::filesystem::is_directory(it->path()); + const auto has_py_extension = it->path().extension() == ".py"; + const auto is_pycache = module_name == "__pycache__"; + if((is_directory && !is_pycache) || has_py_extension) { + try { + auto module = interpreter.add_module(module_name); + if (module) { + Terminal::get().print("Reloading plugin ´" + module_name + "´\n"); + interpreter.reload_module(module); + } else { + Terminal::get().print("Loading plugin ´" + module_name + "´\n"); + py::module::import(module_name.c_str()); + } + + } + catch(py::error_already_set &error) { + Terminal::get().print("Error loading plugin `" + module_name + "`:\n" + error.what() + "\n"); + } + } + if(interpreter.error()) + std::cerr << py::error_already_set().what() << std::endl; + } +} diff --git a/src/plugins.h b/src/plugins.h index 98a0d5e..f7177b5 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -1,54 +1,13 @@ #pragma once -#include "config.h" -#include "menu.h" -#include "python_interpreter.h" -#include "python_module.h" #include -#include +#include "python_interpreter.h" class __attribute__((visibility("default"))) Plugins { public: - Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { - auto &config = Config::get(); - config.load(); - auto sys = py::module::import("sys"); - sys.attr("path").cast().append(config.plugins.path); - // sys.attr("excepthook") = py::cpp_function([](py::object type, py::object value, py::object traceback) { - // Terminal::get().print("const std::string &message\n"); - // }); - } - void load() { - boost::filesystem::directory_iterator end_it; - for(boost::filesystem::directory_iterator it(Config::get().plugins.path); it != end_it; it++) { - auto module_name = it->path().stem().string(); - if(module_name.empty()) - continue; - const auto is_directory = boost::filesystem::is_directory(it->path()); - const auto has_py_extension = it->path().extension() == ".py"; - const auto is_pycache = module_name == "__pycache__"; - if((is_directory && !is_pycache) || has_py_extension) { - try { - auto module = interpreter.add_module(module_name); - if (module) { - Terminal::get().print("Reloading plugin ´" + module_name + "´\n"); - interpreter.reload_module(module); - } else { - Terminal::get().print("Loading plugin ´" + module_name + "´\n"); - py::module::import(module_name.c_str()); - } - - } - catch(py::error_already_set &error) { - Terminal::get().print("Error loading plugin `" + module_name + "`:\n" + error.what() + "\n"); - } - } - if(interpreter.error()) - std::cerr << py::error_already_set().what() << std::endl; - } - } - + Plugins(); + void load(); private: py::detail::embedded_module jucipp_module; Python::Interpreter interpreter; diff --git a/tests/python_interpreter_test.cc b/tests/python_interpreter_test.cc index ed877ae..3773e29 100644 --- a/tests/python_interpreter_test.cc +++ b/tests/python_interpreter_test.cc @@ -3,6 +3,8 @@ #include "python_interpreter.h" #include "python_module.h" #include "terminal.h" +#include "config.h" +#include "python_module.h" class __attribute__((visibility("default"))) From bcd3d0eb96d7fabc6ca7ab706e6455424ff644bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 6 Apr 2019 14:40:44 +0200 Subject: [PATCH 06/63] bind config classes --- src/python_module.h | 112 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 2 deletions(-) diff --git a/src/python_module.h b/src/python_module.h index 8d7b853..31f2385 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -1,4 +1,5 @@ #pragma once +#include "config.h" #include "python_bind.h" #include "terminal.h" #include @@ -20,8 +21,8 @@ namespace pybind11 { return pybind11::str(src.string()); } }; - } -} + } // namespace detail +} // namespace pybind11 class Module { static void init_terminal_module(pybind11::module &api) { @@ -53,10 +54,117 @@ class Module { .def("clear", &Terminal::clear); }; + static void init_config_module(pybind11::module &api) { + py::class_> config(api, "Config"); + config + .def(py::init([]() { return &(Config::get()); })) + .def("load", &Config::load) + .def_readonly("version", &Config::version) + + ; + py::class_(config, "Menu") + .def_readwrite("keys", &Config::Menu::keys) + + ; + py::class_(config, "Theme") + .def_readwrite("name", &Config::Theme::name) + .def_readwrite("variant", &Config::Theme::variant) + .def_readwrite("font", &Config::Theme::font) + + ; + py::class_(config, "Terminal") + .def_readwrite("history_size", &Config::Terminal::history_size) + .def_readwrite("font", &Config::Terminal::font) + + ; + py::class_ project(config, "Project"); + py::class_(project, "CMake") + .def_readwrite("command", &Config::Project::CMake::command) + .def_readwrite("compile_command", &Config::Project::CMake::compile_command) + + ; + py::class_(project, "Meson") + .def_readwrite("command", &Config::Project::Meson::command) + .def_readwrite("compile_command", &Config::Project::Meson::compile_command) + + ; + project + .def_readwrite("default_build_path", &Config::Project::default_build_path) + .def_readwrite("debug_build_path", &Config::Project::debug_build_path) + .def_readwrite("cmake", &Config::Project::cmake) + .def_readwrite("meson", &Config::Project::meson) + .def_readwrite("save_on_compile_or_run", &Config::Project::save_on_compile_or_run) + .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) + .def_readwrite("ctags_command", &Config::Project::ctags_command) + .def_readwrite("python_command", &Config::Project::python_command) + + ; + py::class_ source(config, "Source"); + py::class_(source, "DocumentationSearch") + .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) + .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) + + ; + source + .def_readwrite("style", &Config::Source::style) + .def_readwrite("font", &Config::Source::font) + .def_readwrite("spellcheck_language", &Config::Source::spellcheck_language) + .def_readwrite("cleanup_whitespace_characters", &Config::Source::cleanup_whitespace_characters) + .def_readwrite("show_whitespace_characters", &Config::Source::show_whitespace_characters) + .def_readwrite("format_style_on_save", &Config::Source::format_style_on_save) + .def_readwrite("format_style_on_save_if_style_file_found", &Config::Source::format_style_on_save_if_style_file_found) + .def_readwrite("smart_inserts", &Config::Source::smart_inserts) + .def_readwrite("show_map", &Config::Source::show_map) + .def_readwrite("map_font_size", &Config::Source::map_font_size) + .def_readwrite("show_git_diff", &Config::Source::show_git_diff) + .def_readwrite("show_background_pattern", &Config::Source::show_background_pattern) + .def_readwrite("show_right_margin", &Config::Source::show_right_margin) + .def_readwrite("right_margin_position", &Config::Source::right_margin_position) + .def_readwrite("auto_tab_char_and_size", &Config::Source::auto_tab_char_and_size) + .def_readwrite("default_tab_char", &Config::Source::default_tab_char) + .def_readwrite("default_tab_size", &Config::Source::default_tab_size) + .def_readwrite("tab_indents_line", &Config::Source::tab_indents_line) + .def_readwrite("wrap_lines", &Config::Source::wrap_lines) + .def_readwrite("highlight_current_line", &Config::Source::highlight_current_line) + .def_readwrite("show_line_numbers", &Config::Source::show_line_numbers) + .def_readwrite("enable_multiple_cursors", &Config::Source::enable_multiple_cursors) + .def_readwrite("auto_reload_changed_files", &Config::Source::auto_reload_changed_files) + .def_readwrite("clang_format_style", &Config::Source::clang_format_style) + .def_readwrite("clang_usages_threads", &Config::Source::clang_usages_threads) + .def_readwrite("documentation_searches", &Config::Source::documentation_searches) + + ; + + py::class_(config, "Log") + .def_readwrite("libclang", &Config::Log::libclang) + .def_readwrite("language_server", &Config::Log::language_server) + + ; + py::class_(config, "Plugins") + .def_readwrite("enabled", &Config::Plugins::enabled) + .def_readwrite("path", &Config::Plugins::path) + + ; + config + .def_readwrite("menu", &Config::menu) + .def_readwrite("theme", &Config::theme) + .def_readwrite("terminal", &Config::terminal) + .def_readwrite("project", &Config::project) + .def_readwrite("source", &Config::source) + .def_readwrite("log", &Config::log) + .def_readwrite("plugins", &Config::plugins) + .def_readwrite("home_path", &Config::home_path) + .def_readwrite("home_juci_path", &Config::home_juci_path) + + ; + } + + public: static auto init_jucipp_module() { auto api = py::module("Jucipp", "API"); Module::init_terminal_module(api); + Module::init_config_module(api); return api.ptr(); }; }; From 4763f50e25704d3a5baa38b612ac1c40d98b8b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 6 Apr 2019 15:25:22 +0200 Subject: [PATCH 07/63] bind cmake class --- src/python_module.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/python_module.h b/src/python_module.h index 31f2385..2233a57 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -1,4 +1,5 @@ #pragma once +#include "cmake.h" #include "config.h" #include "python_bind.h" #include "terminal.h" @@ -159,12 +160,28 @@ class Module { ; } + static void init_cmake_module(pybind11::module &api) { + py::class_(api, "CMake") + .def_readwrite("project_path", &CMake::project_path) + .def("update_default_build", &CMake::update_default_build, + py::arg("default_build_path"), + py::arg("force") = false) + .def("update_debug_build", &CMake::update_debug_build, + py::arg("debug_build_path"), + py::arg("force") = false) + .def("get_executable", &CMake::get_executable, + py::arg("build_path"), + py::arg("file_path")) + + ; + } public: static auto init_jucipp_module() { auto api = py::module("Jucipp", "API"); Module::init_terminal_module(api); Module::init_config_module(api); + Module::init_cmake_module(api); return api.ptr(); }; }; From e55c0759811b621864e4cf838e02e7a636a56425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 6 Apr 2019 15:31:30 +0200 Subject: [PATCH 08/63] bind compile commands class --- src/python_module.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/python_module.h b/src/python_module.h index 2233a57..8477d4a 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -1,5 +1,6 @@ #pragma once #include "cmake.h" +#include "compile_commands.h" #include "config.h" #include "python_bind.h" #include "terminal.h" @@ -176,12 +177,34 @@ class Module { ; } + static void init_compile_commands_module(pybind11::module &api) { + py::class_ compile_commands(api, "CompileCommands"); + py::class_(compile_commands, "CompileCommands") + .def_readwrite("directory", &CompileCommands::Command::directory) + .def_readwrite("parameters", &CompileCommands::Command::parameters) + .def_readwrite("file", &CompileCommands::Command::file) + + ; + compile_commands + .def_readwrite("commands", &CompileCommands::commands) + .def_static("get_arguments", &CompileCommands::get_arguments, + py::arg("build_path"), + py::arg("file_path")) + .def_static("is_header", &CompileCommands::is_header, + py::arg("path")) + .def_static("is_source", &CompileCommands::is_source, + py::arg("path")) + + ; + } + public: static auto init_jucipp_module() { auto api = py::module("Jucipp", "API"); Module::init_terminal_module(api); Module::init_config_module(api); Module::init_cmake_module(api); + Module::init_compile_commands_module(api); return api.ptr(); }; }; From ee8226d22425ef63f83e2deb79680c7c3b773200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 6 Apr 2019 15:32:20 +0200 Subject: [PATCH 09/63] small cleanup --- src/plugins.cc | 20 +++++++++----------- src/python_module.h | 3 +-- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/plugins.cc b/src/plugins.cc index 96f27b3..fae6f2f 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -2,15 +2,16 @@ #include "config.h" #include "python_module.h" -Plugins::Plugins(): jucipp_module("Jucipp", Module::init_jucipp_module) { - auto &config = Config::get(); - config.load(); - const auto sys = py::module::import("sys"); - sys.attr("path").cast().append(config.plugins.path); - } +Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { + auto &config = Config::get(); + config.load(); + py::module::import("sys") + .attr("path") + .cast() + .append(config.plugins.path); +} void Plugins::load() { - std::cout << Config::get().plugins.path << std::endl; boost::filesystem::directory_iterator end_it; for(boost::filesystem::directory_iterator it(Config::get().plugins.path); it != end_it; it++) { auto module_name = it->path().stem().string(); @@ -27,15 +28,12 @@ void Plugins::load() { interpreter.reload_module(module); } else { Terminal::get().print("Loading plugin ´" + module_name + "´\n"); - py::module::import(module_name.c_str()); + py::module::import(module_name.c_str()); } - } catch(py::error_already_set &error) { Terminal::get().print("Error loading plugin `" + module_name + "`:\n" + error.what() + "\n"); } } - if(interpreter.error()) - std::cerr << py::error_already_set().what() << std::endl; } } diff --git a/src/python_module.h b/src/python_module.h index 8477d4a..b48e6ea 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -14,8 +14,7 @@ namespace pybind11 { public: PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); bool load(handle src, bool) { - const std::string path = pybind11::str(src); - value = path; + value = pybind11::str(src); return !PyErr_Occurred(); } From 3879f9b0d8782c9570234e62839851f217bc71b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 6 Apr 2019 16:53:53 +0200 Subject: [PATCH 10/63] bind ctags class --- src/python_module.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/python_module.h b/src/python_module.h index b48e6ea..7e64d45 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -2,9 +2,11 @@ #include "cmake.h" #include "compile_commands.h" #include "config.h" +#include "ctags.h" #include "python_bind.h" #include "terminal.h" #include +#include #include namespace pybind11 { @@ -197,6 +199,33 @@ class Module { ; } + static void init_compile_ctags_module(pybind11::module &api) { + py::class_ ctags(api, "Ctags"); + py::class_(api, "Ctags") + .def_readwrite("file_path", &Ctags::Location::file_path) + .def_readwrite("line", &Ctags::Location::line) + .def_readwrite("index", &Ctags::Location::index) + .def_readwrite("symbol", &Ctags::Location::symbol) + .def_readwrite("scope", &Ctags::Location::scope) + .def_readwrite("source", &Ctags::Location::source) + .def("__bool__", &Ctags::Location::operator bool) + + ; + + ctags + .def_static("get_result", &Ctags::get_result, + py::arg("path")) + .def_static("get_location", &Ctags::get_location, + py::arg("line"), + py::arg("markup")) + .def_static("get_locations", &Ctags::get_locations, + py::arg("path"), + py::arg("name"), + py::arg("type")) + + ; + } + public: static auto init_jucipp_module() { auto api = py::module("Jucipp", "API"); From 6ae2d94dd1e59f192f5f78677bb7581ae2b4fda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 15 Apr 2019 16:16:31 +0200 Subject: [PATCH 11/63] partially bind lldb debugger --- src/python_module.h | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/python_module.h b/src/python_module.h index 7e64d45..50cea6d 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -8,6 +8,10 @@ #include #include #include +#ifdef JUCI_ENABLE_DEBUG +#include "debug_lldb.h" +#endif + namespace pybind11 { namespace detail { @@ -226,6 +230,85 @@ class Module { ; } +#ifdef JUCI_ENABLE_DEBUG + static void init_debug_LLDB_module(pybind11::module &api) { + py::class_> dbg(api, "LLDB"); + py::class_(dbg, "Frame") + .def_readwrite("index", &Debug::LLDB::Frame::index) + .def_readwrite("module_filename", &Debug::LLDB::Frame::module_filename) + .def_readwrite("file_path", &Debug::LLDB::Frame::file_path) + .def_readwrite("function_name", &Debug::LLDB::Frame::function_name) + .def_readwrite("line_nr", &Debug::LLDB::Frame::line_nr) + .def_readwrite("line_index", &Debug::LLDB::Frame::line_index) + + ; + py::class_(dbg, "Variable") + .def_readwrite("thread_index_id", &Debug::LLDB::Variable::thread_index_id) + .def_readwrite("frame_index", &Debug::LLDB::Variable::frame_index) + .def_readwrite("name", &Debug::LLDB::Variable::name) + .def_readwrite("value", &Debug::LLDB::Variable::value) + .def_readwrite("declaration_found", &Debug::LLDB::Variable::declaration_found) + .def_readwrite("file_path", &Debug::LLDB::Variable::file_path) + .def_readwrite("line_nr", &Debug::LLDB::Variable::line_nr) + .def_readwrite("line_index", &Debug::LLDB::Variable::line_index) + + ; + + // py::class_(api, "SBProcess"); + // .def_readwrite("on_start", &Debug::LLDB::on_start) + // .def_readwrite("on_event", &Debug::LLDB::on_event) + + dbg + .def(py::init([]() { return &(Debug::LLDB::get()); })) + .def_readwrite("on_exit", &Debug::LLDB::on_exit) + // .def_readwrite("mutex", &Debug::LLDB::mutex) + .def("continue_debug", &Debug::LLDB::continue_debug) + .def("stop", &Debug::LLDB::stop) + .def("kill", &Debug::LLDB::kill) + .def("step_over", &Debug::LLDB::step_over) + .def("step_into", &Debug::LLDB::step_into) + .def("step_out", &Debug::LLDB::step_out) + .def("cancel", &Debug::LLDB::cancel) + .def("is_invalid", &Debug::LLDB::is_invalid) + .def("is_stopped", &Debug::LLDB::is_stopped) + .def("is_running", &Debug::LLDB::is_running) + .def("get_backtrace", &Debug::LLDB::get_backtrace) + .def("get_variables", &Debug::LLDB::get_variables) + .def("cancel", &Debug::LLDB::cancel) + .def("start", &Debug::LLDB::start, + py::arg("command"), + py::arg("path") = "", + py::arg("breakpoints") = std::vector>(), + py::arg("startup_commands") = std::vector(), + py::arg("remote_host") = "") + .def("run_command", &Debug::LLDB::run_command, + py::arg("command")) + .def("select_frame", &Debug::LLDB::select_frame, + py::arg("frame_index"), + py::arg("thread_index_id") = 0) + .def("get_value", &Debug::LLDB::get_value, + py::arg("variable"), + py::arg("file_path"), + py::arg("line_nr"), + py::arg("line_index")) + .def("get_return_value", &Debug::LLDB::get_return_value, + py::arg("file_path"), + py::arg("line_nr"), + py::arg("line_index")) + .def("add_breakpoint", &Debug::LLDB::add_breakpoint, + py::arg("file_path"), + py::arg("line_nr")) + .def("remove_breakpoint", &Debug::LLDB::remove_breakpoint, + py::arg("file_path"), + py::arg("line_nr"), + py::arg("line_count")) + .def(" write", &Debug::LLDB::write, + py::arg("buffer")) + + ; + } +#endif + public: static auto init_jucipp_module() { auto api = py::module("Jucipp", "API"); @@ -233,6 +316,9 @@ public: Module::init_config_module(api); Module::init_cmake_module(api); Module::init_compile_commands_module(api); +#ifdef JUCI_ENABLE_DEBUG + Module::init_debug_LLDB_module(api); +#endif return api.ptr(); }; }; From 8e6eaec757cbb09577e0e65f084c0f2851264f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 15 Apr 2019 18:41:30 +0200 Subject: [PATCH 12/63] wrap with string to ensure windows support --- src/python_module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_module.h b/src/python_module.h index 50cea6d..45d7665 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -20,7 +20,7 @@ namespace pybind11 { public: PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); bool load(handle src, bool) { - value = pybind11::str(src); + value = std::string(pybind11::str(src)); return !PyErr_Occurred(); } From 891edadc487b27e9c203bce4763d954f011cc6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 15 Apr 2019 19:47:46 +0200 Subject: [PATCH 13/63] bind dialogs module --- src/python_module.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/python_module.h b/src/python_module.h index 45d7665..eee365d 100644 --- a/src/python_module.h +++ b/src/python_module.h @@ -11,7 +11,7 @@ #ifdef JUCI_ENABLE_DEBUG #include "debug_lldb.h" #endif - +#include "dialogs.h" namespace pybind11 { namespace detail { @@ -309,6 +309,23 @@ class Module { } #endif + static void init_dialogs_module(py::module &api) { + py::class_(api, "Dialog") + .def_static("open_folder", Dialog::open_folder, + py::arg("path")) + + .def_static("open_file", Dialog::open_file, + py::arg("path")) + .def_static("new_file", Dialog::new_file, + py::arg("path")) + .def_static("new_folder", Dialog::new_folder, + py::arg("path")) + .def_static("save_file_as", Dialog::save_file_as, + py::arg("path")) + + ; + } + public: static auto init_jucipp_module() { auto api = py::module("Jucipp", "API"); @@ -319,6 +336,7 @@ public: #ifdef JUCI_ENABLE_DEBUG Module::init_debug_LLDB_module(api); #endif + Module::init_dialogs_module(api); return api.ptr(); }; }; From f583644a89c2a8c31f1e1d19fec263c50138a496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 18 Apr 2019 02:57:26 +0200 Subject: [PATCH 14/63] move binding code to respective files --- lib/tiny-process-library | 2 +- src/cmake.cpp | 16 ++ src/cmake.hpp | 4 +- src/compile_commands.cpp | 21 +++ src/compile_commands.hpp | 5 +- src/config.cpp | 105 ++++++++++++ src/config.hpp | 2 + src/ctags.cpp | 27 ++++ src/ctags.hpp | 2 + src/debug_lldb.cpp | 77 +++++++++ src/debug_lldb.hpp | 2 + src/dialogs.cpp | 17 ++ src/dialogs.hpp | 2 + src/dispatcher.cpp | 8 + src/dispatcher.hpp | 3 + src/plugins.cc | 24 ++- src/plugins.h | 28 +++- src/python_module.h | 342 --------------------------------------- src/terminal.cpp | 31 ++++ src/terminal.hpp | 2 + 20 files changed, 369 insertions(+), 351 deletions(-) delete mode 100644 src/python_module.h diff --git a/lib/tiny-process-library b/lib/tiny-process-library index c9c8bf8..6e52608 160000 --- a/lib/tiny-process-library +++ b/lib/tiny-process-library @@ -1 +1 @@ -Subproject commit c9c8bf810ddad8cd17882b9a9ee628a690e779f5 +Subproject commit 6e52608b15d12a13e68269b111afda3013e7cf3a diff --git a/src/cmake.cpp b/src/cmake.cpp index 8d11a1b..2befb21 100644 --- a/src/cmake.cpp +++ b/src/cmake.cpp @@ -349,3 +349,19 @@ void CMake::parse_file(const std::string &src, std::map(api, "CMake") + .def_readwrite("project_path", &CMake::project_path) + .def("update_default_build", &CMake::update_default_build, + py::arg("default_build_path"), + py::arg("force") = false) + .def("update_debug_build", &CMake::update_debug_build, + py::arg("debug_build_path"), + py::arg("force") = false) + .def("get_executable", &CMake::get_executable, + py::arg("build_path"), + py::arg("file_path")) + + ; +} diff --git a/src/cmake.hpp b/src/cmake.hpp index bfc5485..e4d5002 100644 --- a/src/cmake.hpp +++ b/src/cmake.hpp @@ -3,16 +3,16 @@ #include #include #include +#include "python_bind.h" class CMake { public: CMake(const boost::filesystem::path &path); boost::filesystem::path project_path; - bool update_default_build(const boost::filesystem::path &default_build_path, bool force = false); bool update_debug_build(const boost::filesystem::path &debug_build_path, bool force = false); - boost::filesystem::path get_executable(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path); + static void init_module(py::module &api); private: std::vector paths; diff --git a/src/compile_commands.cpp b/src/compile_commands.cpp index e5912b9..e6118b0 100644 --- a/src/compile_commands.cpp +++ b/src/compile_commands.cpp @@ -276,3 +276,24 @@ bool CompileCommands::is_source(const boost::filesystem::path &path) { else return false; } + +void CompileCommands::init_module(py::module &api) { + py::class_ compile_commands(api, "CompileCommands"); + py::class_(compile_commands, "CompileCommands") + .def_readwrite("directory", &CompileCommands::Command::directory) + .def_readwrite("parameters", &CompileCommands::Command::parameters) + .def_readwrite("file", &CompileCommands::Command::file) + + ; + compile_commands + .def_readwrite("commands", &CompileCommands::commands) + .def_static("get_arguments", &CompileCommands::get_arguments, + py::arg("build_path"), + py::arg("file_path")) + .def_static("is_header", &CompileCommands::is_header, + py::arg("path")) + .def_static("is_source", &CompileCommands::is_source, + py::arg("path")) + + ; +} diff --git a/src/compile_commands.hpp b/src/compile_commands.hpp index a76ee8a..8ec4949 100644 --- a/src/compile_commands.hpp +++ b/src/compile_commands.hpp @@ -1,4 +1,5 @@ #pragma once +#include "python_bind.h" #include #include #include @@ -21,16 +22,14 @@ public: boost::filesystem::path directory; std::vector parameters; boost::filesystem::path file; - std::vector parameter_values(const std::string ¶meter_name) const; }; CompileCommands(const boost::filesystem::path &build_path); std::vector commands; - /// Return arguments for the given file using libclangmm static std::vector get_arguments(const boost::filesystem::path &build_path, const boost::filesystem::path &file_path); - static bool is_header(const boost::filesystem::path &path); static bool is_source(const boost::filesystem::path &path); + static void init_module(py::module &api); }; diff --git a/src/config.cpp b/src/config.cpp index 941f77e..771e876 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -222,3 +222,108 @@ void Config::read(const boost::property_tree::ptree &cfg) { std::cout << "Plugins enabled" << std::endl; } } + +void Config::init_module(py::module &api) { + py::class_> config(api, "Config"); + config + .def(py::init([]() { return &(Config::get()); })) + .def("load", &Config::load) + .def_readonly("version", &Config::version) + + ; + py::class_(config, "Menu") + .def_readwrite("keys", &Config::Menu::keys) + + ; + py::class_(config, "Theme") + .def_readwrite("name", &Config::Theme::name) + .def_readwrite("variant", &Config::Theme::variant) + .def_readwrite("font", &Config::Theme::font) + + ; + py::class_(config, "Terminal") + .def_readwrite("history_size", &Config::Terminal::history_size) + .def_readwrite("font", &Config::Terminal::font) + + ; + py::class_ project(config, "Project"); + py::class_(project, "CMake") + .def_readwrite("command", &Config::Project::CMake::command) + .def_readwrite("compile_command", &Config::Project::CMake::compile_command) + + ; + py::class_(project, "Meson") + .def_readwrite("command", &Config::Project::Meson::command) + .def_readwrite("compile_command", &Config::Project::Meson::compile_command) + + ; + project + .def_readwrite("default_build_path", &Config::Project::default_build_path) + .def_readwrite("debug_build_path", &Config::Project::debug_build_path) + .def_readwrite("cmake", &Config::Project::cmake) + .def_readwrite("meson", &Config::Project::meson) + .def_readwrite("save_on_compile_or_run", &Config::Project::save_on_compile_or_run) + .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) + .def_readwrite("ctags_command", &Config::Project::ctags_command) + .def_readwrite("python_command", &Config::Project::python_command) + + ; + py::class_ source(config, "Source"); + py::class_(source, "DocumentationSearch") + .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) + .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) + + ; + source + .def_readwrite("style", &Config::Source::style) + .def_readwrite("font", &Config::Source::font) + .def_readwrite("spellcheck_language", &Config::Source::spellcheck_language) + .def_readwrite("cleanup_whitespace_characters", &Config::Source::cleanup_whitespace_characters) + .def_readwrite("show_whitespace_characters", &Config::Source::show_whitespace_characters) + .def_readwrite("format_style_on_save", &Config::Source::format_style_on_save) + .def_readwrite("format_style_on_save_if_style_file_found", &Config::Source::format_style_on_save_if_style_file_found) + .def_readwrite("smart_inserts", &Config::Source::smart_inserts) + .def_readwrite("show_map", &Config::Source::show_map) + .def_readwrite("map_font_size", &Config::Source::map_font_size) + .def_readwrite("show_git_diff", &Config::Source::show_git_diff) + .def_readwrite("show_background_pattern", &Config::Source::show_background_pattern) + .def_readwrite("show_right_margin", &Config::Source::show_right_margin) + .def_readwrite("right_margin_position", &Config::Source::right_margin_position) + .def_readwrite("auto_tab_char_and_size", &Config::Source::auto_tab_char_and_size) + .def_readwrite("default_tab_char", &Config::Source::default_tab_char) + .def_readwrite("default_tab_size", &Config::Source::default_tab_size) + .def_readwrite("tab_indents_line", &Config::Source::tab_indents_line) + .def_readwrite("wrap_lines", &Config::Source::wrap_lines) + .def_readwrite("highlight_current_line", &Config::Source::highlight_current_line) + .def_readwrite("show_line_numbers", &Config::Source::show_line_numbers) + .def_readwrite("enable_multiple_cursors", &Config::Source::enable_multiple_cursors) + .def_readwrite("auto_reload_changed_files", &Config::Source::auto_reload_changed_files) + .def_readwrite("clang_format_style", &Config::Source::clang_format_style) + .def_readwrite("clang_usages_threads", &Config::Source::clang_usages_threads) + .def_readwrite("documentation_searches", &Config::Source::documentation_searches) + + ; + + py::class_(config, "Log") + .def_readwrite("libclang", &Config::Log::libclang) + .def_readwrite("language_server", &Config::Log::language_server) + + ; + py::class_(config, "Plugins") + .def_readwrite("enabled", &Config::Plugins::enabled) + .def_readwrite("path", &Config::Plugins::path) + + ; + config + .def_readwrite("menu", &Config::menu) + .def_readwrite("theme", &Config::theme) + .def_readwrite("terminal", &Config::terminal) + .def_readwrite("project", &Config::project) + .def_readwrite("source", &Config::source) + .def_readwrite("log", &Config::log) + .def_readwrite("plugins", &Config::plugins) + .def_readwrite("home_path", &Config::home_path) + .def_readwrite("home_juci_path", &Config::home_juci_path) + + ; +} diff --git a/src/config.hpp b/src/config.hpp index 629314d..e7c2184 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -6,6 +6,7 @@ #include #include #include +#include "python_bind.h" class Config { public: @@ -141,6 +142,7 @@ public: boost::filesystem::path home_path; boost::filesystem::path home_juci_path; + static void init_module(py::module &api); private: /// Used to dispatch Terminal outputs after juCi++ GUI setup and configuration diff --git a/src/ctags.cpp b/src/ctags.cpp index ccde85e..f2a3596 100644 --- a/src/ctags.cpp +++ b/src/ctags.cpp @@ -278,3 +278,30 @@ std::vector Ctags::get_locations(const boost::filesystem::path return best_locations; } + +void Ctags::init_module(py::module &api) { + py::class_ ctags(api, "Ctags"); + py::class_(api, "Ctags") + .def_readwrite("file_path", &Ctags::Location::file_path) + .def_readwrite("line", &Ctags::Location::line) + .def_readwrite("index", &Ctags::Location::index) + .def_readwrite("symbol", &Ctags::Location::symbol) + .def_readwrite("scope", &Ctags::Location::scope) + .def_readwrite("source", &Ctags::Location::source) + .def("__bool__", &Ctags::Location::operator bool) + + ; + + ctags + .def_static("get_result", &Ctags::get_result, + py::arg("path")) + .def_static("get_location", &Ctags::get_location, + py::arg("line"), + py::arg("markup")) + .def_static("get_locations", &Ctags::get_locations, + py::arg("path"), + py::arg("name"), + py::arg("type")) + + ; +} \ No newline at end of file diff --git a/src/ctags.hpp b/src/ctags.hpp index d989006..ec891d1 100644 --- a/src/ctags.hpp +++ b/src/ctags.hpp @@ -1,4 +1,5 @@ #pragma once +#include "python_bind.h" #include #include #include @@ -28,6 +29,7 @@ public: std::stringstream output; static std::vector get_locations(const boost::filesystem::path &path, const std::string &name, const std::string &type, const std::string &languages = {}); + static void init_module(py::module &api); private: bool enable_scope, enable_kind; diff --git a/src/debug_lldb.cpp b/src/debug_lldb.cpp index e9dd9d8..5266df4 100644 --- a/src/debug_lldb.cpp +++ b/src/debug_lldb.cpp @@ -569,3 +569,80 @@ void Debug::LLDB::write(const std::string &buffer) { process->PutSTDIN(buffer.c_str(), buffer.size()); } } + +void Debug::LLDB::init_module(pybind11::module &api) { + py::class_> dbg(api, "LLDB"); + py::class_(dbg, "Frame") + .def_readwrite("index", &Debug::LLDB::Frame::index) + .def_readwrite("module_filename", &Debug::LLDB::Frame::module_filename) + .def_readwrite("file_path", &Debug::LLDB::Frame::file_path) + .def_readwrite("function_name", &Debug::LLDB::Frame::function_name) + .def_readwrite("line_nr", &Debug::LLDB::Frame::line_nr) + .def_readwrite("line_index", &Debug::LLDB::Frame::line_index) + + ; + py::class_(dbg, "Variable") + .def_readwrite("thread_index_id", &Debug::LLDB::Variable::thread_index_id) + .def_readwrite("frame_index", &Debug::LLDB::Variable::frame_index) + .def_readwrite("name", &Debug::LLDB::Variable::name) + .def_readwrite("value", &Debug::LLDB::Variable::value) + .def_readwrite("declaration_found", &Debug::LLDB::Variable::declaration_found) + .def_readwrite("file_path", &Debug::LLDB::Variable::file_path) + .def_readwrite("line_nr", &Debug::LLDB::Variable::line_nr) + .def_readwrite("line_index", &Debug::LLDB::Variable::line_index) + + ; + + // py::class_(api, "SBProcess"); + // .def_readwrite("on_start", &Debug::LLDB::on_start) + // .def_readwrite("on_event", &Debug::LLDB::on_event) + + dbg + .def(py::init([]() { return &(Debug::LLDB::get()); })) + .def_readwrite("on_exit", &Debug::LLDB::on_exit) + // .def_readwrite("mutex", &Debug::LLDB::mutex) + .def("continue_debug", &Debug::LLDB::continue_debug) + .def("stop", &Debug::LLDB::stop) + .def("kill", &Debug::LLDB::kill) + .def("step_over", &Debug::LLDB::step_over) + .def("step_into", &Debug::LLDB::step_into) + .def("step_out", &Debug::LLDB::step_out) + .def("cancel", &Debug::LLDB::cancel) + .def("is_invalid", &Debug::LLDB::is_invalid) + .def("is_stopped", &Debug::LLDB::is_stopped) + .def("is_running", &Debug::LLDB::is_running) + .def("get_backtrace", &Debug::LLDB::get_backtrace) + .def("get_variables", &Debug::LLDB::get_variables) + .def("cancel", &Debug::LLDB::cancel) + .def("start", &Debug::LLDB::start, + py::arg("command"), + py::arg("path") = "", + py::arg("breakpoints") = std::vector>(), + py::arg("startup_commands") = std::vector(), + py::arg("remote_host") = "") + .def("run_command", &Debug::LLDB::run_command, + py::arg("command")) + .def("select_frame", &Debug::LLDB::select_frame, + py::arg("frame_index"), + py::arg("thread_index_id") = 0) + .def("get_value", &Debug::LLDB::get_value, + py::arg("variable"), + py::arg("file_path"), + py::arg("line_nr"), + py::arg("line_index")) + .def("get_return_value", &Debug::LLDB::get_return_value, + py::arg("file_path"), + py::arg("line_nr"), + py::arg("line_index")) + .def("add_breakpoint", &Debug::LLDB::add_breakpoint, + py::arg("file_path"), + py::arg("line_nr")) + .def("remove_breakpoint", &Debug::LLDB::remove_breakpoint, + py::arg("file_path"), + py::arg("line_nr"), + py::arg("line_count")) + .def(" write", &Debug::LLDB::write, + py::arg("buffer")) + + ; +} diff --git a/src/debug_lldb.hpp b/src/debug_lldb.hpp index 21ea9ac..aef2f9e 100644 --- a/src/debug_lldb.hpp +++ b/src/debug_lldb.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "python_bind.h" namespace Debug { class LLDB { @@ -84,6 +85,7 @@ namespace Debug { void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count); void write(const std::string &buffer); + static void init_module(py::module &api); private: std::tuple, std::string, std::vector> parse_run_arguments(const std::string &command); diff --git a/src/dialogs.cpp b/src/dialogs.cpp index f0ef662..741fbb4 100644 --- a/src/dialogs.cpp +++ b/src/dialogs.cpp @@ -94,3 +94,20 @@ std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::s dialog.add_button(button.first, button.second); return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; } + +void Dialog::init_module(py::module &api) { + py::class_(api, "Dialog") + .def_static("open_folder", Dialog::open_folder, + py::arg("path")) + + .def_static("open_file", Dialog::open_file, + py::arg("path")) + .def_static("new_file", Dialog::new_file, + py::arg("path")) + .def_static("new_folder", Dialog::new_folder, + py::arg("path")) + .def_static("save_file_as", Dialog::save_file_as, + py::arg("path")) + + ; +} diff --git a/src/dialogs.hpp b/src/dialogs.hpp index b4be549..28f019a 100644 --- a/src/dialogs.hpp +++ b/src/dialogs.hpp @@ -1,4 +1,5 @@ #pragma once +#include "python_bind.h" #include #include #include @@ -11,6 +12,7 @@ public: static std::string new_file(const boost::filesystem::path &path); static std::string new_folder(const boost::filesystem::path &path); static std::string save_file_as(const boost::filesystem::path &path); + static void init_module(py::module &api); class Message : public Gtk::Window { public: diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp index 1e1b555..f13dedb 100644 --- a/src/dispatcher.cpp +++ b/src/dispatcher.cpp @@ -40,3 +40,11 @@ void Dispatcher::reset() { functions.clear(); connect(); } + +void Dispatcher::init_module(py::module &api) { + py::class_(api, "Dispatcher") + .def(py::init()) + .def("disconnect", &Dispatcher::disconnect) + .def("post", &Dispatcher::post &>) + + ; diff --git a/src/dispatcher.hpp b/src/dispatcher.hpp index fe8981c..38f1ac6 100644 --- a/src/dispatcher.hpp +++ b/src/dispatcher.hpp @@ -1,5 +1,6 @@ #pragma once #include "mutex.hpp" +#include "python_bind.h" #include #include #include @@ -32,4 +33,6 @@ public: /// Must be called from main GUI thread void reset(); + + static void init_module(py::module &api); }; diff --git a/src/plugins.cc b/src/plugins.cc index fae6f2f..935b75b 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -1,6 +1,28 @@ #include "plugins.h" +#include "cmake.h" +#include "compile_commands.h" #include "config.h" -#include "python_module.h" +#include "ctags.h" +#ifdef JUCI_ENABLE_DEBUG +#include "debug_lldb.h" +#endif +#include "dialogs.h" +#include "terminal.h" + +PyObject *Plugins::Module::init_jucipp_module() { + auto api = py::module("Jucipp", "API"); + CMake::init_module(api); + CompileCommands::init_module(api); + Config::init_module(api); + Ctags::init_module(api); +#ifdef JUCI_ENABLE_DEBUG + Debug::LLDB::init_module(api); +#endif + Dialog::init_module(api); + Dispatcher::init_module(api); + Terminal::init_module(api); + return api.ptr(); +}; Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { auto &config = Config::get(); diff --git a/src/plugins.h b/src/plugins.h index f7177b5..1b5079f 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -1,14 +1,38 @@ #pragma once - -#include #include "python_interpreter.h" +#include +#include + +namespace pybind11 { + namespace detail { + template <> + struct type_caster { + public: + PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); + bool load(handle src, bool) { + value = std::string(pybind11::str(src)); + return !PyErr_Occurred(); + } + + static handle cast(boost::filesystem::path src, return_value_policy, handle) { + return pybind11::str(src.string()); + } + }; + } // namespace detail +} // namespace pybind11 class __attribute__((visibility("default"))) Plugins { public: Plugins(); void load(); + private: + class Module { + public: + static PyObject *init_jucipp_module(); + }; + py::detail::embedded_module jucipp_module; Python::Interpreter interpreter; }; diff --git a/src/python_module.h b/src/python_module.h deleted file mode 100644 index eee365d..0000000 --- a/src/python_module.h +++ /dev/null @@ -1,342 +0,0 @@ -#pragma once -#include "cmake.h" -#include "compile_commands.h" -#include "config.h" -#include "ctags.h" -#include "python_bind.h" -#include "terminal.h" -#include -#include -#include -#ifdef JUCI_ENABLE_DEBUG -#include "debug_lldb.h" -#endif -#include "dialogs.h" - -namespace pybind11 { - namespace detail { - template <> - struct type_caster { - public: - PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); - bool load(handle src, bool) { - value = std::string(pybind11::str(src)); - return !PyErr_Occurred(); - } - - static handle cast(boost::filesystem::path src, return_value_policy, handle) { - return pybind11::str(src.string()); - } - }; - } // namespace detail -} // namespace pybind11 - -class Module { - static void init_terminal_module(pybind11::module &api) { - py::class_>(api, "Terminal") - .def(py::init([]() { return &(Terminal::get()); })) - .def("process", (int (Terminal::*)(const std::string &, const boost::filesystem::path &, bool)) & Terminal::process, - py::arg("command"), - py::arg("path") = "", - py::arg("use_pipes") = false) - .def("async_process", (void (Terminal::*)(const std::string &, const boost::filesystem::path &, const std::function &, bool)) & Terminal::async_process, - py::arg("command"), - py::arg("path") = "", - py::arg("callback") = nullptr, - py::arg("quiet") = false) - .def("kill_last_async_process", &Terminal::kill_last_async_process, - py::arg("force") = false) - .def("kill_async_processes", &Terminal::kill_async_processes, - py::arg("force") = false) - .def("print", &Terminal::print, - py::arg("message"), - py::arg("bold") = false) - .def("async_print", (void (Terminal::*)(const std::string &, bool)) & Terminal::async_print, - py::arg("message"), - py::arg("bold") = false) - .def("async_print", (void (Terminal::*)(size_t, const std::string &)) & Terminal::async_print, - py::arg("line_nr"), - py::arg("message")) - .def("configure", &Terminal::configure) - .def("clear", &Terminal::clear); - }; - - static void init_config_module(pybind11::module &api) { - py::class_> config(api, "Config"); - config - .def(py::init([]() { return &(Config::get()); })) - .def("load", &Config::load) - .def_readonly("version", &Config::version) - - ; - py::class_(config, "Menu") - .def_readwrite("keys", &Config::Menu::keys) - - ; - py::class_(config, "Theme") - .def_readwrite("name", &Config::Theme::name) - .def_readwrite("variant", &Config::Theme::variant) - .def_readwrite("font", &Config::Theme::font) - - ; - py::class_(config, "Terminal") - .def_readwrite("history_size", &Config::Terminal::history_size) - .def_readwrite("font", &Config::Terminal::font) - - ; - py::class_ project(config, "Project"); - py::class_(project, "CMake") - .def_readwrite("command", &Config::Project::CMake::command) - .def_readwrite("compile_command", &Config::Project::CMake::compile_command) - - ; - py::class_(project, "Meson") - .def_readwrite("command", &Config::Project::Meson::command) - .def_readwrite("compile_command", &Config::Project::Meson::compile_command) - - ; - project - .def_readwrite("default_build_path", &Config::Project::default_build_path) - .def_readwrite("debug_build_path", &Config::Project::debug_build_path) - .def_readwrite("cmake", &Config::Project::cmake) - .def_readwrite("meson", &Config::Project::meson) - .def_readwrite("save_on_compile_or_run", &Config::Project::save_on_compile_or_run) - .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) - .def_readwrite("ctags_command", &Config::Project::ctags_command) - .def_readwrite("python_command", &Config::Project::python_command) - - ; - py::class_ source(config, "Source"); - py::class_(source, "DocumentationSearch") - .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) - .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) - - ; - source - .def_readwrite("style", &Config::Source::style) - .def_readwrite("font", &Config::Source::font) - .def_readwrite("spellcheck_language", &Config::Source::spellcheck_language) - .def_readwrite("cleanup_whitespace_characters", &Config::Source::cleanup_whitespace_characters) - .def_readwrite("show_whitespace_characters", &Config::Source::show_whitespace_characters) - .def_readwrite("format_style_on_save", &Config::Source::format_style_on_save) - .def_readwrite("format_style_on_save_if_style_file_found", &Config::Source::format_style_on_save_if_style_file_found) - .def_readwrite("smart_inserts", &Config::Source::smart_inserts) - .def_readwrite("show_map", &Config::Source::show_map) - .def_readwrite("map_font_size", &Config::Source::map_font_size) - .def_readwrite("show_git_diff", &Config::Source::show_git_diff) - .def_readwrite("show_background_pattern", &Config::Source::show_background_pattern) - .def_readwrite("show_right_margin", &Config::Source::show_right_margin) - .def_readwrite("right_margin_position", &Config::Source::right_margin_position) - .def_readwrite("auto_tab_char_and_size", &Config::Source::auto_tab_char_and_size) - .def_readwrite("default_tab_char", &Config::Source::default_tab_char) - .def_readwrite("default_tab_size", &Config::Source::default_tab_size) - .def_readwrite("tab_indents_line", &Config::Source::tab_indents_line) - .def_readwrite("wrap_lines", &Config::Source::wrap_lines) - .def_readwrite("highlight_current_line", &Config::Source::highlight_current_line) - .def_readwrite("show_line_numbers", &Config::Source::show_line_numbers) - .def_readwrite("enable_multiple_cursors", &Config::Source::enable_multiple_cursors) - .def_readwrite("auto_reload_changed_files", &Config::Source::auto_reload_changed_files) - .def_readwrite("clang_format_style", &Config::Source::clang_format_style) - .def_readwrite("clang_usages_threads", &Config::Source::clang_usages_threads) - .def_readwrite("documentation_searches", &Config::Source::documentation_searches) - - ; - - py::class_(config, "Log") - .def_readwrite("libclang", &Config::Log::libclang) - .def_readwrite("language_server", &Config::Log::language_server) - - ; - py::class_(config, "Plugins") - .def_readwrite("enabled", &Config::Plugins::enabled) - .def_readwrite("path", &Config::Plugins::path) - - ; - config - .def_readwrite("menu", &Config::menu) - .def_readwrite("theme", &Config::theme) - .def_readwrite("terminal", &Config::terminal) - .def_readwrite("project", &Config::project) - .def_readwrite("source", &Config::source) - .def_readwrite("log", &Config::log) - .def_readwrite("plugins", &Config::plugins) - .def_readwrite("home_path", &Config::home_path) - .def_readwrite("home_juci_path", &Config::home_juci_path) - - ; - } - - static void init_cmake_module(pybind11::module &api) { - py::class_(api, "CMake") - .def_readwrite("project_path", &CMake::project_path) - .def("update_default_build", &CMake::update_default_build, - py::arg("default_build_path"), - py::arg("force") = false) - .def("update_debug_build", &CMake::update_debug_build, - py::arg("debug_build_path"), - py::arg("force") = false) - .def("get_executable", &CMake::get_executable, - py::arg("build_path"), - py::arg("file_path")) - - ; - } - - static void init_compile_commands_module(pybind11::module &api) { - py::class_ compile_commands(api, "CompileCommands"); - py::class_(compile_commands, "CompileCommands") - .def_readwrite("directory", &CompileCommands::Command::directory) - .def_readwrite("parameters", &CompileCommands::Command::parameters) - .def_readwrite("file", &CompileCommands::Command::file) - - ; - compile_commands - .def_readwrite("commands", &CompileCommands::commands) - .def_static("get_arguments", &CompileCommands::get_arguments, - py::arg("build_path"), - py::arg("file_path")) - .def_static("is_header", &CompileCommands::is_header, - py::arg("path")) - .def_static("is_source", &CompileCommands::is_source, - py::arg("path")) - - ; - } - - static void init_compile_ctags_module(pybind11::module &api) { - py::class_ ctags(api, "Ctags"); - py::class_(api, "Ctags") - .def_readwrite("file_path", &Ctags::Location::file_path) - .def_readwrite("line", &Ctags::Location::line) - .def_readwrite("index", &Ctags::Location::index) - .def_readwrite("symbol", &Ctags::Location::symbol) - .def_readwrite("scope", &Ctags::Location::scope) - .def_readwrite("source", &Ctags::Location::source) - .def("__bool__", &Ctags::Location::operator bool) - - ; - - ctags - .def_static("get_result", &Ctags::get_result, - py::arg("path")) - .def_static("get_location", &Ctags::get_location, - py::arg("line"), - py::arg("markup")) - .def_static("get_locations", &Ctags::get_locations, - py::arg("path"), - py::arg("name"), - py::arg("type")) - - ; - } - -#ifdef JUCI_ENABLE_DEBUG - static void init_debug_LLDB_module(pybind11::module &api) { - py::class_> dbg(api, "LLDB"); - py::class_(dbg, "Frame") - .def_readwrite("index", &Debug::LLDB::Frame::index) - .def_readwrite("module_filename", &Debug::LLDB::Frame::module_filename) - .def_readwrite("file_path", &Debug::LLDB::Frame::file_path) - .def_readwrite("function_name", &Debug::LLDB::Frame::function_name) - .def_readwrite("line_nr", &Debug::LLDB::Frame::line_nr) - .def_readwrite("line_index", &Debug::LLDB::Frame::line_index) - - ; - py::class_(dbg, "Variable") - .def_readwrite("thread_index_id", &Debug::LLDB::Variable::thread_index_id) - .def_readwrite("frame_index", &Debug::LLDB::Variable::frame_index) - .def_readwrite("name", &Debug::LLDB::Variable::name) - .def_readwrite("value", &Debug::LLDB::Variable::value) - .def_readwrite("declaration_found", &Debug::LLDB::Variable::declaration_found) - .def_readwrite("file_path", &Debug::LLDB::Variable::file_path) - .def_readwrite("line_nr", &Debug::LLDB::Variable::line_nr) - .def_readwrite("line_index", &Debug::LLDB::Variable::line_index) - - ; - - // py::class_(api, "SBProcess"); - // .def_readwrite("on_start", &Debug::LLDB::on_start) - // .def_readwrite("on_event", &Debug::LLDB::on_event) - - dbg - .def(py::init([]() { return &(Debug::LLDB::get()); })) - .def_readwrite("on_exit", &Debug::LLDB::on_exit) - // .def_readwrite("mutex", &Debug::LLDB::mutex) - .def("continue_debug", &Debug::LLDB::continue_debug) - .def("stop", &Debug::LLDB::stop) - .def("kill", &Debug::LLDB::kill) - .def("step_over", &Debug::LLDB::step_over) - .def("step_into", &Debug::LLDB::step_into) - .def("step_out", &Debug::LLDB::step_out) - .def("cancel", &Debug::LLDB::cancel) - .def("is_invalid", &Debug::LLDB::is_invalid) - .def("is_stopped", &Debug::LLDB::is_stopped) - .def("is_running", &Debug::LLDB::is_running) - .def("get_backtrace", &Debug::LLDB::get_backtrace) - .def("get_variables", &Debug::LLDB::get_variables) - .def("cancel", &Debug::LLDB::cancel) - .def("start", &Debug::LLDB::start, - py::arg("command"), - py::arg("path") = "", - py::arg("breakpoints") = std::vector>(), - py::arg("startup_commands") = std::vector(), - py::arg("remote_host") = "") - .def("run_command", &Debug::LLDB::run_command, - py::arg("command")) - .def("select_frame", &Debug::LLDB::select_frame, - py::arg("frame_index"), - py::arg("thread_index_id") = 0) - .def("get_value", &Debug::LLDB::get_value, - py::arg("variable"), - py::arg("file_path"), - py::arg("line_nr"), - py::arg("line_index")) - .def("get_return_value", &Debug::LLDB::get_return_value, - py::arg("file_path"), - py::arg("line_nr"), - py::arg("line_index")) - .def("add_breakpoint", &Debug::LLDB::add_breakpoint, - py::arg("file_path"), - py::arg("line_nr")) - .def("remove_breakpoint", &Debug::LLDB::remove_breakpoint, - py::arg("file_path"), - py::arg("line_nr"), - py::arg("line_count")) - .def(" write", &Debug::LLDB::write, - py::arg("buffer")) - - ; - } -#endif - - static void init_dialogs_module(py::module &api) { - py::class_(api, "Dialog") - .def_static("open_folder", Dialog::open_folder, - py::arg("path")) - - .def_static("open_file", Dialog::open_file, - py::arg("path")) - .def_static("new_file", Dialog::new_file, - py::arg("path")) - .def_static("new_folder", Dialog::new_folder, - py::arg("path")) - .def_static("save_file_as", Dialog::save_file_as, - py::arg("path")) - - ; - } - -public: - static auto init_jucipp_module() { - auto api = py::module("Jucipp", "API"); - Module::init_terminal_module(api); - Module::init_config_module(api); - Module::init_cmake_module(api); - Module::init_compile_commands_module(api); -#ifdef JUCI_ENABLE_DEBUG - Module::init_debug_LLDB_module(api); -#endif - Module::init_dialogs_module(api); - return api.ptr(); - }; -}; diff --git a/src/terminal.cpp b/src/terminal.cpp index 332b602..77885a4 100644 --- a/src/terminal.cpp +++ b/src/terminal.cpp @@ -603,3 +603,34 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { } return true; } + +void Terminal::init_module(pybind11::module &api) { + py::class_>(api, "Terminal") + .def(py::init([]() { return &(Terminal::get()); })) + .def("process", (int (Terminal::*)(const std::string &, const boost::filesystem::path &, bool)) & Terminal::process, + py::arg("command"), + py::arg("path") = "", + py::arg("use_pipes") = false) + .def("async_process", (void (Terminal::*)(const std::string &, const boost::filesystem::path &, const std::function &, bool)) & Terminal::async_process, + py::arg("command"), + py::arg("path") = "", + py::arg("callback") = nullptr, + py::arg("quiet") = false) + .def("kill_last_async_process", &Terminal::kill_last_async_process, + py::arg("force") = false) + .def("kill_async_processes", &Terminal::kill_async_processes, + py::arg("force") = false) + .def("print", &Terminal::print, + py::arg("message"), + py::arg("bold") = false) + .def("async_print", (void (Terminal::*)(const std::string &, bool)) & Terminal::async_print, + py::arg("message"), + py::arg("bold") = false) + .def("async_print", (void (Terminal::*)(size_t, const std::string &)) & Terminal::async_print, + py::arg("line_nr"), + py::arg("message")) + .def("configure", &Terminal::configure) + .def("clear", &Terminal::clear) + + ; +} diff --git a/src/terminal.hpp b/src/terminal.hpp index 3781e72..31cf1f6 100644 --- a/src/terminal.hpp +++ b/src/terminal.hpp @@ -2,6 +2,7 @@ #include "dispatcher.hpp" #include "mutex.hpp" #include "process.hpp" +#include "python_bind.h" #include "source_base.hpp" #include #include @@ -33,6 +34,7 @@ public: void configure(); void clear(); + static void init_module(pybind11::module &api); std::function scroll_to_bottom; From e08504e250b71b19be5b4add84a69bdd6d444b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 18 Apr 2019 15:26:20 +0200 Subject: [PATCH 15/63] bind cppreference --- src/documentation.cpp | 5 +++++ src/documentation.hpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/documentation.cpp b/src/documentation.cpp index 808e3f2..27fea53 100644 --- a/src/documentation.cpp +++ b/src/documentation.cpp @@ -12711,3 +12711,8 @@ std::experimental::filesystem::status_known cpp/experimental/fs/status_known return std::string(); return "http://en.cppreference.com/w/" + it->second; } + +void Documentation::CppReference::init_module(py::module &api) { + py::class_(api, "CppReference") + .def("get_url", &CppReference::get_url); +} diff --git a/src/documentation.hpp b/src/documentation.hpp index ceec3a2..078aa3f 100644 --- a/src/documentation.hpp +++ b/src/documentation.hpp @@ -1,4 +1,5 @@ #pragma once +#include "python_bind.h" #include #include @@ -7,5 +8,6 @@ namespace Documentation { public: static std::vector get_headers(const std::string &symbol) noexcept; static std::string get_url(const std::string &symbol) noexcept; + static void init_module(py::module &api); }; } // namespace Documentation From ba24942106b12b28b609a08aad8a5c6982178f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 19 Apr 2019 22:19:55 +0200 Subject: [PATCH 16/63] bind git --- src/git.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/git.hpp | 2 ++ src/plugins.cc | 2 ++ 3 files changed, 81 insertions(+) diff --git a/src/git.cpp b/src/git.cpp index c1cd09d..ef36ee2 100644 --- a/src/git.cpp +++ b/src/git.cpp @@ -261,3 +261,80 @@ boost::filesystem::path Git::path(const char *cpath, boost::optional cpa else return std::string(cpath, cpath_length); } + +void Git::init_module(py::module &api) { + py::class_ git(api, "Git"); + py::class_(git, "Error") + .def("__bool__", &Git::Error::operator bool) + .def_readwrite("code", &Git::Error::code) + + ; + + py::class_ repository(git, "Repository"); + py::class_ diff(repository, "Diff"); + py::class_(diff, "Lines") + .def_readwrite("added", &Git::Repository::Diff::Lines::added) + .def_readwrite("modified", &Git::Repository::Diff::Lines::modified) + .def_readwrite("removed", &Git::Repository::Diff::Lines::removed) + + ; + py::class_(repository, "Lines") + .def(py::init(), + py::arg("old_start"), + py::arg("old_size"), + py::arg("new_start"), + py::arg("new_size")) + .def_readwrite("old_lines", &Git::Repository::Diff::Hunk::old_lines) + .def_readwrite("new_lines", &Git::Repository::Diff::Hunk::new_lines) + + ; + diff + .def("get_lines", &Git::Repository::Diff::get_lines, + py::arg("buffer")) + .def_static("get_hunks", &Git::Repository::Diff::get_hunks, + py::arg("old_buffer"), + py::arg("new_buffer")) + .def("get_details", &Git::Repository::Diff::get_details, + py::arg("buffer"), + py::arg("line_nr")) + + ; + py::enum_(repository, "STATUS") + .value("CURRENT", Git::Repository::STATUS::CURRENT) + .value("NEW", Git::Repository::STATUS::NEW) + .value("MODIFIED", Git::Repository::STATUS::MODIFIED) + .value("DELETED", Git::Repository::STATUS::DELETED) + .value("RENAMED", Git::Repository::STATUS::RENAMED) + .value("TYPECHANGE", Git::Repository::STATUS::TYPECHANGE) + .value("UNREADABLE", Git::Repository::STATUS::UNREADABLE) + .value("IGNORED", Git::Repository::STATUS::IGNORED) + .value("CONFLICTED", Git::Repository::STATUS::CONFLICTED) + .export_values(); + + py::class_(repository, "Status") + .def_readwrite("added", &Git::Repository::Status::added) + .def_readwrite("modified", &Git::Repository::Status::modified) + + ; + + repository + .def_static("status_string", &Git::Repository::status_string, + py::arg("status")) + + .def("get_status", &Git::Repository::get_status) + .def("clear_saved_status", &Git::Repository::clear_saved_status) + .def("get_work_path", &Git::Repository::get_work_path) + .def_static("get_root_path", &Git::Repository::get_root_path, + py::arg("path")) + .def("get_diff", &Git::Repository::get_diff, + py::arg("path")) + .def("get_branch", &Git::Repository::get_branch) + + ; + + git + .def_static("get_repository", &Git::get_repository, + py::arg("path")) + + ; +} diff --git a/src/git.hpp b/src/git.hpp index c03d97e..b3db629 100644 --- a/src/git.hpp +++ b/src/git.hpp @@ -8,6 +8,7 @@ #include #include #include +#include "python_bind.h" class Git { friend class Repository; @@ -103,4 +104,5 @@ private: public: static std::shared_ptr get_repository(const boost::filesystem::path &path); + static void init_module(py::module &api); }; diff --git a/src/plugins.cc b/src/plugins.cc index 935b75b..350b2d0 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -8,6 +8,7 @@ #endif #include "dialogs.h" #include "terminal.h" +#include "git.h" PyObject *Plugins::Module::init_jucipp_module() { auto api = py::module("Jucipp", "API"); @@ -20,6 +21,7 @@ PyObject *Plugins::Module::init_jucipp_module() { #endif Dialog::init_module(api); Dispatcher::init_module(api); + Git::init_module(api); Terminal::init_module(api); return api.ptr(); }; From 0f4c4a7ce7bcd6ad8c796ae0cc73c10dfd06e9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 20 Apr 2019 13:44:59 +0200 Subject: [PATCH 17/63] fix tests after moving pybind code --- CMakeLists.txt | 3 -- src/juci.hpp | 2 -- tests/CMakeLists.txt | 54 +++++++++++++++++++++++++++++++- tests/python_interpreter_test.cc | 7 ++--- tests/stubs/config.cc | 5 +++ tests/stubs/config.cpp | 2 ++ 6 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 tests/stubs/config.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index f133543..356cba2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,10 +97,7 @@ if(${PYTHONLIBS_FOUND}) endif() if(${PYGOBJECT_FOUND}) - add_definitions(-DJUCI_ENABLE_PLUGINS) add_definitions(-DPYTHON_HOME_DIR=L"${PYTHON_LIBRARY_DIR}") -else() - message(STATUS "Python or pygobject not found. Building juCi++ without plugin support.") endif() set(BUILD_TESTING_SAVED ${BUILD_TESTING}) diff --git a/src/juci.hpp b/src/juci.hpp index 45b36c1..279ca8a 100644 --- a/src/juci.hpp +++ b/src/juci.hpp @@ -43,7 +43,5 @@ private: std::vector> files; std::vector errors; Window window; -#ifdef JUCI_ENABLE_PLUGINS Plugins plugins; -#endif }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2999a72..44ac878 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(test_stubs OBJECT stubs/selection_dialog.cpp ) +<<<<<<< HEAD if(BUILD_TESTING) add_executable(process_test process_test.cpp $) target_link_libraries(process_test juci_shared) @@ -120,10 +121,61 @@ if(BUILD_FUZZING) target_compile_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_libraries(markdown_fuzzer juci_shared) +======= +add_executable(process_test process_test.cc $) +target_link_libraries(process_test juci_shared ${PYTHON_LIBRARIES}) +add_test(process_test process_test) + +add_executable(compile_commands_test compile_commands_test.cc $) + target_link_libraries(compile_commands_test juci_shared ${PYTHON_LIBRARIES}) +add_test(compile_commands_test compile_commands_test) + +add_executable(filesystem_test filesystem_test.cc $) +target_link_libraries(filesystem_test juci_shared ${PYTHON_LIBRARIES}) +add_test(filesystem_test filesystem_test) + +add_executable(cmake_build_test cmake_build_test.cc $) +target_link_libraries(cmake_build_test juci_shared ${PYTHON_LIBRARIES}) +add_test(cmake_build_test cmake_build_test) + +add_executable(meson_build_test meson_build_test.cc $) +target_link_libraries(meson_build_test juci_shared ${PYTHON_LIBRARIES}) +add_test(meson_build_test meson_build_test) + +add_executable(source_test source_test.cc $) +target_link_libraries(source_test juci_shared ${PYTHON_LIBRARIES}) +add_test(source_test source_test) + +add_executable(source_clang_test source_clang_test.cc $) +target_link_libraries(source_clang_test juci_shared ${PYTHON_LIBRARIES}) +add_test(source_clang_test source_clang_test) + +add_executable(source_generic_test source_generic_test.cc $) +target_link_libraries(source_generic_test juci_shared ${PYTHON_LIBRARIES}) +add_test(source_generic_test source_generic_test) + +add_executable(source_key_test source_key_test.cc $) +target_link_libraries(source_key_test juci_shared ${PYTHON_LIBRARIES}) +add_test(source_key_test source_key_test) + +add_executable(terminal_test terminal_test.cc $) +target_link_libraries(terminal_test juci_shared ${PYTHON_LIBRARIES}) +add_test(terminal_test terminal_test) + +add_executable(usages_clang_test usages_clang_test.cc $) +target_link_libraries(usages_clang_test juci_shared ${PYTHON_LIBRARIES}) +add_test(usages_clang_test usages_clang_test) + +if(LIBLLDB_FOUND) + add_executable(lldb_test lldb_test.cc $) + target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) + add_test(lldb_test lldb_test) + add_subdirectory("lldb_test_files") +>>>>>>> de6858a... fix tests after moving pybind code endif() add_executable(git_test git_test.cc $) -target_link_libraries(git_test juci_shared) +target_link_libraries(git_test juci_shared ${PYTHON_LIBRARIES}) add_test(git_test git_test) add_executable(python_interpreter_test python_interpreter_test.cc $) diff --git a/tests/python_interpreter_test.cc b/tests/python_interpreter_test.cc index 3773e29..0fdabaa 100644 --- a/tests/python_interpreter_test.cc +++ b/tests/python_interpreter_test.cc @@ -1,24 +1,21 @@ #include "config.h" #include "plugins.h" #include "python_interpreter.h" -#include "python_module.h" #include "terminal.h" #include "config.h" -#include "python_module.h" class __attribute__((visibility("default"))) suite { public: Glib::RefPtr app = Gtk::Application::create(); - py::detail::embedded_module jucipp = py::detail::embedded_module("Jucipp", Module::init_jucipp_module); - Python::Interpreter interpreter; + Plugins plugins; Terminal &terminal = Terminal::get(); Config &config = Config::get(); boost::filesystem::path test_file_path = boost::filesystem::canonical(std::string(JUCI_TESTS_PATH) + "/python_interpreter_test_files"); bool has_assertion = false; suite() { - auto sys = interpreter.add_module("sys"); + auto sys = plugins.interpreter.add_module("sys"); sys.attr("path").cast().append(test_file_path.string()); config.terminal.history_size = 100; } diff --git a/tests/stubs/config.cc b/tests/stubs/config.cc new file mode 100644 index 0000000..2d75322 --- /dev/null +++ b/tests/stubs/config.cc @@ -0,0 +1,5 @@ +#include "config.h" + +Config::Config() {} +void Config::load() {} +void Config::init_module(py::module &) {} diff --git a/tests/stubs/config.cpp b/tests/stubs/config.cpp index 0445e5d..e798955 100644 --- a/tests/stubs/config.cpp +++ b/tests/stubs/config.cpp @@ -1,3 +1,5 @@ #include "config.hpp" Config::Config() {} +void Config::load() {} +void Config::init_module(py::module &) {} From 57a42c8f9ec6ca3dd373e8a2822a5c46e158ef7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 20 Apr 2019 13:46:04 +0200 Subject: [PATCH 18/63] bind some of menu --- src/menu.cpp | 14 ++++++++++++++ src/menu.hpp | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/menu.cpp b/src/menu.cpp index 5760594..ed69ea5 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -1,6 +1,7 @@ #include "menu.hpp" #include "config.hpp" #include +#include #include const Glib::ustring menu_xml = R"RAW( @@ -574,3 +575,16 @@ void Menu::build() { std::cerr << "building menu failed: " << ex.what(); } } + +void Menu::init_module(py::module &api) { + // TODO bind glib members + py::class_>(api, "Menu") + .def(py::init([] { return &Menu::get(); })) + .def("add_action", &Menu::add_action, + py::arg("name"), + py::arg("action")) + .def("set_keys", &Menu::set_keys) + .def("build", &Menu::build) + + ; +} diff --git a/src/menu.hpp b/src/menu.hpp index a6f56f8..6f1b6e0 100644 --- a/src/menu.hpp +++ b/src/menu.hpp @@ -1,4 +1,5 @@ #pragma once +#include "python_bind.h" #include #include #include @@ -24,6 +25,7 @@ public: std::unique_ptr right_click_line_menu; std::unique_ptr right_click_selected_menu; std::function toggle_menu_items = [] {}; + static void init_module(py::module &api); private: Glib::RefPtr builder; From 806173185161e606cd1081a96eabf1b7b5edc727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 27 Apr 2019 15:59:35 +0200 Subject: [PATCH 19/63] fix bug where two classes got the same name --- src/ctags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctags.cpp b/src/ctags.cpp index f2a3596..17c8199 100644 --- a/src/ctags.cpp +++ b/src/ctags.cpp @@ -281,7 +281,7 @@ std::vector Ctags::get_locations(const boost::filesystem::path void Ctags::init_module(py::module &api) { py::class_ ctags(api, "Ctags"); - py::class_(api, "Ctags") + py::class_(api, "Location") .def_readwrite("file_path", &Ctags::Location::file_path) .def_readwrite("line", &Ctags::Location::line) .def_readwrite("index", &Ctags::Location::index) From b898db575faff503fcb5f047ccf622160cafa543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 27 Apr 2019 17:08:15 +0200 Subject: [PATCH 20/63] make sure boost filesystem is type casted consistlty --- src/debug_lldb.cpp | 1 + src/plugins.h | 19 ----------------- src/python_type_casters.h | 21 +++++++++++++++++++ tests/python_interpreter_test.cc | 1 + .../terminal_test.py | 2 +- 5 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 src/python_type_casters.h diff --git a/src/debug_lldb.cpp b/src/debug_lldb.cpp index 5266df4..08f45e9 100644 --- a/src/debug_lldb.cpp +++ b/src/debug_lldb.cpp @@ -10,6 +10,7 @@ #include "utility.hpp" #include #include +#include extern char **environ; diff --git a/src/plugins.h b/src/plugins.h index 1b5079f..39f38a0 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -1,26 +1,7 @@ #pragma once #include "python_interpreter.h" -#include #include -namespace pybind11 { - namespace detail { - template <> - struct type_caster { - public: - PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); - bool load(handle src, bool) { - value = std::string(pybind11::str(src)); - return !PyErr_Occurred(); - } - - static handle cast(boost::filesystem::path src, return_value_policy, handle) { - return pybind11::str(src.string()); - } - }; - } // namespace detail -} // namespace pybind11 - class __attribute__((visibility("default"))) Plugins { public: diff --git a/src/python_type_casters.h b/src/python_type_casters.h new file mode 100644 index 0000000..42d0503 --- /dev/null +++ b/src/python_type_casters.h @@ -0,0 +1,21 @@ +#pragma once +#include "python_bind.h" +#include + +namespace pybind11 { + namespace detail { + template <> + struct type_caster { + public: + PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); + bool load(handle src, bool) { + value = std::string(pybind11::str(src)); + return !PyErr_Occurred(); + } + + static handle cast(boost::filesystem::path src, return_value_policy, handle) { + return pybind11::str(src.string()); + } + }; + } // namespace detail +} // namespace pybind11 diff --git a/tests/python_interpreter_test.cc b/tests/python_interpreter_test.cc index 0fdabaa..7376a51 100644 --- a/tests/python_interpreter_test.cc +++ b/tests/python_interpreter_test.cc @@ -3,6 +3,7 @@ #include "python_interpreter.h" #include "terminal.h" #include "config.h" +#include "python_type_casters.h" class __attribute__((visibility("default"))) diff --git a/tests/python_interpreter_test_files/terminal_test.py b/tests/python_interpreter_test_files/terminal_test.py index e2d3736..d8151d6 100644 --- a/tests/python_interpreter_test_files/terminal_test.py +++ b/tests/python_interpreter_test_files/terminal_test.py @@ -1,6 +1,6 @@ from Jucipp import Terminal -t = Terminal(); +t = Terminal() def hello_world(): t.print("Hello, World!\n") From 91ba2234fe3a2c575b55a8473c6abdea5566d301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 27 Apr 2019 18:48:47 +0200 Subject: [PATCH 21/63] refactor test suite to make room for tests of all bindings --- src/CMakeLists.txt | 3 + src/plugins.cc | 32 ++------ src/plugins.h | 5 -- src/python_module.cc | 27 +++++++ src/python_module.h | 7 ++ src/terminal.hpp | 1 + tests/CMakeLists.txt | 8 +- tests/python_bindings/CMakeLists.txt | 13 ++++ .../interpreter_test.cc | 25 ++++++ .../interpreter_test.py} | 0 .../Terminal_tests}/ls/hello_world.txt | 0 .../Terminal_tests/terminal_test.cc | 40 ++++++++++ .../Terminal_tests}/terminal_test.py | 0 tests/python_bindings/test_suite.cc | 12 +++ tests/python_bindings/test_suite.h | 16 ++++ tests/python_interpreter_test.cc | 76 ------------------- tests/stubs/plugins.cc | 6 ++ 17 files changed, 160 insertions(+), 111 deletions(-) create mode 100644 src/python_module.cc create mode 100644 src/python_module.h create mode 100644 tests/python_bindings/CMakeLists.txt create mode 100644 tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc rename tests/{python_interpreter_test_files/basic_test.py => python_bindings/PythonInterpreter_tests/interpreter_test.py} (100%) rename tests/{python_interpreter_test_files => python_bindings/Terminal_tests}/ls/hello_world.txt (100%) create mode 100644 tests/python_bindings/Terminal_tests/terminal_test.cc rename tests/{python_interpreter_test_files => python_bindings/Terminal_tests}/terminal_test.py (100%) create mode 100644 tests/python_bindings/test_suite.cc create mode 100644 tests/python_bindings/test_suite.h delete mode 100644 tests/python_interpreter_test.cc create mode 100644 tests/stubs/plugins.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fcce2b4..226a78e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,8 @@ set(JUCI_SHARED_FILES tooltips.cpp usages_clang.cpp utility.cpp + python_interpreter.cc + python_module.cc ) if(LIBLLDB_FOUND) list(APPEND JUCI_SHARED_FILES debug_lldb.cpp) @@ -56,6 +58,7 @@ set(JUCI_SOURCES selection_dialog.cpp tooltips.cpp window.cpp + plugins.cc ) if(APPLE) diff --git a/src/plugins.cc b/src/plugins.cc index 350b2d0..6539060 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -1,30 +1,7 @@ #include "plugins.h" -#include "cmake.h" -#include "compile_commands.h" -#include "config.h" -#include "ctags.h" -#ifdef JUCI_ENABLE_DEBUG -#include "debug_lldb.h" -#endif -#include "dialogs.h" +#include "python_module.h" #include "terminal.h" -#include "git.h" - -PyObject *Plugins::Module::init_jucipp_module() { - auto api = py::module("Jucipp", "API"); - CMake::init_module(api); - CompileCommands::init_module(api); - Config::init_module(api); - Ctags::init_module(api); -#ifdef JUCI_ENABLE_DEBUG - Debug::LLDB::init_module(api); -#endif - Dialog::init_module(api); - Dispatcher::init_module(api); - Git::init_module(api); - Terminal::init_module(api); - return api.ptr(); -}; +#include "config.h" Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { auto &config = Config::get(); @@ -47,10 +24,11 @@ void Plugins::load() { if((is_directory && !is_pycache) || has_py_extension) { try { auto module = interpreter.add_module(module_name); - if (module) { + if(module) { Terminal::get().print("Reloading plugin ´" + module_name + "´\n"); interpreter.reload_module(module); - } else { + } + else { Terminal::get().print("Loading plugin ´" + module_name + "´\n"); py::module::import(module_name.c_str()); } diff --git a/src/plugins.h b/src/plugins.h index 39f38a0..056be25 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -9,11 +9,6 @@ public: void load(); private: - class Module { - public: - static PyObject *init_jucipp_module(); - }; - py::detail::embedded_module jucipp_module; Python::Interpreter interpreter; }; diff --git a/src/python_module.cc b/src/python_module.cc new file mode 100644 index 0000000..69eedca --- /dev/null +++ b/src/python_module.cc @@ -0,0 +1,27 @@ +#include "python_module.h" +#include "cmake.h" +#include "compile_commands.h" +#include "config.h" +#include "ctags.h" +#ifdef JUCI_ENABLE_DEBUG +#include "debug_lldb.h" +#endif +#include "dialogs.h" +#include "terminal.h" +#include "git.h" + +PyObject *Module::init_jucipp_module() { + auto api = py::module("Jucipp", "API"); + CMake::init_module(api); + CompileCommands::init_module(api); + Config::init_module(api); + Ctags::init_module(api); +#ifdef JUCI_ENABLE_DEBUG + Debug::LLDB::init_module(api); +#endif + Dialog::init_module(api); + Dispatcher::init_module(api); + Git::init_module(api); + Terminal::init_module(api); + return api.ptr(); +} diff --git a/src/python_module.h b/src/python_module.h new file mode 100644 index 0000000..001655e --- /dev/null +++ b/src/python_module.h @@ -0,0 +1,7 @@ +#pragma once +#include "python_bind.h" + +class Module { +public: + static PyObject *init_jucipp_module(); +}; diff --git a/src/terminal.hpp b/src/terminal.hpp index 31cf1f6..c95cb4e 100644 --- a/src/terminal.hpp +++ b/src/terminal.hpp @@ -3,6 +3,7 @@ #include "mutex.hpp" #include "process.hpp" #include "python_bind.h" +#include "python_type_casters.h" #include "source_base.hpp" #include #include diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 44ac878..258d557 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,9 +19,10 @@ add_library(test_stubs OBJECT stubs/notebook.cpp stubs/project.cpp stubs/selection_dialog.cpp + stubs/tooltips.cpp + stubs/plugins.cc ) -<<<<<<< HEAD if(BUILD_TESTING) add_executable(process_test process_test.cpp $) target_link_libraries(process_test juci_shared) @@ -121,7 +122,8 @@ if(BUILD_FUZZING) target_compile_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_libraries(markdown_fuzzer juci_shared) -======= +endif() + add_executable(process_test process_test.cc $) target_link_libraries(process_test juci_shared ${PYTHON_LIBRARIES}) add_test(process_test process_test) @@ -171,7 +173,6 @@ if(LIBLLDB_FOUND) target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) add_test(lldb_test lldb_test) add_subdirectory("lldb_test_files") ->>>>>>> de6858a... fix tests after moving pybind code endif() add_executable(git_test git_test.cc $) @@ -182,3 +183,4 @@ add_executable(python_interpreter_test python_interpreter_test.cc $) +add_test(pb_python_interpreter_test pb_python_interpreter_test) + +add_executable(pb_terminal_test Terminal_tests/terminal_test.cc) +target_link_libraries(pb_terminal_test juci_shared test_suite $) +add_test(pb_terminal_test pb_terminal_test) diff --git a/tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc b/tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc new file mode 100644 index 0000000..2ef7681 --- /dev/null +++ b/tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc @@ -0,0 +1,25 @@ +#include "python_type_casters.h" +#include + +int main() { + { + suite test_suite("PythonInterpreter_tests"); + { + py::module::import("interpreter_test"); + test_suite.has_assertion = true; + } + } + { + suite test_suite("PythonInterpreter_tests"); + { + try { + py::module::import("exception_test"); + } + catch(const py::error_already_set &error) { + test_suite.has_assertion = true; + } + } + } + + return 0; +} diff --git a/tests/python_interpreter_test_files/basic_test.py b/tests/python_bindings/PythonInterpreter_tests/interpreter_test.py similarity index 100% rename from tests/python_interpreter_test_files/basic_test.py rename to tests/python_bindings/PythonInterpreter_tests/interpreter_test.py diff --git a/tests/python_interpreter_test_files/ls/hello_world.txt b/tests/python_bindings/Terminal_tests/ls/hello_world.txt similarity index 100% rename from tests/python_interpreter_test_files/ls/hello_world.txt rename to tests/python_bindings/Terminal_tests/ls/hello_world.txt diff --git a/tests/python_bindings/Terminal_tests/terminal_test.cc b/tests/python_bindings/Terminal_tests/terminal_test.cc new file mode 100644 index 0000000..89972b2 --- /dev/null +++ b/tests/python_bindings/Terminal_tests/terminal_test.cc @@ -0,0 +1,40 @@ +#include "test_suite.h" +#include "terminal.h" + +int main() { + const auto test_directory = "Terminal_tests"; + { + suite test_suite(test_directory); + { + auto &terminal = Terminal::get(); + auto connection = terminal.get_buffer()->signal_insert().connect([&](const Gtk::TextBuffer::iterator &, const Glib::ustring &msg, int) { + g_assert_cmpstr(msg.c_str(), ==, "Hello, World!\n"); + test_suite.has_assertion = true; + }); + auto module = py::module::import("terminal_test"); + module.attr("hello_world")(); + connection.disconnect(); + } + } + { + suite test_suite(test_directory); + { + auto &terminal = Terminal::get(); + auto connection = terminal.get_buffer()->signal_insert().connect([&](const Gtk::TextBuffer::iterator &, const Glib::ustring &msg, int) { + g_assert_cmpstr(msg.c_str(), ==, "hello_world.txt\n"); + test_suite.has_assertion = true; + test_suite.app->release(); + }); + test_suite.app->hold(); + std::thread thread([&] { + const auto ls_dir = test_suite.test_file_path / test_directory / "ls"; + auto module = py::module::import("terminal_test"); + auto res = module.attr("process")(ls_dir).cast(); + g_assert_cmpint(res, ==, 0); + }); + test_suite.app->run(); + thread.join(); + connection.disconnect(); + } + } +} \ No newline at end of file diff --git a/tests/python_interpreter_test_files/terminal_test.py b/tests/python_bindings/Terminal_tests/terminal_test.py similarity index 100% rename from tests/python_interpreter_test_files/terminal_test.py rename to tests/python_bindings/Terminal_tests/terminal_test.py diff --git a/tests/python_bindings/test_suite.cc b/tests/python_bindings/test_suite.cc new file mode 100644 index 0000000..ced4fcd --- /dev/null +++ b/tests/python_bindings/test_suite.cc @@ -0,0 +1,12 @@ +#include "test_suite.h" +#include "python_module.h" +#include + +suite::suite(const boost::filesystem::path &path) { + auto sys = py::module::import("sys"); + sys.attr("path").cast().append((test_file_path / path).string()); + config.terminal.history_size = 100; +} +suite::~suite() { + g_assert_true(has_assertion); +} diff --git a/tests/python_bindings/test_suite.h b/tests/python_bindings/test_suite.h new file mode 100644 index 0000000..95370cd --- /dev/null +++ b/tests/python_bindings/test_suite.h @@ -0,0 +1,16 @@ +#pragma once +#include "config.h" +#include "plugins.h" +#include + +class __attribute__((visibility("default"))) +suite { +public: + suite(const boost::filesystem::path &path); + Glib::RefPtr app = Gtk::Application::create(); + Config &config = Config::get(); + boost::filesystem::path test_file_path = boost::filesystem::canonical(std::string(JUCI_TESTS_PATH) + "/python_bindings"); + bool has_assertion = false; + Plugins plugins; + ~suite(); +}; diff --git a/tests/python_interpreter_test.cc b/tests/python_interpreter_test.cc deleted file mode 100644 index 7376a51..0000000 --- a/tests/python_interpreter_test.cc +++ /dev/null @@ -1,76 +0,0 @@ -#include "config.h" -#include "plugins.h" -#include "python_interpreter.h" -#include "terminal.h" -#include "config.h" -#include "python_type_casters.h" - - -class __attribute__((visibility("default"))) -suite { -public: - Glib::RefPtr app = Gtk::Application::create(); - Plugins plugins; - Terminal &terminal = Terminal::get(); - Config &config = Config::get(); - boost::filesystem::path test_file_path = boost::filesystem::canonical(std::string(JUCI_TESTS_PATH) + "/python_interpreter_test_files"); - bool has_assertion = false; - suite() { - auto sys = plugins.interpreter.add_module("sys"); - sys.attr("path").cast().append(test_file_path.string()); - config.terminal.history_size = 100; - } - ~suite() { - g_assert_true(has_assertion); - } -}; - -int main() { - { - suite test_suite; - { - py::module::import("basic_test"); - try { - py::module::import("exception_test"); - } - catch(const py::error_already_set &error) { - test_suite.has_assertion = true; - } - } - } - - { - suite test_suite; - { - auto connection = test_suite.terminal.get_buffer()->signal_insert().connect([&](const Gtk::TextBuffer::iterator &, const Glib::ustring &msg, int) { - g_assert_cmpstr(msg.c_str(), ==, "Hello, World!\n"); - test_suite.has_assertion = true; - }); - auto module = py::module::import("terminal_test"); - module.attr("hello_world")(); - connection.disconnect(); - } - } - { - suite test_suite; - { - auto connection = test_suite.terminal.get_buffer()->signal_insert().connect([&](const Gtk::TextBuffer::iterator &, const Glib::ustring &msg, int) { - g_assert_cmpstr(msg.c_str(), ==, "hello_world.txt\n"); - test_suite.has_assertion = true; - test_suite.app->release(); - }); - test_suite.app->hold(); - std::thread thread([&] { - const auto ls_dir = test_suite.test_file_path / "ls"; - auto module = py::module::import("terminal_test"); - auto res = module.attr("process")(ls_dir).cast(); - g_assert_cmpint(res, ==, 0); - }); - test_suite.app->run(); - thread.join(); - connection.disconnect(); - } - } - - return 0; -} diff --git a/tests/stubs/plugins.cc b/tests/stubs/plugins.cc new file mode 100644 index 0000000..c375e43 --- /dev/null +++ b/tests/stubs/plugins.cc @@ -0,0 +1,6 @@ +#include "plugins.h" +#include "python_module.h" + +Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) {} + +void Plugins::load() {} From 00e1282008157d0b9e6d925d08759b7455e791c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 27 Apr 2019 18:53:27 +0200 Subject: [PATCH 22/63] add very basic CMake test --- tests/python_bindings/CMakeLists.txt | 4 ++++ tests/python_bindings/CMake_tests/cmake_test.cc | 6 ++++++ tests/python_bindings/CMake_tests/cmake_test.py | 1 + 3 files changed, 11 insertions(+) create mode 100644 tests/python_bindings/CMake_tests/cmake_test.cc create mode 100644 tests/python_bindings/CMake_tests/cmake_test.py diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index 7eaf6e3..fc4b16c 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -8,6 +8,10 @@ add_executable(pb_python_interpreter_test PythonInterpreter_tests/interpreter_te target_link_libraries(pb_python_interpreter_test juci_shared test_suite $) add_test(pb_python_interpreter_test pb_python_interpreter_test) +add_executable(pb_cmake_test CMake_tests/cmake_test.cc) +target_link_libraries(pb_cmake_test juci_shared test_suite $) +add_test(pb_cmake_test pb_cmake_test) + add_executable(pb_terminal_test Terminal_tests/terminal_test.cc) target_link_libraries(pb_terminal_test juci_shared test_suite $) add_test(pb_terminal_test pb_terminal_test) diff --git a/tests/python_bindings/CMake_tests/cmake_test.cc b/tests/python_bindings/CMake_tests/cmake_test.cc new file mode 100644 index 0000000..780287f --- /dev/null +++ b/tests/python_bindings/CMake_tests/cmake_test.cc @@ -0,0 +1,6 @@ +#include "test_suite.h" + +int main() { + suite test_suite("CMake_tests"); + py::module::import("cmake_test"); +} \ No newline at end of file diff --git a/tests/python_bindings/CMake_tests/cmake_test.py b/tests/python_bindings/CMake_tests/cmake_test.py new file mode 100644 index 0000000..c20e897 --- /dev/null +++ b/tests/python_bindings/CMake_tests/cmake_test.py @@ -0,0 +1 @@ +from Jucipp import CMake From 32b5df10608518142dc8cc619f55094f3852deb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 27 Apr 2019 18:54:24 +0200 Subject: [PATCH 23/63] remove lldb tests for build check --- tests/CMakeLists.txt | 12 ++++++------ tests/python_bindings/CMake_tests/cmake_test.cc | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 258d557..47251fc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -168,12 +168,12 @@ add_executable(usages_clang_test usages_clang_test.cc $) - target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) - add_test(lldb_test lldb_test) - add_subdirectory("lldb_test_files") -endif() +# if(LIBLLDB_FOUND) +# add_executable(lldb_test lldb_test.cc $) +# target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) +# add_test(lldb_test lldb_test) +# add_subdirectory("lldb_test_files") +# endif() add_executable(git_test git_test.cc $) target_link_libraries(git_test juci_shared ${PYTHON_LIBRARIES}) diff --git a/tests/python_bindings/CMake_tests/cmake_test.cc b/tests/python_bindings/CMake_tests/cmake_test.cc index 780287f..cf0cd58 100644 --- a/tests/python_bindings/CMake_tests/cmake_test.cc +++ b/tests/python_bindings/CMake_tests/cmake_test.cc @@ -3,4 +3,5 @@ int main() { suite test_suite("CMake_tests"); py::module::import("cmake_test"); + test_suite.has_assertion = true; } \ No newline at end of file From c519c9dd94a21ee4b892303b9a3f51a8b0ef17dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Tue, 30 Apr 2019 15:41:37 +0200 Subject: [PATCH 24/63] remove interpreter wrapping --- src/CMakeLists.txt | 1 - src/plugins.cc | 15 ++++++++++- src/plugins.h | 4 +-- src/python_interpreter.cc | 39 ----------------------------- src/python_interpreter.h | 13 ---------- tests/python_bindings/test_suite.cc | 2 ++ tests/stubs/plugins.cc | 2 ++ 7 files changed, 20 insertions(+), 56 deletions(-) delete mode 100644 src/python_interpreter.cc delete mode 100644 src/python_interpreter.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 226a78e..6a5c802 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,7 +26,6 @@ set(JUCI_SHARED_FILES tooltips.cpp usages_clang.cpp utility.cpp - python_interpreter.cc python_module.cc ) if(LIBLLDB_FOUND) diff --git a/src/plugins.cc b/src/plugins.cc index 6539060..ce51b7a 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -1,17 +1,30 @@ #include "plugins.h" +#include "config.h" #include "python_module.h" #include "terminal.h" -#include "config.h" Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { auto &config = Config::get(); config.load(); +#ifdef PYTHON_HOME_DIR +#ifdef _WIN32 + const std::wstring python_home(PYTHON_HOME_DIR); + const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages" ); + Py_SetPythonHome(python_home.c_str()); + Py_SetPath(python_path.c_str()); +#endif +#endif + py::initialize_interpreter(); py::module::import("sys") .attr("path") .cast() .append(config.plugins.path); } +Plugins::~Plugins() { + py::finalize_interpreter(); +} + void Plugins::load() { boost::filesystem::directory_iterator end_it; for(boost::filesystem::directory_iterator it(Config::get().plugins.path); it != end_it; it++) { diff --git a/src/plugins.h b/src/plugins.h index 056be25..84d98ac 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -1,14 +1,14 @@ #pragma once -#include "python_interpreter.h" +#include "python_bind.h" #include class __attribute__((visibility("default"))) Plugins { public: Plugins(); + ~Plugins(); void load(); private: py::detail::embedded_module jucipp_module; - Python::Interpreter interpreter; }; diff --git a/src/python_interpreter.cc b/src/python_interpreter.cc deleted file mode 100644 index 5d5d2e0..0000000 --- a/src/python_interpreter.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "python_interpreter.h" - -pybind11::module Python::Interpreter::add_module(const std::string &module_name) { - return pybind11::reinterpret_borrow(PyImport_AddModule(module_name.c_str())); -} - -pybind11::object Python::Interpreter::error() { - return pybind11::reinterpret_borrow(PyErr_Occurred()); -} - -pybind11::module Python::Interpreter::reload_module(pybind11::module &module) { - auto reload = pybind11::reinterpret_steal(PyImport_ReloadModule(module.ptr())); - if(!reload) { - throw pybind11::error_already_set(); - } - return reload; -} - -#include -#include - -Python::Interpreter::~Interpreter() { - if (error()){ - std::cout << py::error_already_set().what() << std::endl; - } - py::finalize_interpreter(); -} - -Python::Interpreter::Interpreter() { -#ifdef PYTHON_HOME_DIR -#ifdef _WIN32 - const std::wstring python_home(PYTHON_HOME_DIR); - const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages" ); - Py_SetPythonHome(python_home.c_str()); - Py_SetPath(python_path.c_str()); -#endif -#endif - py::initialize_interpreter(); -} diff --git a/src/python_interpreter.h b/src/python_interpreter.h deleted file mode 100644 index 1986ab0..0000000 --- a/src/python_interpreter.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "python_bind.h" - -namespace Python { - class Interpreter { - public: - pybind11::module static add_module(const std::string &module_name); - pybind11::module static reload_module(pybind11::module &module); - pybind11::object static error(); - ~Interpreter(); - Interpreter(); - }; -}; // namespace Python diff --git a/tests/python_bindings/test_suite.cc b/tests/python_bindings/test_suite.cc index ced4fcd..670b3f2 100644 --- a/tests/python_bindings/test_suite.cc +++ b/tests/python_bindings/test_suite.cc @@ -3,10 +3,12 @@ #include suite::suite(const boost::filesystem::path &path) { + py::initialize_interpreter(); auto sys = py::module::import("sys"); sys.attr("path").cast().append((test_file_path / path).string()); config.terminal.history_size = 100; } suite::~suite() { + py::finalize_interpreter(); g_assert_true(has_assertion); } diff --git a/tests/stubs/plugins.cc b/tests/stubs/plugins.cc index c375e43..0c7dec5 100644 --- a/tests/stubs/plugins.cc +++ b/tests/stubs/plugins.cc @@ -4,3 +4,5 @@ Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) {} void Plugins::load() {} + +Plugins::~Plugins() {} From 05b5b5799721997c479ff7c53d2e414f7b432cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Tue, 30 Apr 2019 15:42:00 +0200 Subject: [PATCH 25/63] remove references to interpreter --- src/plugins.cc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/plugins.cc b/src/plugins.cc index ce51b7a..e572cd6 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -36,15 +36,8 @@ void Plugins::load() { const auto is_pycache = module_name == "__pycache__"; if((is_directory && !is_pycache) || has_py_extension) { try { - auto module = interpreter.add_module(module_name); - if(module) { - Terminal::get().print("Reloading plugin ´" + module_name + "´\n"); - interpreter.reload_module(module); - } - else { - Terminal::get().print("Loading plugin ´" + module_name + "´\n"); - py::module::import(module_name.c_str()); - } + auto module = py::module::import(module_name.c_str()); + Terminal::get().print("Loading plugin ´" + module_name + "´\n"); } catch(py::error_already_set &error) { Terminal::get().print("Error loading plugin `" + module_name + "`:\n" + error.what() + "\n"); From 730730784656fad7205cca195238addd54f1a1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Tue, 30 Apr 2019 15:42:29 +0200 Subject: [PATCH 26/63] compile target with files instead of linking --- tests/python_bindings/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index fc4b16c..a3abfac 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -4,14 +4,14 @@ target_link_libraries(test_suite juci_shared ${PYTHON_LIBRARIES}) include_directories(${CMAKE_SOURCE_DIR}/tests/python_bindings) -add_executable(pb_python_interpreter_test PythonInterpreter_tests/interpreter_test.cc) -target_link_libraries(pb_python_interpreter_test juci_shared test_suite $) +add_executable(pb_python_interpreter_test PythonInterpreter_tests/interpreter_test.cc $) +target_link_libraries(pb_python_interpreter_test juci_shared test_suite) add_test(pb_python_interpreter_test pb_python_interpreter_test) -add_executable(pb_cmake_test CMake_tests/cmake_test.cc) -target_link_libraries(pb_cmake_test juci_shared test_suite $) +add_executable(pb_cmake_test CMake_tests/cmake_test.cc $) +target_link_libraries(pb_cmake_test juci_shared test_suite) add_test(pb_cmake_test pb_cmake_test) -add_executable(pb_terminal_test Terminal_tests/terminal_test.cc) -target_link_libraries(pb_terminal_test juci_shared test_suite $) +add_executable(pb_terminal_test Terminal_tests/terminal_test.cc $) +target_link_libraries(pb_terminal_test juci_shared test_suite) add_test(pb_terminal_test pb_terminal_test) From 76e8e5dc54d3eab14d9c1a752647fa0ca07ba9b9 Mon Sep 17 00:00:00 2001 From: zalox Date: Mon, 6 May 2019 21:17:21 +0200 Subject: [PATCH 27/63] add paths for windows in test environment --- tests/stubs/plugins.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/stubs/plugins.cc b/tests/stubs/plugins.cc index 0c7dec5..10b5b94 100644 --- a/tests/stubs/plugins.cc +++ b/tests/stubs/plugins.cc @@ -1,7 +1,16 @@ #include "plugins.h" #include "python_module.h" -Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) {} +Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { +#ifdef PYTHON_HOME_DIR +#ifdef _WIN32 + const std::wstring python_home(PYTHON_HOME_DIR); + const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages" ); + Py_SetPythonHome(python_home.c_str()); + Py_SetPath(python_path.c_str()); +#endif +#endif +} void Plugins::load() {} From 7778752da0d1471e3fb4890ba488a628f6a9282e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 18 May 2019 15:01:37 +0200 Subject: [PATCH 28/63] disable lldb tests on debian due to an bug in python --- tests/CMakeLists.txt | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 47251fc..cba50ea 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -168,12 +168,21 @@ add_executable(usages_clang_test usages_clang_test.cc $) -# target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) -# add_test(lldb_test lldb_test) -# add_subdirectory("lldb_test_files") -# endif() +set(debian_version_file /etc/debian_version) +if(EXISTS ${debian_version_file}) + file(READ ${debian_version_file} debian_version) + message(${debian_version}) + if(${debian_version} EQUAL 9.9) + set(DEBIAN_STRETCH_FOUND True) + endif() +endif() + +if(LIBLLDB_FOUND AND NOT DEBIAN_STRETCH_FOUND) + add_executable(lldb_test lldb_test.cc $) + target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) + add_test(lldb_test lldb_test) + add_subdirectory("lldb_test_files") +endif() add_executable(git_test git_test.cc $) target_link_libraries(git_test juci_shared ${PYTHON_LIBRARIES}) From 95f15ef264453f934db3d05297cfba1e6c7f6f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 16:47:23 +0200 Subject: [PATCH 29/63] move python interpreter test to python module test --- tests/python_bindings/CMakeLists.txt | 10 +++++----- .../PythonModule_tests}/exception_test.py | 0 .../python_module_test.cc} | 6 +++--- .../python_module_test.py} | 0 4 files changed, 8 insertions(+), 8 deletions(-) rename tests/{python_interpreter_test_files => python_bindings/PythonModule_tests}/exception_test.py (100%) rename tests/python_bindings/{PythonInterpreter_tests/interpreter_test.cc => PythonModule_tests/python_module_test.cc} (69%) rename tests/python_bindings/{PythonInterpreter_tests/interpreter_test.py => PythonModule_tests/python_module_test.py} (100%) diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index a3abfac..559df74 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -4,14 +4,14 @@ target_link_libraries(test_suite juci_shared ${PYTHON_LIBRARIES}) include_directories(${CMAKE_SOURCE_DIR}/tests/python_bindings) -add_executable(pb_python_interpreter_test PythonInterpreter_tests/interpreter_test.cc $) -target_link_libraries(pb_python_interpreter_test juci_shared test_suite) -add_test(pb_python_interpreter_test pb_python_interpreter_test) +add_executable(pb_python_module_test PythonModule_tests/python_module_test.cc $) +target_link_libraries(pb_python_module_test test_suite) +add_test(pb_python_module_test pb_python_module_test) add_executable(pb_cmake_test CMake_tests/cmake_test.cc $) -target_link_libraries(pb_cmake_test juci_shared test_suite) +target_link_libraries(pb_cmake_test test_suite) add_test(pb_cmake_test pb_cmake_test) add_executable(pb_terminal_test Terminal_tests/terminal_test.cc $) -target_link_libraries(pb_terminal_test juci_shared test_suite) +target_link_libraries(pb_terminal_test test_suite) add_test(pb_terminal_test pb_terminal_test) diff --git a/tests/python_interpreter_test_files/exception_test.py b/tests/python_bindings/PythonModule_tests/exception_test.py similarity index 100% rename from tests/python_interpreter_test_files/exception_test.py rename to tests/python_bindings/PythonModule_tests/exception_test.py diff --git a/tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc b/tests/python_bindings/PythonModule_tests/python_module_test.cc similarity index 69% rename from tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc rename to tests/python_bindings/PythonModule_tests/python_module_test.cc index 2ef7681..b50d4b7 100644 --- a/tests/python_bindings/PythonInterpreter_tests/interpreter_test.cc +++ b/tests/python_bindings/PythonModule_tests/python_module_test.cc @@ -3,14 +3,14 @@ int main() { { - suite test_suite("PythonInterpreter_tests"); + suite test_suite("PythonModule_tests"); { - py::module::import("interpreter_test"); + py::module::import("python_module_test"); test_suite.has_assertion = true; } } { - suite test_suite("PythonInterpreter_tests"); + suite test_suite("PythonModule_tests"); { try { py::module::import("exception_test"); diff --git a/tests/python_bindings/PythonInterpreter_tests/interpreter_test.py b/tests/python_bindings/PythonModule_tests/python_module_test.py similarity index 100% rename from tests/python_bindings/PythonInterpreter_tests/interpreter_test.py rename to tests/python_bindings/PythonModule_tests/python_module_test.py From 3368b4ffc2294828b09f79a44a43c63691ba3b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 19:08:49 +0200 Subject: [PATCH 30/63] test cmake bindings --- src/cmake.cpp | 25 ++++++++++--------- .../CMake_tests/cmake_project/CMakeLists.txt | 7 ++++++ .../python_bindings/CMake_tests/cmake_test.cc | 18 ++++++++++--- .../python_bindings/CMake_tests/cmake_test.py | 11 ++++++++ 4 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt diff --git a/src/cmake.cpp b/src/cmake.cpp index 2befb21..7a485db 100644 --- a/src/cmake.cpp +++ b/src/cmake.cpp @@ -351,17 +351,18 @@ void CMake::parse_file(const std::string &src, std::map(api, "CMake") - .def_readwrite("project_path", &CMake::project_path) - .def("update_default_build", &CMake::update_default_build, - py::arg("default_build_path"), - py::arg("force") = false) - .def("update_debug_build", &CMake::update_debug_build, - py::arg("debug_build_path"), - py::arg("force") = false) - .def("get_executable", &CMake::get_executable, - py::arg("build_path"), - py::arg("file_path")) + py::class_(api, "CMake") + .def(py::init()) + .def_readwrite("project_path", &CMake::project_path) + .def("update_default_build", &CMake::update_default_build, + py::arg("default_build_path"), + py::arg("force") = false) + .def("update_debug_build", &CMake::update_debug_build, + py::arg("debug_build_path"), + py::arg("force") = false) + .def("get_executable", &CMake::get_executable, + py::arg("build_path"), + py::arg("file_path")) - ; + ; } diff --git a/tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt b/tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt new file mode 100644 index 0000000..6400f28 --- /dev/null +++ b/tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8) + +project(cmake_project) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra") + +add_executable(cmake_project main.cpp) diff --git a/tests/python_bindings/CMake_tests/cmake_test.cc b/tests/python_bindings/CMake_tests/cmake_test.cc index cf0cd58..89d45df 100644 --- a/tests/python_bindings/CMake_tests/cmake_test.cc +++ b/tests/python_bindings/CMake_tests/cmake_test.cc @@ -1,7 +1,17 @@ #include "test_suite.h" +#include int main() { - suite test_suite("CMake_tests"); - py::module::import("cmake_test"); - test_suite.has_assertion = true; -} \ No newline at end of file + auto &config = Config::get(); + config.project.cmake.command = "cmake"; + auto suite_name = "CMake_tests"; + suite test_suite(suite_name); + auto module = py::module::import("cmake_test"); + + try { + module.attr("run")((test_suite.test_file_path / suite_name / "cmake_project").string()); + test_suite.has_assertion = true; + } catch(const py::error_already_set &error){ + std::cout << error.what(); + } +} diff --git a/tests/python_bindings/CMake_tests/cmake_test.py b/tests/python_bindings/CMake_tests/cmake_test.py index c20e897..f413afb 100644 --- a/tests/python_bindings/CMake_tests/cmake_test.py +++ b/tests/python_bindings/CMake_tests/cmake_test.py @@ -1 +1,12 @@ from Jucipp import CMake + +def run(project_path): + cmake = CMake(project_path) + assert project_path == cmake.project_path, "Construction of CMake failed" + default_build_path = project_path + "/build" + assert cmake.update_default_build(default_build_path) == True, "Update of default build failed" + executable = cmake.get_executable(default_build_path, project_path) + assert executable == default_build_path + "/cmake_project", "Invalid executable" + default_debug_path = project_path + "/debug" + assert cmake.update_debug_build(default_debug_path), "Update of debug build failed" + executable = cmake.get_executable(default_debug_path, project_path) From f8127a76d2f3e34571206d6ec003718d9ebcbe1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 19:31:29 +0200 Subject: [PATCH 31/63] move cmake project one level up --- tests/python_bindings/CMake_tests/cmake_test.cc | 2 +- .../{CMake_tests => }/cmake_project/CMakeLists.txt | 4 ---- tests/python_bindings/cmake_project/main.cpp | 1 + 3 files changed, 2 insertions(+), 5 deletions(-) rename tests/python_bindings/{CMake_tests => }/cmake_project/CMakeLists.txt (58%) create mode 100644 tests/python_bindings/cmake_project/main.cpp diff --git a/tests/python_bindings/CMake_tests/cmake_test.cc b/tests/python_bindings/CMake_tests/cmake_test.cc index 89d45df..1f79d31 100644 --- a/tests/python_bindings/CMake_tests/cmake_test.cc +++ b/tests/python_bindings/CMake_tests/cmake_test.cc @@ -9,7 +9,7 @@ int main() { auto module = py::module::import("cmake_test"); try { - module.attr("run")((test_suite.test_file_path / suite_name / "cmake_project").string()); + module.attr("run")((test_suite.test_file_path / "cmake_project").string()); test_suite.has_assertion = true; } catch(const py::error_already_set &error){ std::cout << error.what(); diff --git a/tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt b/tests/python_bindings/cmake_project/CMakeLists.txt similarity index 58% rename from tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt rename to tests/python_bindings/cmake_project/CMakeLists.txt index 6400f28..c8eae37 100644 --- a/tests/python_bindings/CMake_tests/cmake_project/CMakeLists.txt +++ b/tests/python_bindings/cmake_project/CMakeLists.txt @@ -1,7 +1,3 @@ cmake_minimum_required(VERSION 2.8) - project(cmake_project) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra") - add_executable(cmake_project main.cpp) diff --git a/tests/python_bindings/cmake_project/main.cpp b/tests/python_bindings/cmake_project/main.cpp new file mode 100644 index 0000000..76e8197 --- /dev/null +++ b/tests/python_bindings/cmake_project/main.cpp @@ -0,0 +1 @@ +int main() { return 0; } From 3cf14b78415e676cfe5abfdbfe24d213226eb50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 20:48:04 +0200 Subject: [PATCH 32/63] add tests for compile commands and fix some bugs --- src/compile_commands.cpp | 7 +++- tests/python_bindings/CMakeLists.txt | 4 +++ .../compile_commands_test.cc | 21 ++++++++++++ .../compile_commands_test.py | 32 +++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/python_bindings/CompileCommands_tests/compile_commands_test.cc create mode 100644 tests/python_bindings/CompileCommands_tests/compile_commands_test.py diff --git a/src/compile_commands.cpp b/src/compile_commands.cpp index e6118b0..2ba6926 100644 --- a/src/compile_commands.cpp +++ b/src/compile_commands.cpp @@ -1,10 +1,12 @@ #include "compile_commands.hpp" #include "clangmm.hpp" #include "config.hpp" +#include "python_type_casters.h" #include "terminal.hpp" #include "utility.hpp" #include #include +#include #include CompileCommands::FindSystemIncludePaths::FindSystemIncludePaths() { @@ -279,13 +281,16 @@ bool CompileCommands::is_source(const boost::filesystem::path &path) { void CompileCommands::init_module(py::module &api) { py::class_ compile_commands(api, "CompileCommands"); - py::class_(compile_commands, "CompileCommands") + py::class_(compile_commands, "Command") .def_readwrite("directory", &CompileCommands::Command::directory) .def_readwrite("parameters", &CompileCommands::Command::parameters) .def_readwrite("file", &CompileCommands::Command::file) + .def("parameter_values", &CompileCommands::Command::parameter_values, + py::arg("parameter_name")) ; compile_commands + .def(py::init()) .def_readwrite("commands", &CompileCommands::commands) .def_static("get_arguments", &CompileCommands::get_arguments, py::arg("build_path"), diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index 559df74..8d2bd54 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -12,6 +12,10 @@ add_executable(pb_cmake_test CMake_tests/cmake_test.cc $) +target_link_libraries(pb_compile_commands_test test_suite) +add_test(pb_compile_commands_test pb_compile_commands_test) + add_executable(pb_terminal_test Terminal_tests/terminal_test.cc $) target_link_libraries(pb_terminal_test test_suite) add_test(pb_terminal_test pb_terminal_test) diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc new file mode 100644 index 0000000..6753ffb --- /dev/null +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc @@ -0,0 +1,21 @@ +#include "cmake.h" +#include "test_suite.h" +#include + +int main() { + auto suite_name = "CompileCommands_tests"; + suite test_suite(suite_name); + auto project_path = (test_suite.test_file_path / "cmake_project"); + auto &config = Config::get(); + config.project.cmake.command = "cmake"; + CMake cmake(project_path); + cmake.update_default_build(project_path/"build"); + try { + auto module = py::module::import("compile_commands_test"); + module.attr("run")(project_path.string()); + test_suite.has_assertion = true; + } + catch(const py::error_already_set &error) { + std::cout << error.what(); + } +} diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.py b/tests/python_bindings/CompileCommands_tests/compile_commands_test.py new file mode 100644 index 0000000..4601f01 --- /dev/null +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.py @@ -0,0 +1,32 @@ +from Jucipp import CompileCommands + +def run(project_path): + build_path = project_path + "/build" + cc = CompileCommands(build_path) + commands = cc.commands + assert len(commands) == 1, "Wrong length of compile commands" + command = commands.pop() + assert command.directory == build_path + assert command.file == project_path + "/main.cpp" + + params = command.parameters + param = params.pop() + assert param == project_path + "/main.cpp" + + param = params.pop() + assert param == "-c" + + param = params.pop() + param = params.pop() + assert param == "-o" + + values = command.parameter_values("-c") + value = values.pop() + assert value == project_path + "/main.cpp" + + assert CompileCommands.is_source(project_path + "/main.cpp") == True + assert CompileCommands.is_header(project_path + "/main.cpp") == False + + arguments = CompileCommands.get_arguments(build_path, project_path + "/main.cpp") + argument = arguments.pop() + assert argument == build_path From 53f1c755b7bd9bed2610513fea050ccb0577bbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 21:12:53 +0200 Subject: [PATCH 33/63] add basic config test --- src/CMakeLists.txt | 1 + src/config.cpp | 105 ----------------- src/config_module.cc | 106 ++++++++++++++++++ tests/python_bindings/CMakeLists.txt | 4 + .../Config_tests/config_test.cc | 14 +++ .../Config_tests/config_test.py | 3 + tests/stubs/config.cc | 1 - 7 files changed, 128 insertions(+), 106 deletions(-) create mode 100644 src/config_module.cc create mode 100644 tests/python_bindings/Config_tests/config_test.cc create mode 100644 tests/python_bindings/Config_tests/config_test.py diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a5c802..64c03c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,7 @@ set(JUCI_SHARED_FILES usages_clang.cpp utility.cpp python_module.cc + config_module.cc ) if(LIBLLDB_FOUND) list(APPEND JUCI_SHARED_FILES debug_lldb.cpp) diff --git a/src/config.cpp b/src/config.cpp index 771e876..941f77e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -222,108 +222,3 @@ void Config::read(const boost::property_tree::ptree &cfg) { std::cout << "Plugins enabled" << std::endl; } } - -void Config::init_module(py::module &api) { - py::class_> config(api, "Config"); - config - .def(py::init([]() { return &(Config::get()); })) - .def("load", &Config::load) - .def_readonly("version", &Config::version) - - ; - py::class_(config, "Menu") - .def_readwrite("keys", &Config::Menu::keys) - - ; - py::class_(config, "Theme") - .def_readwrite("name", &Config::Theme::name) - .def_readwrite("variant", &Config::Theme::variant) - .def_readwrite("font", &Config::Theme::font) - - ; - py::class_(config, "Terminal") - .def_readwrite("history_size", &Config::Terminal::history_size) - .def_readwrite("font", &Config::Terminal::font) - - ; - py::class_ project(config, "Project"); - py::class_(project, "CMake") - .def_readwrite("command", &Config::Project::CMake::command) - .def_readwrite("compile_command", &Config::Project::CMake::compile_command) - - ; - py::class_(project, "Meson") - .def_readwrite("command", &Config::Project::Meson::command) - .def_readwrite("compile_command", &Config::Project::Meson::compile_command) - - ; - project - .def_readwrite("default_build_path", &Config::Project::default_build_path) - .def_readwrite("debug_build_path", &Config::Project::debug_build_path) - .def_readwrite("cmake", &Config::Project::cmake) - .def_readwrite("meson", &Config::Project::meson) - .def_readwrite("save_on_compile_or_run", &Config::Project::save_on_compile_or_run) - .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) - .def_readwrite("ctags_command", &Config::Project::ctags_command) - .def_readwrite("python_command", &Config::Project::python_command) - - ; - py::class_ source(config, "Source"); - py::class_(source, "DocumentationSearch") - .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) - .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) - - ; - source - .def_readwrite("style", &Config::Source::style) - .def_readwrite("font", &Config::Source::font) - .def_readwrite("spellcheck_language", &Config::Source::spellcheck_language) - .def_readwrite("cleanup_whitespace_characters", &Config::Source::cleanup_whitespace_characters) - .def_readwrite("show_whitespace_characters", &Config::Source::show_whitespace_characters) - .def_readwrite("format_style_on_save", &Config::Source::format_style_on_save) - .def_readwrite("format_style_on_save_if_style_file_found", &Config::Source::format_style_on_save_if_style_file_found) - .def_readwrite("smart_inserts", &Config::Source::smart_inserts) - .def_readwrite("show_map", &Config::Source::show_map) - .def_readwrite("map_font_size", &Config::Source::map_font_size) - .def_readwrite("show_git_diff", &Config::Source::show_git_diff) - .def_readwrite("show_background_pattern", &Config::Source::show_background_pattern) - .def_readwrite("show_right_margin", &Config::Source::show_right_margin) - .def_readwrite("right_margin_position", &Config::Source::right_margin_position) - .def_readwrite("auto_tab_char_and_size", &Config::Source::auto_tab_char_and_size) - .def_readwrite("default_tab_char", &Config::Source::default_tab_char) - .def_readwrite("default_tab_size", &Config::Source::default_tab_size) - .def_readwrite("tab_indents_line", &Config::Source::tab_indents_line) - .def_readwrite("wrap_lines", &Config::Source::wrap_lines) - .def_readwrite("highlight_current_line", &Config::Source::highlight_current_line) - .def_readwrite("show_line_numbers", &Config::Source::show_line_numbers) - .def_readwrite("enable_multiple_cursors", &Config::Source::enable_multiple_cursors) - .def_readwrite("auto_reload_changed_files", &Config::Source::auto_reload_changed_files) - .def_readwrite("clang_format_style", &Config::Source::clang_format_style) - .def_readwrite("clang_usages_threads", &Config::Source::clang_usages_threads) - .def_readwrite("documentation_searches", &Config::Source::documentation_searches) - - ; - - py::class_(config, "Log") - .def_readwrite("libclang", &Config::Log::libclang) - .def_readwrite("language_server", &Config::Log::language_server) - - ; - py::class_(config, "Plugins") - .def_readwrite("enabled", &Config::Plugins::enabled) - .def_readwrite("path", &Config::Plugins::path) - - ; - config - .def_readwrite("menu", &Config::menu) - .def_readwrite("theme", &Config::theme) - .def_readwrite("terminal", &Config::terminal) - .def_readwrite("project", &Config::project) - .def_readwrite("source", &Config::source) - .def_readwrite("log", &Config::log) - .def_readwrite("plugins", &Config::plugins) - .def_readwrite("home_path", &Config::home_path) - .def_readwrite("home_juci_path", &Config::home_juci_path) - - ; -} diff --git a/src/config_module.cc b/src/config_module.cc new file mode 100644 index 0000000..54efc7d --- /dev/null +++ b/src/config_module.cc @@ -0,0 +1,106 @@ +#include "config.h" + +void Config::init_module(py::module &api) { + py::class_> config(api, "Config"); + config + .def(py::init([]() { return &(Config::get()); })) + .def("load", &Config::load) + .def_readonly("version", &Config::version) + + ; + py::class_(config, "Menu") + .def_readwrite("keys", &Config::Menu::keys) + + ; + py::class_(config, "Theme") + .def_readwrite("name", &Config::Theme::name) + .def_readwrite("variant", &Config::Theme::variant) + .def_readwrite("font", &Config::Theme::font) + + ; + py::class_(config, "Terminal") + .def_readwrite("history_size", &Config::Terminal::history_size) + .def_readwrite("font", &Config::Terminal::font) + + ; + py::class_ project(config, "Project"); + py::class_(project, "CMake") + .def_readwrite("command", &Config::Project::CMake::command) + .def_readwrite("compile_command", &Config::Project::CMake::compile_command) + + ; + py::class_(project, "Meson") + .def_readwrite("command", &Config::Project::Meson::command) + .def_readwrite("compile_command", &Config::Project::Meson::compile_command) + + ; + project + .def_readwrite("default_build_path", &Config::Project::default_build_path) + .def_readwrite("debug_build_path", &Config::Project::debug_build_path) + .def_readwrite("cmake", &Config::Project::cmake) + .def_readwrite("meson", &Config::Project::meson) + .def_readwrite("save_on_compile_or_run", &Config::Project::save_on_compile_or_run) + .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) + .def_readwrite("ctags_command", &Config::Project::ctags_command) + .def_readwrite("python_command", &Config::Project::python_command) + + ; + py::class_ source(config, "Source"); + py::class_(source, "DocumentationSearch") + .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) + .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) + + ; + source + .def_readwrite("style", &Config::Source::style) + .def_readwrite("font", &Config::Source::font) + .def_readwrite("spellcheck_language", &Config::Source::spellcheck_language) + .def_readwrite("cleanup_whitespace_characters", &Config::Source::cleanup_whitespace_characters) + .def_readwrite("show_whitespace_characters", &Config::Source::show_whitespace_characters) + .def_readwrite("format_style_on_save", &Config::Source::format_style_on_save) + .def_readwrite("format_style_on_save_if_style_file_found", &Config::Source::format_style_on_save_if_style_file_found) + .def_readwrite("smart_inserts", &Config::Source::smart_inserts) + .def_readwrite("show_map", &Config::Source::show_map) + .def_readwrite("map_font_size", &Config::Source::map_font_size) + .def_readwrite("show_git_diff", &Config::Source::show_git_diff) + .def_readwrite("show_background_pattern", &Config::Source::show_background_pattern) + .def_readwrite("show_right_margin", &Config::Source::show_right_margin) + .def_readwrite("right_margin_position", &Config::Source::right_margin_position) + .def_readwrite("auto_tab_char_and_size", &Config::Source::auto_tab_char_and_size) + .def_readwrite("default_tab_char", &Config::Source::default_tab_char) + .def_readwrite("default_tab_size", &Config::Source::default_tab_size) + .def_readwrite("tab_indents_line", &Config::Source::tab_indents_line) + .def_readwrite("wrap_lines", &Config::Source::wrap_lines) + .def_readwrite("highlight_current_line", &Config::Source::highlight_current_line) + .def_readwrite("show_line_numbers", &Config::Source::show_line_numbers) + .def_readwrite("enable_multiple_cursors", &Config::Source::enable_multiple_cursors) + .def_readwrite("auto_reload_changed_files", &Config::Source::auto_reload_changed_files) + .def_readwrite("clang_format_style", &Config::Source::clang_format_style) + .def_readwrite("clang_usages_threads", &Config::Source::clang_usages_threads) + .def_readwrite("documentation_searches", &Config::Source::documentation_searches) + + ; + + py::class_(config, "Log") + .def_readwrite("libclang", &Config::Log::libclang) + .def_readwrite("language_server", &Config::Log::language_server) + + ; + py::class_(config, "Plugins") + .def_readwrite("enabled", &Config::Plugins::enabled) + .def_readwrite("path", &Config::Plugins::path) + + ; + config + .def_readwrite("menu", &Config::menu) + .def_readwrite("theme", &Config::theme) + .def_readwrite("terminal", &Config::terminal) + .def_readwrite("project", &Config::project) + .def_readwrite("source", &Config::source) + .def_readwrite("log", &Config::log) + .def_readwrite("plugins", &Config::plugins) + .def_readwrite("home_path", &Config::home_path) + .def_readwrite("home_juci_path", &Config::home_juci_path) + + ; +} diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index 8d2bd54..41ef3c8 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -16,6 +16,10 @@ add_executable(pb_compile_commands_test CompileCommands_tests/compile_commands_t target_link_libraries(pb_compile_commands_test test_suite) add_test(pb_compile_commands_test pb_compile_commands_test) +add_executable(pb_config_test Config_tests/config_test.cc $) +target_link_libraries(pb_config_test test_suite) +add_test(pb_config_test pb_config_test) + add_executable(pb_terminal_test Terminal_tests/terminal_test.cc $) target_link_libraries(pb_terminal_test test_suite) add_test(pb_terminal_test pb_terminal_test) diff --git a/tests/python_bindings/Config_tests/config_test.cc b/tests/python_bindings/Config_tests/config_test.cc new file mode 100644 index 0000000..601a2d4 --- /dev/null +++ b/tests/python_bindings/Config_tests/config_test.cc @@ -0,0 +1,14 @@ +#include "test_suite.h" +#include + +int main() { + auto &config = Config::get(); + auto suite_name = "Config_tests"; + suite test_suite(suite_name); + try { + py::module::import("config_test"); + test_suite.has_assertion = true; + } catch(const py::error_already_set &error){ + std::cout << error.what(); + } +} diff --git a/tests/python_bindings/Config_tests/config_test.py b/tests/python_bindings/Config_tests/config_test.py new file mode 100644 index 0000000..f1be75f --- /dev/null +++ b/tests/python_bindings/Config_tests/config_test.py @@ -0,0 +1,3 @@ +from Jucipp import Config + +config = Config() diff --git a/tests/stubs/config.cc b/tests/stubs/config.cc index 2d75322..52f73ea 100644 --- a/tests/stubs/config.cc +++ b/tests/stubs/config.cc @@ -2,4 +2,3 @@ Config::Config() {} void Config::load() {} -void Config::init_module(py::module &) {} From 333fe0aa8179918b18632a8e624ed1ab64138541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 21:17:44 +0200 Subject: [PATCH 34/63] fix assignment bug and add default constructor --- src/config_module.cc | 2 ++ tests/python_bindings/Config_tests/config_test.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/config_module.cc b/src/config_module.cc index 54efc7d..06642d6 100644 --- a/src/config_module.cc +++ b/src/config_module.cc @@ -1,4 +1,5 @@ #include "config.h" +#include void Config::init_module(py::module &api) { py::class_> config(api, "Config"); @@ -9,6 +10,7 @@ void Config::init_module(py::module &api) { ; py::class_(config, "Menu") + .def(py::init()) .def_readwrite("keys", &Config::Menu::keys) ; diff --git a/tests/python_bindings/Config_tests/config_test.py b/tests/python_bindings/Config_tests/config_test.py index f1be75f..468c0c8 100644 --- a/tests/python_bindings/Config_tests/config_test.py +++ b/tests/python_bindings/Config_tests/config_test.py @@ -1,3 +1,9 @@ from Jucipp import Config config = Config() + +menu = Config.Menu() + +menu.keys = { + 'key': 'value', +} \ No newline at end of file From 6d04f7cff69ee0feba2cc20c9d49e05c9b7fcbb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 19 May 2019 21:18:07 +0200 Subject: [PATCH 35/63] add default contstructor for all subclasses of config --- src/config_module.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/config_module.cc b/src/config_module.cc index 06642d6..c6f66c8 100644 --- a/src/config_module.cc +++ b/src/config_module.cc @@ -3,40 +3,40 @@ void Config::init_module(py::module &api) { py::class_> config(api, "Config"); - config - .def(py::init([]() { return &(Config::get()); })) - .def("load", &Config::load) - .def_readonly("version", &Config::version) - ; py::class_(config, "Menu") .def(py::init()) .def_readwrite("keys", &Config::Menu::keys) ; py::class_(config, "Theme") + .def(py::init()) .def_readwrite("name", &Config::Theme::name) .def_readwrite("variant", &Config::Theme::variant) .def_readwrite("font", &Config::Theme::font) ; py::class_(config, "Terminal") + .def(py::init()) .def_readwrite("history_size", &Config::Terminal::history_size) .def_readwrite("font", &Config::Terminal::font) ; py::class_ project(config, "Project"); py::class_(project, "CMake") + .def(py::init()) .def_readwrite("command", &Config::Project::CMake::command) .def_readwrite("compile_command", &Config::Project::CMake::compile_command) ; py::class_(project, "Meson") + .def(py::init()) .def_readwrite("command", &Config::Project::Meson::command) .def_readwrite("compile_command", &Config::Project::Meson::compile_command) ; project + .def(py::init()) .def_readwrite("default_build_path", &Config::Project::default_build_path) .def_readwrite("debug_build_path", &Config::Project::debug_build_path) .def_readwrite("cmake", &Config::Project::cmake) @@ -49,11 +49,13 @@ void Config::init_module(py::module &api) { ; py::class_ source(config, "Source"); py::class_(source, "DocumentationSearch") + .def(py::init()) .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) ; source + .def(py::init()) .def_readwrite("style", &Config::Source::style) .def_readwrite("font", &Config::Source::font) .def_readwrite("spellcheck_language", &Config::Source::spellcheck_language) @@ -84,16 +86,21 @@ void Config::init_module(py::module &api) { ; py::class_(config, "Log") + .def(py::init()) .def_readwrite("libclang", &Config::Log::libclang) .def_readwrite("language_server", &Config::Log::language_server) ; py::class_(config, "Plugins") + .def(py::init()) .def_readwrite("enabled", &Config::Plugins::enabled) .def_readwrite("path", &Config::Plugins::path) ; config + .def(py::init([]() { return &(Config::get()); })) + .def("load", &Config::load) + .def_readonly("version", &Config::version) .def_readwrite("menu", &Config::menu) .def_readwrite("theme", &Config::theme) .def_readwrite("terminal", &Config::terminal) From 6afde6fe372076a1948c7a5b00bb9e5c107cf660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 25 May 2019 14:20:26 +0200 Subject: [PATCH 36/63] test all config options and fix two bugs in module --- src/config_module.cc | 3 +- .../Config_tests/config_test.cc | 94 +++++++++++++++++-- .../Config_tests/config_test.py | 90 +++++++++++++++++- 3 files changed, 172 insertions(+), 15 deletions(-) diff --git a/src/config_module.cc b/src/config_module.cc index c6f66c8..902a9aa 100644 --- a/src/config_module.cc +++ b/src/config_module.cc @@ -1,5 +1,6 @@ #include "config.h" #include +#include "python_type_casters.h" void Config::init_module(py::module &api) { py::class_> config(api, "Config"); @@ -51,7 +52,7 @@ void Config::init_module(py::module &api) { py::class_(source, "DocumentationSearch") .def(py::init()) .def_readwrite("separator", &Config::Source::DocumentationSearch::separator) - .def_readwrite("compile_command", &Config::Source::DocumentationSearch::queries) + .def_readwrite("queries", &Config::Source::DocumentationSearch::queries) ; source diff --git a/tests/python_bindings/Config_tests/config_test.cc b/tests/python_bindings/Config_tests/config_test.cc index 601a2d4..29c6b79 100644 --- a/tests/python_bindings/Config_tests/config_test.cc +++ b/tests/python_bindings/Config_tests/config_test.cc @@ -2,13 +2,89 @@ #include int main() { - auto &config = Config::get(); - auto suite_name = "Config_tests"; - suite test_suite(suite_name); - try { - py::module::import("config_test"); - test_suite.has_assertion = true; - } catch(const py::error_already_set &error){ - std::cout << error.what(); - } + const auto suite_name = "Config_tests"; + const auto doTest = [&](const std::string &test, const std::function &assertions) { + auto &config = Config::get(); + suite test_suite(suite_name); + try { + auto module = py::module::import("config_test"); + module.attr(test.c_str())(); + assertions(config); + test_suite.has_assertion = true; + } + catch(const py::error_already_set &error) { + std::cout << error.what(); + } + }; + + doTest("menu", [](Config &config) { + g_assert_cmpstr(config.menu.keys.at("key").c_str(), ==, "value"); + }); + + doTest("theme", [](Config &config) { + g_assert_cmpstr(config.theme.name.c_str(), ==, "Star Wars"); + g_assert_cmpstr(config.theme.variant.c_str(), ==, "Instrumental"); + g_assert_cmpstr(config.theme.font.c_str(), ==, "Imperial"); + }); + + doTest("terminal", [](Config &config) { + g_assert_cmpstr(config.terminal.font.c_str(), ==, "Comic Sans"); + g_assert_cmpuint(config.terminal.history_size, ==, 3); + }); + + doTest("project", [](Config &config) { + g_assert_cmpstr(config.project.default_build_path.c_str(), ==, "/build"); + g_assert_cmpstr(config.project.debug_build_path.c_str(), ==, "/debug"); + g_assert_cmpstr(config.project.meson.command.c_str(), ==, "meson"); + g_assert_cmpstr(config.project.meson.compile_command.c_str(), ==, "meson --build"); + g_assert_cmpstr(config.project.cmake.command.c_str(), ==, "cmake"); + g_assert_cmpstr(config.project.cmake.compile_command.c_str(), ==, "cmake --build"); + g_assert_true(config.project.save_on_compile_or_run); + g_assert_false(config.project.clear_terminal_on_compile); + g_assert_cmpstr(config.project.ctags_command.c_str(), ==, "ctags"); + g_assert_cmpstr(config.project.python_command.c_str(), ==, "python"); + }); + + doTest("source", [](Config &config) { + g_assert_cmpstr(config.source.style.c_str(), ==, "Classical"); + g_assert_cmpstr(config.source.font.c_str(), ==, "Monospaced"); + g_assert_cmpstr(config.source.spellcheck_language.c_str(), ==, "Klingon"); + g_assert_false(config.source.cleanup_whitespace_characters); + g_assert_cmpstr(config.source.show_whitespace_characters.c_str(), ==, "no"); + g_assert_false(config.source.format_style_on_save); + g_assert_false(config.source.format_style_on_save_if_style_file_found); + g_assert_false(config.source.smart_inserts); + g_assert_false(config.source.show_map); + g_assert_cmpstr(config.source.map_font_size.c_str(), ==, "10px"); + g_assert_false(config.source.show_git_diff); + g_assert_false(config.source.show_background_pattern); + g_assert_false(config.source.show_right_margin); + g_assert_cmpuint(config.source.right_margin_position, ==, 10); + g_assert_false(config.source.auto_tab_char_and_size); + g_assert_cmpint(config.source.default_tab_char, ==, 'c'); + g_assert_cmpuint(config.source.default_tab_size, ==, 1); + g_assert_false(config.source.tab_indents_line); + g_assert_false(config.source.wrap_lines); + g_assert_false(config.source.highlight_current_line); + g_assert_false(config.source.show_line_numbers); + g_assert_false(config.source.enable_multiple_cursors); + g_assert_false(config.source.auto_reload_changed_files); + g_assert_cmpstr(config.source.clang_format_style.c_str(), ==, "CFS"); + g_assert_cmpuint(config.source.clang_usages_threads, ==, 1); + g_assert_cmpuint(config.source.documentation_searches.size(), ==, 1); + auto ds = config.source.documentation_searches.at("cpp"); + g_assert_cmpstr(ds.separator.c_str(), ==, "::"); + g_assert_cmpint(ds.queries.size(), ==, 1); + g_assert_cmpstr(ds.queries.at("key").c_str(), ==, "value"); + }); + + doTest("log", [](Config &config) { + g_assert_true(config.log.libclang); + g_assert_false(config.log.language_server); + }); + + doTest("cfg", [](Config &config) { + g_assert_cmpstr(config.home_juci_path.c_str(), ==, "/away"); + g_assert_cmpstr(config.home_path.c_str(), ==, "/home"); + }); } diff --git a/tests/python_bindings/Config_tests/config_test.py b/tests/python_bindings/Config_tests/config_test.py index 468c0c8..55b5629 100644 --- a/tests/python_bindings/Config_tests/config_test.py +++ b/tests/python_bindings/Config_tests/config_test.py @@ -1,9 +1,89 @@ from Jucipp import Config -config = Config() +def menu(): + config = Config() + menu = Config.Menu() + menu.keys = { + 'key': 'value', + } + config.menu = menu -menu = Config.Menu() +def theme(): + theme = Config.Theme() + theme.name = "Star Wars" + theme.variant = "Instrumental" + theme.font = "Imperial" + config = Config() + config.theme = theme -menu.keys = { - 'key': 'value', -} \ No newline at end of file +def terminal(): + terminal = Config.Terminal() + terminal.font = "Comic Sans" + terminal.history_size = 3 + Config().terminal = terminal + +def project(): + project = Config.Project() + project.default_build_path = "/build" + project.debug_build_path = "/debug" + meson = Config.Project.Meson() + meson.command = "meson" + meson.compile_command = "meson --build" + cmake = Config.Project.CMake() + cmake.command = "cmake" + cmake.compile_command = "cmake --build" + project.meson = meson + project.cmake = cmake + project.save_on_compile_or_run = True + project.clear_terminal_on_compile = False + project.ctags_command = "ctags" + project.python_command = "python" + Config().project = project + +def source(): + source = Config.Source() + source.style = "Classical" + source.font = "Monospaced" + source.spellcheck_language = "Klingon" + source.cleanup_whitespace_characters = False + source.show_whitespace_characters = "no" + source.format_style_on_save = False + source.format_style_on_save_if_style_file_found = False + source.smart_inserts = False + source.show_map = False + source.map_font_size = "10px" + source.show_git_diff = False + source.show_background_pattern = False + source.show_right_margin = False + source.right_margin_position = 10 + source.auto_tab_char_and_size = False + source.default_tab_char = "c" + source.default_tab_size = 1 + source.tab_indents_line = False + source.wrap_lines = False + source.highlight_current_line = False + source.show_line_numbers = False + source.enable_multiple_cursors = False + source.auto_reload_changed_files = False + source.clang_format_style = "CFS" + source.clang_usages_threads = 1 + documentation_search = Config.Source.DocumentationSearch() + documentation_search.separator = '::' + documentation_search.queries = { + 'key': 'value', + } + source.documentation_searches = { + 'cpp' : documentation_search + } + Config().source = source + +def log(): + log = Config.Log() + log.libclang = True + log.language_server = False + Config().log = log + +def cfg(): + config = Config() + config.home_path = "/home" + config.home_juci_path = "/away" From ce37b55d0ba5e2c76c9e260ccd09c5117fba6505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 25 May 2019 14:22:01 +0200 Subject: [PATCH 37/63] move terminal target to top --- tests/python_bindings/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index 41ef3c8..e66c281 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -4,6 +4,10 @@ target_link_libraries(test_suite juci_shared ${PYTHON_LIBRARIES}) include_directories(${CMAKE_SOURCE_DIR}/tests/python_bindings) +add_executable(pb_terminal_test Terminal_tests/terminal_test.cc $) +target_link_libraries(pb_terminal_test test_suite) +add_test(pb_terminal_test pb_terminal_test) + add_executable(pb_python_module_test PythonModule_tests/python_module_test.cc $) target_link_libraries(pb_python_module_test test_suite) add_test(pb_python_module_test pb_python_module_test) @@ -19,7 +23,3 @@ add_test(pb_compile_commands_test pb_compile_commands_test) add_executable(pb_config_test Config_tests/config_test.cc $) target_link_libraries(pb_config_test test_suite) add_test(pb_config_test pb_config_test) - -add_executable(pb_terminal_test Terminal_tests/terminal_test.cc $) -target_link_libraries(pb_terminal_test test_suite) -add_test(pb_terminal_test pb_terminal_test) From c9055243c3ace9d02ba376c09427e53f347fba1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 25 May 2019 14:22:13 +0200 Subject: [PATCH 38/63] organize imports --- src/config_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config_module.cc b/src/config_module.cc index 902a9aa..119a5f0 100644 --- a/src/config_module.cc +++ b/src/config_module.cc @@ -1,6 +1,6 @@ #include "config.h" -#include #include "python_type_casters.h" +#include void Config::init_module(py::module &api) { py::class_> config(api, "Config"); From cdf8b4548f5a6ad496c4c2885569d3f84e0f93bb Mon Sep 17 00:00:00 2001 From: zalox Date: Sat, 25 May 2019 17:26:11 +0200 Subject: [PATCH 39/63] fix tests in compile_commands for windows and fix a bug in compile_commands.cc --- src/compile_commands.cpp | 2 +- .../compile_commands_test.cc | 16 +++++++-- .../compile_commands_test.py | 34 +++++++++++-------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/compile_commands.cpp b/src/compile_commands.cpp index 2ba6926..d28fa9a 100644 --- a/src/compile_commands.cpp +++ b/src/compile_commands.cpp @@ -109,7 +109,7 @@ CompileCommands::CompileCommands(const boost::filesystem::path &build_path) { if(parameter_start_pos != std::string::npos) add_parameter(); - commands.emplace_back(Command{directory, parameters, boost::filesystem::absolute(file, build_path)}); + commands.emplace_back(Command{directory.make_preferred(), parameters, boost::filesystem::absolute(file, build_path).make_preferred()}); } } catch(...) { diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc index 6753ffb..1e8226e 100644 --- a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc @@ -5,14 +5,24 @@ int main() { auto suite_name = "CompileCommands_tests"; suite test_suite(suite_name); - auto project_path = (test_suite.test_file_path / "cmake_project"); + auto project_path = test_suite.test_file_path / "cmake_project"; auto &config = Config::get(); +#ifdef _WIN32 + config.project.cmake.command = "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=/mingw64"; +#else config.project.cmake.command = "cmake"; +#endif CMake cmake(project_path); - cmake.update_default_build(project_path/"build"); + cmake.update_default_build(boost::filesystem::path(project_path) / "build"); try { auto module = py::module::import("compile_commands_test"); - module.attr("run")(project_path.string()); + std::string slash = +#ifdef _WIN32 + "\\"; +#else + "/"; +#endif + module.attr("run")(project_path.make_preferred().string(), slash); test_suite.has_assertion = true; } catch(const py::error_already_set &error) { diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.py b/tests/python_bindings/CompileCommands_tests/compile_commands_test.py index 4601f01..9ef2592 100644 --- a/tests/python_bindings/CompileCommands_tests/compile_commands_test.py +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.py @@ -1,32 +1,38 @@ from Jucipp import CompileCommands -def run(project_path): - build_path = project_path + "/build" +from os import path + +def assert_equal(expected, actual): + assert actual == expected, "Expected: " + expected + ", got " + actual + +def run(project_path, slash): + build_path = project_path + slash + "build" cc = CompileCommands(build_path) commands = cc.commands assert len(commands) == 1, "Wrong length of compile commands" command = commands.pop() - assert command.directory == build_path - assert command.file == project_path + "/main.cpp" + assert_equal(build_path, command.directory) + assert_equal(project_path + slash + "main.cpp", command.file) params = command.parameters - param = params.pop() - assert param == project_path + "/main.cpp" + param = path.basename(params.pop()) + assert_equal("main.cpp", param) param = params.pop() - assert param == "-c" + assert_equal("-c", param) param = params.pop() param = params.pop() - assert param == "-o" + assert_equal("-o", param) values = command.parameter_values("-c") - value = values.pop() - assert value == project_path + "/main.cpp" + value = path.basename(values.pop()) + assert_equal("main.cpp", value) - assert CompileCommands.is_source(project_path + "/main.cpp") == True - assert CompileCommands.is_header(project_path + "/main.cpp") == False + assert_equal(True, CompileCommands.is_source(project_path + slash + "main.cpp")) + assert_equal(False, CompileCommands.is_header(project_path + slash + "main.cpp")) - arguments = CompileCommands.get_arguments(build_path, project_path + "/main.cpp") + arguments = CompileCommands.get_arguments(build_path, project_path + slash + "main.cpp") argument = arguments.pop() - assert argument == build_path + + assert_equal(build_path, argument) \ No newline at end of file From b736400807676d48aec2a289606290680c0fa70d Mon Sep 17 00:00:00 2001 From: zalox Date: Sat, 25 May 2019 17:27:35 +0200 Subject: [PATCH 40/63] fix remaining tests on windows --- tests/python_bindings/CMake_tests/cmake_test.cc | 4 ++++ tests/python_bindings/Config_tests/config_test.cc | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/python_bindings/CMake_tests/cmake_test.cc b/tests/python_bindings/CMake_tests/cmake_test.cc index 1f79d31..512d959 100644 --- a/tests/python_bindings/CMake_tests/cmake_test.cc +++ b/tests/python_bindings/CMake_tests/cmake_test.cc @@ -3,7 +3,11 @@ int main() { auto &config = Config::get(); +#ifdef _WIN32 + config.project.cmake.command = "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=/mingw64"; +#else config.project.cmake.command = "cmake"; +#endif auto suite_name = "CMake_tests"; suite test_suite(suite_name); auto module = py::module::import("cmake_test"); diff --git a/tests/python_bindings/Config_tests/config_test.cc b/tests/python_bindings/Config_tests/config_test.cc index 29c6b79..b594670 100644 --- a/tests/python_bindings/Config_tests/config_test.cc +++ b/tests/python_bindings/Config_tests/config_test.cc @@ -84,7 +84,7 @@ int main() { }); doTest("cfg", [](Config &config) { - g_assert_cmpstr(config.home_juci_path.c_str(), ==, "/away"); - g_assert_cmpstr(config.home_path.c_str(), ==, "/home"); + g_assert_cmpstr(config.home_juci_path.string().c_str(), ==, "/away"); + g_assert_cmpstr(config.home_path.string().c_str(), ==, "/home"); }); } From be76f943741dc97f74e294867ef6027ef71ab9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 26 May 2019 13:48:59 +0200 Subject: [PATCH 41/63] small cleanup --- tests/python_bindings/Config_tests/config_test.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/python_bindings/Config_tests/config_test.py b/tests/python_bindings/Config_tests/config_test.py index 55b5629..610cbf3 100644 --- a/tests/python_bindings/Config_tests/config_test.py +++ b/tests/python_bindings/Config_tests/config_test.py @@ -1,20 +1,18 @@ from Jucipp import Config def menu(): - config = Config() menu = Config.Menu() menu.keys = { 'key': 'value', } - config.menu = menu + Config().menu = menu def theme(): theme = Config.Theme() theme.name = "Star Wars" theme.variant = "Instrumental" theme.font = "Imperial" - config = Config() - config.theme = theme + Config().theme = theme def terminal(): terminal = Config.Terminal() From ca7d9830b2fcc1a8fa2b4537a0edc63aa4bfdd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 26 May 2019 14:32:37 +0200 Subject: [PATCH 42/63] extract common method --- tests/python_bindings/CMake_tests/cmake_test.py | 10 ++++++---- .../CompileCommands_tests/compile_commands_test.py | 5 ++--- tests/python_bindings/jucipp_test.py | 5 +++++ 3 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 tests/python_bindings/jucipp_test.py diff --git a/tests/python_bindings/CMake_tests/cmake_test.py b/tests/python_bindings/CMake_tests/cmake_test.py index f413afb..777efee 100644 --- a/tests/python_bindings/CMake_tests/cmake_test.py +++ b/tests/python_bindings/CMake_tests/cmake_test.py @@ -1,12 +1,14 @@ from Jucipp import CMake +from jucipp_test import assert_equal + def run(project_path): cmake = CMake(project_path) - assert project_path == cmake.project_path, "Construction of CMake failed" + assert_equal(project_path, cmake.project_path) default_build_path = project_path + "/build" - assert cmake.update_default_build(default_build_path) == True, "Update of default build failed" + assert_equal(True, cmake.update_default_build(default_build_path)) executable = cmake.get_executable(default_build_path, project_path) - assert executable == default_build_path + "/cmake_project", "Invalid executable" + assert_equal(default_build_path + "/cmake_project", executable) default_debug_path = project_path + "/debug" - assert cmake.update_debug_build(default_debug_path), "Update of debug build failed" + assert_equal(True, cmake.update_debug_build(default_debug_path)) executable = cmake.get_executable(default_debug_path, project_path) diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.py b/tests/python_bindings/CompileCommands_tests/compile_commands_test.py index 9ef2592..3a90b6c 100644 --- a/tests/python_bindings/CompileCommands_tests/compile_commands_test.py +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.py @@ -2,8 +2,7 @@ from Jucipp import CompileCommands from os import path -def assert_equal(expected, actual): - assert actual == expected, "Expected: " + expected + ", got " + actual +from jucipp_test import assert_equal def run(project_path, slash): build_path = project_path + slash + "build" @@ -35,4 +34,4 @@ def run(project_path, slash): arguments = CompileCommands.get_arguments(build_path, project_path + slash + "main.cpp") argument = arguments.pop() - assert_equal(build_path, argument) \ No newline at end of file + assert_equal(build_path, argument) diff --git a/tests/python_bindings/jucipp_test.py b/tests/python_bindings/jucipp_test.py new file mode 100644 index 0000000..5584728 --- /dev/null +++ b/tests/python_bindings/jucipp_test.py @@ -0,0 +1,5 @@ +""" Shared test methods """ + +def assert_equal(expected, actual): + """ Assert two variables for equality with an useful error message """ + assert actual == expected, "Expected: " + expected + ", got " + actual From c3b4f217350afadb42e3878e48766c36420e0777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 31 May 2019 16:06:53 +0200 Subject: [PATCH 43/63] fix reference count bug in type caster --- CMakeLists.txt | 2 +- src/python_type_casters.h | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 356cba2..1fdbd23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ include(CPack) set(CMAKE_CXX_STANDARD 14) -add_compile_options(-pthread -Wall -Wextra -Wno-unused-parameter -Wno-deprecated-declarations) +add_compile_options(-pthread -Wall -Wextra -Wno-unused-parameter -Wno-deprecated-declarations -fvisibility=hidden) add_definitions(-DJUCI_VERSION="${JUCI_VERSION}") if(CMAKE_BUILD_TYPE STREQUAL "") add_compile_options(-O3) diff --git a/src/python_type_casters.h b/src/python_type_casters.h index 42d0503..69e1c6a 100644 --- a/src/python_type_casters.h +++ b/src/python_type_casters.h @@ -9,12 +9,19 @@ namespace pybind11 { public: PYBIND11_TYPE_CASTER(boost::filesystem::path, _("str")); bool load(handle src, bool) { - value = std::string(pybind11::str(src)); + if (!src) { + return false; + } + try { + value = std::string(py::str(src)); + } catch(...) { + return false; + } return !PyErr_Occurred(); } static handle cast(boost::filesystem::path src, return_value_policy, handle) { - return pybind11::str(src.string()); + return pybind11::str(src.string()).release(); } }; } // namespace detail From f8a607a8ab48c8561e84559a3938cb18c54c3abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 31 May 2019 16:09:36 +0200 Subject: [PATCH 44/63] fix some formatting and check for errors in suite --- .../CompileCommands_tests/compile_commands_test.cc | 8 ++------ tests/python_bindings/jucipp_test.py | 2 +- tests/python_bindings/test_suite.cc | 12 ++++++++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc index 1e8226e..1e5ff6d 100644 --- a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc @@ -8,20 +8,16 @@ int main() { auto project_path = test_suite.test_file_path / "cmake_project"; auto &config = Config::get(); #ifdef _WIN32 + std::string slash = "\\"; config.project.cmake.command = "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=/mingw64"; #else + std::string slash = "/"; config.project.cmake.command = "cmake"; #endif CMake cmake(project_path); cmake.update_default_build(boost::filesystem::path(project_path) / "build"); try { auto module = py::module::import("compile_commands_test"); - std::string slash = -#ifdef _WIN32 - "\\"; -#else - "/"; -#endif module.attr("run")(project_path.make_preferred().string(), slash); test_suite.has_assertion = true; } diff --git a/tests/python_bindings/jucipp_test.py b/tests/python_bindings/jucipp_test.py index 5584728..fdf9b59 100644 --- a/tests/python_bindings/jucipp_test.py +++ b/tests/python_bindings/jucipp_test.py @@ -2,4 +2,4 @@ def assert_equal(expected, actual): """ Assert two variables for equality with an useful error message """ - assert actual == expected, "Expected: " + expected + ", got " + actual + assert actual == expected, "Expected: " + str(expected) + ", got " + str(actual) diff --git a/tests/python_bindings/test_suite.cc b/tests/python_bindings/test_suite.cc index 670b3f2..c9c3666 100644 --- a/tests/python_bindings/test_suite.cc +++ b/tests/python_bindings/test_suite.cc @@ -4,11 +4,19 @@ suite::suite(const boost::filesystem::path &path) { py::initialize_interpreter(); + if(!Py_IsInitialized()) { + throw std::runtime_error("Unable to initialize interpreter"); + } auto sys = py::module::import("sys"); + if(!sys) { + throw std::runtime_error("Unable to append sys path"); + } sys.attr("path").cast().append((test_file_path / path).string()); config.terminal.history_size = 100; } suite::~suite() { - py::finalize_interpreter(); - g_assert_true(has_assertion); + if(Py_IsInitialized()) { + py::finalize_interpreter(); + g_assert_true(has_assertion); + } } From 86e6a1218075a174369a839ed84baa7100b4bffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 31 May 2019 16:20:49 +0200 Subject: [PATCH 45/63] add ctags test --- src/ctags.cpp | 5 +-- tests/python_bindings/CMakeLists.txt | 4 ++ .../python_bindings/Ctags_tests/ctags_test.cc | 39 +++++++++++++++++++ .../python_bindings/Ctags_tests/ctags_test.py | 27 +++++++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 tests/python_bindings/Ctags_tests/ctags_test.cc create mode 100644 tests/python_bindings/Ctags_tests/ctags_test.py diff --git a/src/ctags.cpp b/src/ctags.cpp index 17c8199..9a82a07 100644 --- a/src/ctags.cpp +++ b/src/ctags.cpp @@ -282,6 +282,7 @@ std::vector Ctags::get_locations(const boost::filesystem::path void Ctags::init_module(py::module &api) { py::class_ ctags(api, "Ctags"); py::class_(api, "Location") + .def(py::init<>()) .def_readwrite("file_path", &Ctags::Location::file_path) .def_readwrite("line", &Ctags::Location::line) .def_readwrite("index", &Ctags::Location::index) @@ -293,8 +294,6 @@ void Ctags::init_module(py::module &api) { ; ctags - .def_static("get_result", &Ctags::get_result, - py::arg("path")) .def_static("get_location", &Ctags::get_location, py::arg("line"), py::arg("markup")) @@ -304,4 +303,4 @@ void Ctags::init_module(py::module &api) { py::arg("type")) ; -} \ No newline at end of file +} diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index e66c281..a49ce81 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -23,3 +23,7 @@ add_test(pb_compile_commands_test pb_compile_commands_test) add_executable(pb_config_test Config_tests/config_test.cc $) target_link_libraries(pb_config_test test_suite) add_test(pb_config_test pb_config_test) + +add_executable(pb_ctags_test Ctags_tests/ctags_test.cc $) +target_link_libraries(pb_ctags_test test_suite) +add_test(pb_ctags_test pb_ctags_test) diff --git a/tests/python_bindings/Ctags_tests/ctags_test.cc b/tests/python_bindings/Ctags_tests/ctags_test.cc new file mode 100644 index 0000000..6d62afc --- /dev/null +++ b/tests/python_bindings/Ctags_tests/ctags_test.cc @@ -0,0 +1,39 @@ +#include "test_suite.h" +#include + +int main() { + auto &config = Config::get(); + config.project.ctags_command = "ctags"; +#ifdef _WIN32 + std::string slash = "\\"; + config.project.cmake.command = + "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=/mingw64"; +#else + auto slash = "/"; + config.project.cmake.command = "cmake"; +#endif + auto suite_name = "Ctags_tests"; + + { + auto doTest = [&](auto test) { + auto test_suite = suite(suite_name); + { + auto module = py::module::import("ctags_test"); + test_suite.has_assertion = false; + auto project_path = (test_suite.test_file_path / "cmake_project") + .make_preferred() + .string(); + try { + module.attr(test)(project_path, slash); + test_suite.has_assertion = true; + } + catch(const std::exception &error) { + std::cout << error.what(); + } + } + }; + + doTest("get_location"); + doTest("get_locations"); + } +} diff --git a/tests/python_bindings/Ctags_tests/ctags_test.py b/tests/python_bindings/Ctags_tests/ctags_test.py new file mode 100644 index 0000000..2f2e713 --- /dev/null +++ b/tests/python_bindings/Ctags_tests/ctags_test.py @@ -0,0 +1,27 @@ +from Jucipp import Ctags +from jucipp_test import assert_equal + +def get_location(a, b): + line = 'main main.cpp /^int main() { return 0; }$/;" line:1' + location = Ctags.get_location(line, False) + if location: + assert_equal('main.cpp', location.file_path) + assert_equal(0, location.line) + assert_equal(4, location.index) + assert_equal('main', location.symbol) + assert_equal('', location.scope) + assert_equal('int main() { return 0; }', location.source) + else: + raise ValueError('File path was empty') + +def get_locations(project_path, slash): + path = project_path + slash + 'main.cpp' + locations = Ctags.get_locations(project_path + slash + 'main.cpp', 'main', 'int ()') + assert_equal(len(locations), 1) + location = locations[0]; + assert_equal(path, location.file_path) + assert_equal(0, location.line) + assert_equal(4, location.index) + assert_equal('main', location.symbol) + assert_equal('', location.scope) + assert_equal('int main() { return 0; }', location.source) From ff0c52cc4534bcc6ca9c52205dfc4dd4b105d12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sat, 1 Jun 2019 00:21:52 +0200 Subject: [PATCH 46/63] add debug lldb test and fix bug with functional header missing --- src/debug_lldb.cpp | 4 +-- tests/python_bindings/CMakeLists.txt | 6 +++++ .../Debug_lldb_tests/debug_lldb_test.cc | 27 +++++++++++++++++++ .../Debug_lldb_tests/debug_lldb_test.py | 21 +++++++++++++++ tests/python_bindings/test_suite.cc | 4 ++- tests/python_bindings/test_suite.h | 1 + 6 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 tests/python_bindings/Debug_lldb_tests/debug_lldb_test.cc create mode 100644 tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py diff --git a/src/debug_lldb.cpp b/src/debug_lldb.cpp index 08f45e9..845181e 100644 --- a/src/debug_lldb.cpp +++ b/src/debug_lldb.cpp @@ -11,6 +11,7 @@ #include #include #include +#include extern char **environ; @@ -601,7 +602,6 @@ void Debug::LLDB::init_module(pybind11::module &api) { dbg .def(py::init([]() { return &(Debug::LLDB::get()); })) .def_readwrite("on_exit", &Debug::LLDB::on_exit) - // .def_readwrite("mutex", &Debug::LLDB::mutex) .def("continue_debug", &Debug::LLDB::continue_debug) .def("stop", &Debug::LLDB::stop) .def("kill", &Debug::LLDB::kill) @@ -642,7 +642,7 @@ void Debug::LLDB::init_module(pybind11::module &api) { py::arg("file_path"), py::arg("line_nr"), py::arg("line_count")) - .def(" write", &Debug::LLDB::write, + .def("write", &Debug::LLDB::write, py::arg("buffer")) ; diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index a49ce81..1c09093 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -27,3 +27,9 @@ add_test(pb_config_test pb_config_test) add_executable(pb_ctags_test Ctags_tests/ctags_test.cc $) target_link_libraries(pb_ctags_test test_suite) add_test(pb_ctags_test pb_ctags_test) + +if(LIBLLDB_FOUND AND NOT DEBIAN_STRETCH_FOUND) + add_executable(pb_debug_lldb_test Debug_lldb_tests/debug_lldb_test.cc $) + target_link_libraries(pb_debug_lldb_test test_suite) + add_test(pb_debug_lldb_test pb_debug_lldb_test) +endif() diff --git a/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.cc b/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.cc new file mode 100644 index 0000000..a999586 --- /dev/null +++ b/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.cc @@ -0,0 +1,27 @@ +#include "test_suite.h" +#include + +int main() { + auto &config = Config::get(); + config.project.ctags_command = "ctags"; + auto suite_name = "Debug_lldb_tests"; + { + auto doTest = [&](auto test) { + auto test_suite = suite(suite_name); + auto build_path = test_suite.build_file_path / "tests" / "lldb_test_files" / "lldb_test_executable"; + { + auto module = py::module::import("debug_lldb_test"); + test_suite.has_assertion = false; + try { + module.attr(test)(build_path.c_str()); + test_suite.has_assertion = true; + } + catch(const std::exception &error) { + std::cout << error.what(); + } + } + }; + + doTest("start_on_exit"); + } +} diff --git a/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py b/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py new file mode 100644 index 0000000..09e05fa --- /dev/null +++ b/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py @@ -0,0 +1,21 @@ +from Jucipp import LLDB +from time import sleep +from jucipp_test import assert_equal + + +exited = False + +def on_exit(exit_code): + assert_equal(0, exit_code) + global exited + exited = True + +def start_on_exit(exec_path): + print(exec_path) + l = LLDB() + l.on_exit = [on_exit] + l.start(exec_path, "", []) + + while not exited: + sleep(0.1) + l.cancel() diff --git a/tests/python_bindings/test_suite.cc b/tests/python_bindings/test_suite.cc index c9c3666..f391509 100644 --- a/tests/python_bindings/test_suite.cc +++ b/tests/python_bindings/test_suite.cc @@ -11,7 +11,9 @@ suite::suite(const boost::filesystem::path &path) { if(!sys) { throw std::runtime_error("Unable to append sys path"); } - sys.attr("path").cast().append((test_file_path / path).string()); + auto sys_path = sys.attr("path").cast(); + sys_path.append((test_file_path / path).string()); + sys_path.append((test_file_path).string()); config.terminal.history_size = 100; } suite::~suite() { diff --git a/tests/python_bindings/test_suite.h b/tests/python_bindings/test_suite.h index 95370cd..0b13f8c 100644 --- a/tests/python_bindings/test_suite.h +++ b/tests/python_bindings/test_suite.h @@ -10,6 +10,7 @@ public: Glib::RefPtr app = Gtk::Application::create(); Config &config = Config::get(); boost::filesystem::path test_file_path = boost::filesystem::canonical(std::string(JUCI_TESTS_PATH) + "/python_bindings"); + boost::filesystem::path build_file_path = boost::filesystem::canonical(JUCI_BUILD_PATH); bool has_assertion = false; Plugins plugins; ~suite(); From c5d40c1d0ebdf6fbed4b855ae073c231739608a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 8 Jul 2019 20:36:54 +0200 Subject: [PATCH 47/63] Add files --- src/debug_lldb.cpp | 7 ------- src/dispatcher.cpp | 1 + src/git.cpp | 3 --- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/debug_lldb.cpp b/src/debug_lldb.cpp index 845181e..49fe600 100644 --- a/src/debug_lldb.cpp +++ b/src/debug_lldb.cpp @@ -608,13 +608,11 @@ void Debug::LLDB::init_module(pybind11::module &api) { .def("step_over", &Debug::LLDB::step_over) .def("step_into", &Debug::LLDB::step_into) .def("step_out", &Debug::LLDB::step_out) - .def("cancel", &Debug::LLDB::cancel) .def("is_invalid", &Debug::LLDB::is_invalid) .def("is_stopped", &Debug::LLDB::is_stopped) .def("is_running", &Debug::LLDB::is_running) .def("get_backtrace", &Debug::LLDB::get_backtrace) .def("get_variables", &Debug::LLDB::get_variables) - .def("cancel", &Debug::LLDB::cancel) .def("start", &Debug::LLDB::start, py::arg("command"), py::arg("path") = "", @@ -626,11 +624,6 @@ void Debug::LLDB::init_module(pybind11::module &api) { .def("select_frame", &Debug::LLDB::select_frame, py::arg("frame_index"), py::arg("thread_index_id") = 0) - .def("get_value", &Debug::LLDB::get_value, - py::arg("variable"), - py::arg("file_path"), - py::arg("line_nr"), - py::arg("line_index")) .def("get_return_value", &Debug::LLDB::get_return_value, py::arg("file_path"), py::arg("line_nr"), diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp index f13dedb..5274389 100644 --- a/src/dispatcher.cpp +++ b/src/dispatcher.cpp @@ -48,3 +48,4 @@ void Dispatcher::init_module(py::module &api) { .def("post", &Dispatcher::post &>) ; +} diff --git a/src/git.cpp b/src/git.cpp index ef36ee2..631d875 100644 --- a/src/git.cpp +++ b/src/git.cpp @@ -318,9 +318,6 @@ void Git::init_module(py::module &api) { ; repository - .def_static("status_string", &Git::Repository::status_string, - py::arg("status")) - .def("get_status", &Git::Repository::get_status) .def("clear_saved_status", &Git::Repository::clear_saved_status) .def("get_work_path", &Git::Repository::get_work_path) From ecc2a4d642de1bfb2c958bfb6d12f05ba7372fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Mon, 7 Sep 2020 19:21:41 +0200 Subject: [PATCH 48/63] remove duplicate include --- CMakeLists.txt | 2 -- src/CMakeLists.txt | 1 - 2 files changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fdbd23..f484d62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,8 +102,6 @@ endif() set(BUILD_TESTING_SAVED ${BUILD_TESTING}) set(BUILD_TESTING OFF CACHE BOOL "Disable sub-project tests" FORCE) -add_subdirectory(lib/libclangmm) -add_subdirectory(lib/tiny-process-library) set(BUILD_TESTING ${BUILD_TESTING_SAVED} CACHE BOOL "Set to previous value" FORCE) find_package(Boost 1.54 COMPONENTS REQUIRED filesystem serialization) find_package(ASPELL REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64c03c9..f0f0007 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,6 @@ set(JUCI_SHARED_FILES meson.cpp project_build.cpp plugins.cc - python_interpreter.cc snippets.cpp source.cpp source_base.cpp From 03cf0990f27b0135da651e0fa46848df63bd626a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Mon, 7 Sep 2020 19:40:35 +0200 Subject: [PATCH 49/63] fix merge mistakes in tests --- src/ctags.cpp | 10 ++-- tests/CMakeLists.txt | 135 ++++++++++++------------------------------- 2 files changed, 44 insertions(+), 101 deletions(-) diff --git a/src/ctags.cpp b/src/ctags.cpp index 9a82a07..46226e0 100644 --- a/src/ctags.cpp +++ b/src/ctags.cpp @@ -294,13 +294,15 @@ void Ctags::init_module(py::module &api) { ; ctags - .def_static("get_location", &Ctags::get_location, - py::arg("line"), - py::arg("markup")) + .def("get_location", &Ctags::get_location, + py::arg("line"), + py::arg("add_markup"), + py::arg("symbol_ends_with_open_parenthesis")) .def_static("get_locations", &Ctags::get_locations, py::arg("path"), py::arg("name"), - py::arg("type")) + py::arg("type"), + py::arg("languages")) ; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cba50ea..662eded 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,7 +19,6 @@ add_library(test_stubs OBJECT stubs/notebook.cpp stubs/project.cpp stubs/selection_dialog.cpp - stubs/tooltips.cpp stubs/plugins.cc ) @@ -29,167 +28,109 @@ if(BUILD_TESTING) add_test(process_test process_test) add_executable(compile_commands_test compile_commands_test.cpp $) - target_link_libraries(compile_commands_test juci_shared) + target_link_libraries(compile_commands_test juci_shared ${PYTHON_LIBRARIES}) add_test(compile_commands_test compile_commands_test) add_executable(filesystem_test filesystem_test.cpp $) - target_link_libraries(filesystem_test juci_shared) + target_link_libraries(filesystem_test juci_shared ${PYTHON_LIBRARIES}) add_test(filesystem_test filesystem_test) add_executable(cmake_build_test cmake_build_test.cpp $) - target_link_libraries(cmake_build_test juci_shared) + target_link_libraries(cmake_build_test juci_shared ${PYTHON_LIBRARIES}) add_test(cmake_build_test cmake_build_test) add_executable(meson_build_test meson_build_test.cpp $) - target_link_libraries(meson_build_test juci_shared) + target_link_libraries(meson_build_test juci_shared ${PYTHON_LIBRARIES}) add_test(meson_build_test meson_build_test) add_executable(source_test source_test.cpp $) - target_link_libraries(source_test juci_shared) + target_link_libraries(source_test juci_shared ${PYTHON_LIBRARIES}) add_test(source_test source_test) add_executable(source_clang_test source_clang_test.cpp $) - target_link_libraries(source_clang_test juci_shared) + target_link_libraries(source_clang_test juci_shared ${PYTHON_LIBRARIES}) add_test(source_clang_test source_clang_test) add_executable(source_generic_test source_generic_test.cpp $) - target_link_libraries(source_generic_test juci_shared) + target_link_libraries(source_generic_test juci_shared ${PYTHON_LIBRARIES}) add_test(source_generic_test source_generic_test) add_executable(source_key_test source_key_test.cpp $) - target_link_libraries(source_key_test juci_shared) + target_link_libraries(source_key_test juci_shared ${PYTHON_LIBRARIES}) add_test(source_key_test source_key_test) add_executable(terminal_test terminal_test.cpp $) - target_link_libraries(terminal_test juci_shared) + target_link_libraries(terminal_test juci_shared ${PYTHON_LIBRARIES}) add_test(terminal_test terminal_test) add_executable(usages_clang_test usages_clang_test.cpp $) - target_link_libraries(usages_clang_test juci_shared) + target_link_libraries(usages_clang_test juci_shared ${PYTHON_LIBRARIES}) add_test(usages_clang_test usages_clang_test) - - if(LIBLLDB_FOUND) + + set(debian_version_file /etc/debian_version) + if(EXISTS ${debian_version_file}) + file(READ ${debian_version_file} debian_version) + message(${debian_version}) + if(${debian_version} EQUAL 9.9) + set(DEBIAN_STRETCH_FOUND True) + endif() + endif() + + if(LIBLLDB_FOUND AND NOT DEBIAN_STRETCH_FOUND) add_executable(lldb_test lldb_test.cpp $) - target_link_libraries(lldb_test juci_shared) + target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) add_test(lldb_test lldb_test) add_subdirectory("lldb_test_files") endif() - + add_executable(git_test git_test.cpp $) - target_link_libraries(git_test juci_shared) + target_link_libraries(git_test juci_shared ${PYTHON_LIBRARIES}) add_test(git_test git_test) - + add_executable(ctags_grep_test ctags_grep_test.cpp $) - target_link_libraries(ctags_grep_test juci_shared) + target_link_libraries(ctags_grep_test juci_shared ${PYTHON_LIBRARIES}) add_test(ctags_grep_test ctags_grep_test) - + add_executable(tooltips_test tooltips_test.cpp $) - target_link_libraries(tooltips_test juci_shared) + target_link_libraries(tooltips_test juci_shared ${PYTHON_LIBRARIES}) add_test(tooltips_test tooltips_test) - + add_executable(utility_test utility_test.cpp $) - target_link_libraries(utility_test juci_shared) + target_link_libraries(utility_test juci_shared ${PYTHON_LIBRARIES}) add_test(utility_test utility_test) + + add_subdirectory(./python_bindings) endif() if(BUILD_FUZZING) add_executable(cmake_fuzzer fuzzers/cmake.cpp $) target_compile_options(cmake_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(cmake_fuzzer PRIVATE -fsanitize=address,fuzzer) - target_link_libraries(cmake_fuzzer juci_shared) + target_link_libraries(cmake_fuzzer juci_shared ${PYTHON_LIBRARIES}) add_executable(ctags_fuzzer fuzzers/ctags.cpp $) target_compile_options(ctags_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(ctags_fuzzer PRIVATE -fsanitize=address,fuzzer) - target_link_libraries(ctags_fuzzer juci_shared) + target_link_libraries(ctags_fuzzer juci_shared ${PYTHON_LIBRARIES}) add_executable(docstring_fuzzer fuzzers/docstring.cpp $) target_compile_options(docstring_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(docstring_fuzzer PRIVATE -fsanitize=address,fuzzer) - target_link_libraries(docstring_fuzzer juci_shared) + target_link_libraries(docstring_fuzzer juci_shared ${PYTHON_LIBRARIES}) add_executable(doxygen_fuzzer fuzzers/doxygen.cpp $) target_compile_options(doxygen_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(doxygen_fuzzer PRIVATE -fsanitize=address,fuzzer) - target_link_libraries(doxygen_fuzzer juci_shared) + target_link_libraries(doxygen_fuzzer juci_shared ${PYTHON_LIBRARIES}) add_executable(grep_fuzzer fuzzers/grep.cpp $) target_compile_options(grep_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(grep_fuzzer PRIVATE -fsanitize=address,fuzzer) - target_link_libraries(grep_fuzzer juci_shared) + target_link_libraries(grep_fuzzer juci_shared ${PYTHON_LIBRARIES}) add_executable(markdown_fuzzer fuzzers/markdown.cpp $) target_compile_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) target_link_options(markdown_fuzzer PRIVATE -fsanitize=address,fuzzer) - target_link_libraries(markdown_fuzzer juci_shared) + target_link_libraries(markdown_fuzzer juci_shared ${PYTHON_LIBRARIES}) endif() -add_executable(process_test process_test.cc $) -target_link_libraries(process_test juci_shared ${PYTHON_LIBRARIES}) -add_test(process_test process_test) - -add_executable(compile_commands_test compile_commands_test.cc $) - target_link_libraries(compile_commands_test juci_shared ${PYTHON_LIBRARIES}) -add_test(compile_commands_test compile_commands_test) - -add_executable(filesystem_test filesystem_test.cc $) -target_link_libraries(filesystem_test juci_shared ${PYTHON_LIBRARIES}) -add_test(filesystem_test filesystem_test) - -add_executable(cmake_build_test cmake_build_test.cc $) -target_link_libraries(cmake_build_test juci_shared ${PYTHON_LIBRARIES}) -add_test(cmake_build_test cmake_build_test) - -add_executable(meson_build_test meson_build_test.cc $) -target_link_libraries(meson_build_test juci_shared ${PYTHON_LIBRARIES}) -add_test(meson_build_test meson_build_test) - -add_executable(source_test source_test.cc $) -target_link_libraries(source_test juci_shared ${PYTHON_LIBRARIES}) -add_test(source_test source_test) - -add_executable(source_clang_test source_clang_test.cc $) -target_link_libraries(source_clang_test juci_shared ${PYTHON_LIBRARIES}) -add_test(source_clang_test source_clang_test) - -add_executable(source_generic_test source_generic_test.cc $) -target_link_libraries(source_generic_test juci_shared ${PYTHON_LIBRARIES}) -add_test(source_generic_test source_generic_test) - -add_executable(source_key_test source_key_test.cc $) -target_link_libraries(source_key_test juci_shared ${PYTHON_LIBRARIES}) -add_test(source_key_test source_key_test) - -add_executable(terminal_test terminal_test.cc $) -target_link_libraries(terminal_test juci_shared ${PYTHON_LIBRARIES}) -add_test(terminal_test terminal_test) - -add_executable(usages_clang_test usages_clang_test.cc $) -target_link_libraries(usages_clang_test juci_shared ${PYTHON_LIBRARIES}) -add_test(usages_clang_test usages_clang_test) - -set(debian_version_file /etc/debian_version) -if(EXISTS ${debian_version_file}) - file(READ ${debian_version_file} debian_version) - message(${debian_version}) - if(${debian_version} EQUAL 9.9) - set(DEBIAN_STRETCH_FOUND True) - endif() -endif() - -if(LIBLLDB_FOUND AND NOT DEBIAN_STRETCH_FOUND) - add_executable(lldb_test lldb_test.cc $) - target_link_libraries(lldb_test juci_shared ${PYTHON_LIBRARIES}) - add_test(lldb_test lldb_test) - add_subdirectory("lldb_test_files") -endif() - -add_executable(git_test git_test.cc $) -target_link_libraries(git_test juci_shared ${PYTHON_LIBRARIES}) -add_test(git_test git_test) - -add_executable(python_interpreter_test python_interpreter_test.cc $) -target_link_libraries(python_interpreter_test juci_shared ${PYTHON_LIBRARIES}) -add_test(python_interpreter_test python_interpreter_test) - -add_subdirectory(./python_bindings) From c72aa8cdc4dd4901840dfc9b6f9513dbc975c9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Mon, 7 Sep 2020 21:10:32 +0200 Subject: [PATCH 50/63] Compiling again --- lib/tiny-process-library | 2 +- src/config_module.cc | 6 +++--- src/git.cpp | 11 ----------- src/juci.hpp | 2 +- src/plugins.cc | 6 +++--- src/python_module.cc | 16 ++++++++-------- src/window.cpp | 5 +++-- tests/CMakeLists.txt | 2 +- tests/python_bindings/CMakeLists.txt | 1 - .../compile_commands_test.cc | 2 +- .../python_bindings/Config_tests/config_test.cc | 6 +++--- .../Terminal_tests/terminal_test.cc | 2 +- tests/python_bindings/test_suite.h | 2 +- tests/stubs/dialogs.cpp | 2 ++ 14 files changed, 28 insertions(+), 37 deletions(-) diff --git a/lib/tiny-process-library b/lib/tiny-process-library index 6e52608..c5b0028 160000 --- a/lib/tiny-process-library +++ b/lib/tiny-process-library @@ -1 +1 @@ -Subproject commit 6e52608b15d12a13e68269b111afda3013e7cf3a +Subproject commit c5b0028fde831c1f5155aa2fe06a87e7c60ca124 diff --git a/src/config_module.cc b/src/config_module.cc index 119a5f0..82d7b99 100644 --- a/src/config_module.cc +++ b/src/config_module.cc @@ -1,4 +1,4 @@ -#include "config.h" +#include "config.hpp" #include "python_type_casters.h" #include @@ -43,7 +43,7 @@ void Config::init_module(py::module &api) { .def_readwrite("cmake", &Config::Project::cmake) .def_readwrite("meson", &Config::Project::meson) .def_readwrite("save_on_compile_or_run", &Config::Project::save_on_compile_or_run) - .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) + // .def_readwrite("clear_terminal_on_compile", &Config::Project::clear_terminal_on_compile) .def_readwrite("ctags_command", &Config::Project::ctags_command) .def_readwrite("python_command", &Config::Project::python_command) @@ -75,7 +75,7 @@ void Config::init_module(py::module &api) { .def_readwrite("default_tab_char", &Config::Source::default_tab_char) .def_readwrite("default_tab_size", &Config::Source::default_tab_size) .def_readwrite("tab_indents_line", &Config::Source::tab_indents_line) - .def_readwrite("wrap_lines", &Config::Source::wrap_lines) + // .def_readwrite("wrap_lines", &Config::Source::wrap_lines) .def_readwrite("highlight_current_line", &Config::Source::highlight_current_line) .def_readwrite("show_line_numbers", &Config::Source::show_line_numbers) .def_readwrite("enable_multiple_cursors", &Config::Source::enable_multiple_cursors) diff --git a/src/git.cpp b/src/git.cpp index 631d875..af2b246 100644 --- a/src/git.cpp +++ b/src/git.cpp @@ -299,17 +299,6 @@ void Git::init_module(py::module &api) { py::arg("line_nr")) ; - py::enum_(repository, "STATUS") - .value("CURRENT", Git::Repository::STATUS::CURRENT) - .value("NEW", Git::Repository::STATUS::NEW) - .value("MODIFIED", Git::Repository::STATUS::MODIFIED) - .value("DELETED", Git::Repository::STATUS::DELETED) - .value("RENAMED", Git::Repository::STATUS::RENAMED) - .value("TYPECHANGE", Git::Repository::STATUS::TYPECHANGE) - .value("UNREADABLE", Git::Repository::STATUS::UNREADABLE) - .value("IGNORED", Git::Repository::STATUS::IGNORED) - .value("CONFLICTED", Git::Repository::STATUS::CONFLICTED) - .export_values(); py::class_(repository, "Status") .def_readwrite("added", &Git::Repository::Status::added) diff --git a/src/juci.hpp b/src/juci.hpp index 279ca8a..2920b27 100644 --- a/src/juci.hpp +++ b/src/juci.hpp @@ -1,7 +1,7 @@ #pragma once +#include "window.hpp" #include #include -#include "window.h" #ifdef JUCI_ENABLE_PLUGINS #include "plugins.h" #endif diff --git a/src/plugins.cc b/src/plugins.cc index e572cd6..d14de2c 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -1,7 +1,7 @@ #include "plugins.h" -#include "config.h" +#include "config.hpp" #include "python_module.h" -#include "terminal.h" +#include "terminal.hpp" Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { auto &config = Config::get(); @@ -9,7 +9,7 @@ Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { #ifdef PYTHON_HOME_DIR #ifdef _WIN32 const std::wstring python_home(PYTHON_HOME_DIR); - const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages" ); + const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages"); Py_SetPythonHome(python_home.c_str()); Py_SetPath(python_path.c_str()); #endif diff --git a/src/python_module.cc b/src/python_module.cc index 69eedca..ad34880 100644 --- a/src/python_module.cc +++ b/src/python_module.cc @@ -1,14 +1,14 @@ #include "python_module.h" -#include "cmake.h" -#include "compile_commands.h" -#include "config.h" -#include "ctags.h" +#include "cmake.hpp" +#include "compile_commands.hpp" +#include "config.hpp" +#include "ctags.hpp" #ifdef JUCI_ENABLE_DEBUG -#include "debug_lldb.h" +#include "debug_lldb.hpp" #endif -#include "dialogs.h" -#include "terminal.h" -#include "git.h" +#include "dialogs.hpp" +#include "git.hpp" +#include "terminal.hpp" PyObject *Module::init_jucipp_module() { auto api = py::module("Jucipp", "API"); diff --git a/src/window.cpp b/src/window.cpp index f4a1057..d8342b2 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -33,7 +33,7 @@ void Window::init() { if(screen->get_rgba_visual()) border_radius_style = "border-radius: 5px; "; #if GTK_VERSION_GE(3, 20) -n std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}"); + std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; padding: 0 4px; margin: 0;}"); #else std::string notebook_style(".juci_notebook {-GtkNotebook-tab-overlap: 0px;} .juci_notebook tab {border-radius: 5px 5px 0 0; padding: 4px 4px;}"); #endif @@ -45,7 +45,8 @@ n std::string notebook_style(".juci_notebook tab {border-radius: 5px 5px 0 0; p .juci_terminal_scrolledwindow {padding-left: 3px;} .juci_info {border-radius: 5px;} .juci_tooltip_window {background-color: transparent;} - .juci_tooltip_box {)" + border_radius_style + R"(padding: 3px;} + .juci_tooltip_box {)" + border_radius_style + + R"(padding: 3px;} )"); get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 662eded..e47464e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,7 +24,7 @@ add_library(test_stubs OBJECT if(BUILD_TESTING) add_executable(process_test process_test.cpp $) - target_link_libraries(process_test juci_shared) + target_link_libraries(process_test juci_shared ${PYTHON_LIBRARIES}) add_test(process_test process_test) add_executable(compile_commands_test compile_commands_test.cpp $) diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index 1c09093..aeb8ad8 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -1,4 +1,3 @@ - add_library(test_suite test_suite.cc) target_link_libraries(test_suite juci_shared ${PYTHON_LIBRARIES}) diff --git a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc index 1e5ff6d..36624a3 100644 --- a/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc +++ b/tests/python_bindings/CompileCommands_tests/compile_commands_test.cc @@ -1,4 +1,4 @@ -#include "cmake.h" +#include "cmake.hpp" #include "test_suite.h" #include diff --git a/tests/python_bindings/Config_tests/config_test.cc b/tests/python_bindings/Config_tests/config_test.cc index b594670..982fb55 100644 --- a/tests/python_bindings/Config_tests/config_test.cc +++ b/tests/python_bindings/Config_tests/config_test.cc @@ -40,7 +40,7 @@ int main() { g_assert_cmpstr(config.project.cmake.command.c_str(), ==, "cmake"); g_assert_cmpstr(config.project.cmake.compile_command.c_str(), ==, "cmake --build"); g_assert_true(config.project.save_on_compile_or_run); - g_assert_false(config.project.clear_terminal_on_compile); + // g_assert_false(config.project.clear_terminal_on_compile); g_assert_cmpstr(config.project.ctags_command.c_str(), ==, "ctags"); g_assert_cmpstr(config.project.python_command.c_str(), ==, "python"); }); @@ -55,7 +55,7 @@ int main() { g_assert_false(config.source.format_style_on_save_if_style_file_found); g_assert_false(config.source.smart_inserts); g_assert_false(config.source.show_map); - g_assert_cmpstr(config.source.map_font_size.c_str(), ==, "10px"); + // g_assert_cmpstr(config.source.map_font_size.c_str(), ==, "10px"); g_assert_false(config.source.show_git_diff); g_assert_false(config.source.show_background_pattern); g_assert_false(config.source.show_right_margin); @@ -64,7 +64,7 @@ int main() { g_assert_cmpint(config.source.default_tab_char, ==, 'c'); g_assert_cmpuint(config.source.default_tab_size, ==, 1); g_assert_false(config.source.tab_indents_line); - g_assert_false(config.source.wrap_lines); + // g_assert_false(config.source.wrap_lines); g_assert_false(config.source.highlight_current_line); g_assert_false(config.source.show_line_numbers); g_assert_false(config.source.enable_multiple_cursors); diff --git a/tests/python_bindings/Terminal_tests/terminal_test.cc b/tests/python_bindings/Terminal_tests/terminal_test.cc index 89972b2..48821a6 100644 --- a/tests/python_bindings/Terminal_tests/terminal_test.cc +++ b/tests/python_bindings/Terminal_tests/terminal_test.cc @@ -1,5 +1,5 @@ +#include "terminal.hpp" #include "test_suite.h" -#include "terminal.h" int main() { const auto test_directory = "Terminal_tests"; diff --git a/tests/python_bindings/test_suite.h b/tests/python_bindings/test_suite.h index 0b13f8c..87c6f92 100644 --- a/tests/python_bindings/test_suite.h +++ b/tests/python_bindings/test_suite.h @@ -1,5 +1,5 @@ #pragma once -#include "config.h" +#include "config.hpp" #include "plugins.h" #include diff --git a/tests/stubs/dialogs.cpp b/tests/stubs/dialogs.cpp index 50255e4..b4ea172 100644 --- a/tests/stubs/dialogs.cpp +++ b/tests/stubs/dialogs.cpp @@ -7,3 +7,5 @@ void Dialog::Message::set_fraction(double fraction) {} bool Dialog::Message::on_delete_event(GdkEventAny *event) { return true; } + +void Dialog::init_module(py::module &) {} \ No newline at end of file From 69d5297d88ef54cdca8b288d7110f021281890c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Mon, 7 Sep 2020 21:22:24 +0200 Subject: [PATCH 51/63] bump version number so that config file updates --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f484d62..8f4d9d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 2.8.8) project(juci) -set(JUCI_VERSION "1.6.1.2") +set(JUCI_VERSION "1.7.0.0") set(CPACK_PACKAGE_NAME "jucipp") set(CPACK_PACKAGE_CONTACT "Ole Christian Eidheim ") From ad60559d979b2c2d3809ad59891f49baae0d47c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Mon, 7 Sep 2020 23:09:43 +0200 Subject: [PATCH 52/63] load plugins before application, we might want to do changes before the application starts --- src/juci.cpp | 9 +++++++-- src/juci.hpp | 6 +----- src/plugins.cc | 4 +--- src/plugins.h | 3 ++- tests/python_bindings/test_suite.cc | 2 +- tests/stubs/plugins.cc | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/juci.cpp b/src/juci.cpp index ad0da2b..a9e5ab8 100644 --- a/src/juci.cpp +++ b/src/juci.cpp @@ -4,6 +4,7 @@ #include "filesystem.hpp" #include "menu.hpp" #include "notebook.hpp" +#include "plugins.h" #include "terminal.hpp" #include "utility.hpp" #include "window.hpp" @@ -131,7 +132,7 @@ void Application::on_startup() { } } -Application::Application() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE), window(plugins) { +Application::Application(Plugins &p) : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE), window(p) { Glib::set_application_name("juCi++"); //Gtk::MessageDialog without buttons caused text to be selected, this prevents that @@ -142,5 +143,9 @@ int main(int argc, char *argv[]) { #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); // Do not terminate application when writing to a process fails #endif - return Application().run(argc, argv); + auto &config = Config::get(); + Plugins plugins(config); + plugins.load(); + + return Application(plugins).run(argc, argv); } diff --git a/src/juci.hpp b/src/juci.hpp index 2920b27..73a1950 100644 --- a/src/juci.hpp +++ b/src/juci.hpp @@ -2,9 +2,6 @@ #include "window.hpp" #include #include -#ifdef JUCI_ENABLE_PLUGINS -#include "plugins.h" -#endif /** \mainpage juCi++ is a lightweight C++ IDE written in C++ @@ -33,7 +30,7 @@ */ class Application : public Gtk::Application { public: - Application(); + Application(Plugins &p); int on_command_line(const Glib::RefPtr &cmd) override; void on_activate() override; void on_startup() override; @@ -43,5 +40,4 @@ private: std::vector> files; std::vector errors; Window window; - Plugins plugins; }; diff --git a/src/plugins.cc b/src/plugins.cc index d14de2c..ceaf995 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -3,9 +3,7 @@ #include "python_module.h" #include "terminal.hpp" -Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { - auto &config = Config::get(); - config.load(); +Plugins::Plugins(Config &config) : jucipp_module("Jucipp", Module::init_jucipp_module) { #ifdef PYTHON_HOME_DIR #ifdef _WIN32 const std::wstring python_home(PYTHON_HOME_DIR); diff --git a/src/plugins.h b/src/plugins.h index 84d98ac..ff2655b 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -1,11 +1,12 @@ #pragma once +#include "config.hpp" #include "python_bind.h" #include class __attribute__((visibility("default"))) Plugins { public: - Plugins(); + Plugins(Config &config); ~Plugins(); void load(); diff --git a/tests/python_bindings/test_suite.cc b/tests/python_bindings/test_suite.cc index f391509..e0c3ac9 100644 --- a/tests/python_bindings/test_suite.cc +++ b/tests/python_bindings/test_suite.cc @@ -2,7 +2,7 @@ #include "python_module.h" #include -suite::suite(const boost::filesystem::path &path) { +suite::suite(const boost::filesystem::path &path) : plugins(config) { py::initialize_interpreter(); if(!Py_IsInitialized()) { throw std::runtime_error("Unable to initialize interpreter"); diff --git a/tests/stubs/plugins.cc b/tests/stubs/plugins.cc index 10b5b94..68af68e 100644 --- a/tests/stubs/plugins.cc +++ b/tests/stubs/plugins.cc @@ -1,11 +1,11 @@ #include "plugins.h" #include "python_module.h" -Plugins::Plugins() : jucipp_module("Jucipp", Module::init_jucipp_module) { +Plugins::Plugins(Config &config) : jucipp_module("Jucipp", Module::init_jucipp_module) { #ifdef PYTHON_HOME_DIR #ifdef _WIN32 const std::wstring python_home(PYTHON_HOME_DIR); - const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages" ); + const std::wstring python_path(python_home + L";" + python_home + L"\\lib-dynload;" + python_home + L"\\site-packages"); Py_SetPythonHome(python_home.c_str()); Py_SetPath(python_path.c_str()); #endif From a994405c7110fda8d6286254cc7632f7b132c504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 00:05:49 +0200 Subject: [PATCH 53/63] load config and plugins early --- src/juci.cpp | 6 ++++-- src/window.cpp | 5 +---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/juci.cpp b/src/juci.cpp index a9e5ab8..95c5bf4 100644 --- a/src/juci.cpp +++ b/src/juci.cpp @@ -144,8 +144,10 @@ int main(int argc, char *argv[]) { signal(SIGPIPE, SIG_IGN); // Do not terminate application when writing to a process fails #endif auto &config = Config::get(); + config.load(); Plugins plugins(config); - plugins.load(); - + if(Config::get().plugins.enabled) { + plugins.load(); + } return Application(plugins).run(argc, argv); } diff --git a/src/window.cpp b/src/window.cpp index d8342b2..40bcb32 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -161,13 +161,9 @@ void Window::init() { about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy"); about.set_license_type(Gtk::License::LICENSE_MIT_X11); about.set_transient_for(*this); - if(Config::get().plugins.enabled) { - plugins.load(); - } } void Window::configure() { - Config::get().load(); Snippets::get().load(); auto screen = get_screen(); @@ -471,6 +467,7 @@ void Window::set_menu_actions() { if(auto view = Notebook::get().get_current_view()) { if(Notebook::get().save_current()) { if(view->file_path == Config::get().home_juci_path / "config" / "config.json") { + Config::get().load(); configure(); for(size_t c = 0; c < Notebook::get().size(); c++) { Notebook::get().get_view(c)->configure(); From c7e67a70b4fc30dbcf23f2d96c8a0a82cefe2cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 00:06:57 +0200 Subject: [PATCH 54/63] handle creation of plugins directory if it doesn't exist, remove calls to terminal as it might not have been loaded yet at this point --- src/plugins.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/plugins.cc b/src/plugins.cc index ceaf995..be649b9 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -24,8 +24,22 @@ Plugins::~Plugins() { } void Plugins::load() { + const auto &plugin_path = Config::get().plugins.path; + + boost::system::error_code ec; + if(!boost::filesystem::exists(plugin_path, ec)) { + ec.clear(); + boost::filesystem::create_directories(plugin_path, ec); + } + + if(ec) { + std::cerr << ec.message() << std::endl; + return; + } + boost::filesystem::directory_iterator end_it; - for(boost::filesystem::directory_iterator it(Config::get().plugins.path); it != end_it; it++) { + + for(boost::filesystem::directory_iterator it(plugin_path); it != end_it; it++) { auto module_name = it->path().stem().string(); if(module_name.empty()) continue; @@ -35,10 +49,10 @@ void Plugins::load() { if((is_directory && !is_pycache) || has_py_extension) { try { auto module = py::module::import(module_name.c_str()); - Terminal::get().print("Loading plugin ´" + module_name + "´\n"); } catch(py::error_already_set &error) { - Terminal::get().print("Error loading plugin `" + module_name + "`:\n" + error.what() + "\n"); + std::cerr << "Error loading plugin `" << module_name << "`:\n" + << error.what() << "\n"; } } } From 19c3e90cca74a63852df498b8860351f3aaffa76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 01:13:31 +0200 Subject: [PATCH 55/63] hook into juci after window has been loaded --- src/plugins.cc | 20 ++++++++++++++++++++ src/plugins.h | 3 +++ src/window.cpp | 1 + 3 files changed, 24 insertions(+) diff --git a/src/plugins.cc b/src/plugins.cc index be649b9..79df00f 100644 --- a/src/plugins.cc +++ b/src/plugins.cc @@ -23,6 +23,25 @@ Plugins::~Plugins() { py::finalize_interpreter(); } + +void Plugins::init_hook() { + for(auto &module_name : loaded_modules) { + auto module = py::module(py::handle(PyImport_GetModule(py::str(module_name.c_str()).ptr())), false); + if(py::hasattr(module, "init_hook")) { + py::object obj = module.attr("init_hook"); + if(py::isinstance(obj)) { + py::function func(obj); + try { + func(); + } + catch(const py::error_already_set &err) { + std::cerr << err.what() << std::endl; + } + } + } + } +} + void Plugins::load() { const auto &plugin_path = Config::get().plugins.path; @@ -49,6 +68,7 @@ void Plugins::load() { if((is_directory && !is_pycache) || has_py_extension) { try { auto module = py::module::import(module_name.c_str()); + loaded_modules.push_back(module_name); } catch(py::error_already_set &error) { std::cerr << "Error loading plugin `" << module_name << "`:\n" diff --git a/src/plugins.h b/src/plugins.h index ff2655b..0a18617 100644 --- a/src/plugins.h +++ b/src/plugins.h @@ -10,6 +10,9 @@ public: ~Plugins(); void load(); + void init_hook(); + private: py::detail::embedded_module jucipp_module; + std::vector loaded_modules; }; diff --git a/src/window.cpp b/src/window.cpp index 40bcb32..ffa492a 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -161,6 +161,7 @@ void Window::init() { about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy"); about.set_license_type(Gtk::License::LICENSE_MIT_X11); about.set_transient_for(*this); + plugins.init_hook(); } void Window::configure() { From 32a70dd5b050aa03f53b19a8c003b69cb8d021fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 01:22:22 +0200 Subject: [PATCH 56/63] add basic docs --- docs/plugins.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/plugins.md diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 0000000..a8d75ac --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,14 @@ +# Plugins + +## Getting started + +Plugins are stored in .juci/plugins + +### Basic hello world +from Jucipp import Terminal + +print("Hello world from before the application is loaded") + +def init_hook(): + t = Terminal() + t.print("Hello, world! From after the application is started.") From 5b20c327548625801a7c58159d5aacf1451e009e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 14:52:19 +0200 Subject: [PATCH 57/63] remove enabled print --- src/config.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 941f77e..3fca01c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -218,7 +218,4 @@ void Config::read(const boost::property_tree::ptree &cfg) { boost::replace_all(plugins_path, "", home_juci_path.string()); plugins.path = plugins_path; plugins.enabled = cfg.get("plugins.enabled"); - if (plugins.enabled) { - std::cout << "Plugins enabled" << std::endl; - } } From 5139d6e127f55e95351cd0938c7fe695e6c04ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 15:28:37 +0200 Subject: [PATCH 58/63] add new line to terminal call --- docs/plugins.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/plugins.md b/docs/plugins.md index a8d75ac..58d6ffc 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -7,8 +7,8 @@ Plugins are stored in .juci/plugins ### Basic hello world from Jucipp import Terminal -print("Hello world from before the application is loaded") +print("Hello, world! From before the application is loaded") def init_hook(): t = Terminal() - t.print("Hello, world! From after the application is started.") + t.print("Hello, world! From after the application is started.\n") From 8a7dd41b73a99bd7a97b5bf7afbdf77df4deb5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 15:30:12 +0200 Subject: [PATCH 59/63] initialize gtksourceviewmm since terminal uses that now and calls to terminal will cause an null value of the sourcebuffer --- tests/python_bindings/test_suite.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/python_bindings/test_suite.cc b/tests/python_bindings/test_suite.cc index e0c3ac9..d6bc08e 100644 --- a/tests/python_bindings/test_suite.cc +++ b/tests/python_bindings/test_suite.cc @@ -1,8 +1,10 @@ #include "test_suite.h" #include "python_module.h" +#include #include suite::suite(const boost::filesystem::path &path) : plugins(config) { + Gsv::init(); py::initialize_interpreter(); if(!Py_IsInitialized()) { throw std::runtime_error("Unable to initialize interpreter"); From 9ad7c21407bee6a43962fd71a9eee35868227d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 16:42:15 +0200 Subject: [PATCH 60/63] update config test to not fail. Needs updating according to new config options --- tests/python_bindings/Config_tests/config_test.py | 6 +++--- tests/stubs/config.cc | 4 ---- tests/stubs/config.cpp | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 tests/stubs/config.cc diff --git a/tests/python_bindings/Config_tests/config_test.py b/tests/python_bindings/Config_tests/config_test.py index 610cbf3..7ce7130 100644 --- a/tests/python_bindings/Config_tests/config_test.py +++ b/tests/python_bindings/Config_tests/config_test.py @@ -33,7 +33,7 @@ def project(): project.meson = meson project.cmake = cmake project.save_on_compile_or_run = True - project.clear_terminal_on_compile = False + # project.clear_terminal_on_compile = False project.ctags_command = "ctags" project.python_command = "python" Config().project = project @@ -49,7 +49,7 @@ def source(): source.format_style_on_save_if_style_file_found = False source.smart_inserts = False source.show_map = False - source.map_font_size = "10px" + # source.map_font_size = "10px" source.show_git_diff = False source.show_background_pattern = False source.show_right_margin = False @@ -58,7 +58,7 @@ def source(): source.default_tab_char = "c" source.default_tab_size = 1 source.tab_indents_line = False - source.wrap_lines = False + # source.wrap_lines = False source.highlight_current_line = False source.show_line_numbers = False source.enable_multiple_cursors = False diff --git a/tests/stubs/config.cc b/tests/stubs/config.cc deleted file mode 100644 index 52f73ea..0000000 --- a/tests/stubs/config.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "config.h" - -Config::Config() {} -void Config::load() {} diff --git a/tests/stubs/config.cpp b/tests/stubs/config.cpp index e798955..1795590 100644 --- a/tests/stubs/config.cpp +++ b/tests/stubs/config.cpp @@ -2,4 +2,3 @@ Config::Config() {} void Config::load() {} -void Config::init_module(py::module &) {} From 92679161f422d62ccf27246d67b41d770382e4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 17:11:59 +0200 Subject: [PATCH 61/63] update bindings of ctags, but disable test of it for now --- src/ctags.cpp | 8 ++++++++ tests/python_bindings/CMakeLists.txt | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ctags.cpp b/src/ctags.cpp index 46226e0..65bbf2c 100644 --- a/src/ctags.cpp +++ b/src/ctags.cpp @@ -289,11 +289,17 @@ void Ctags::init_module(py::module &api) { .def_readwrite("symbol", &Ctags::Location::symbol) .def_readwrite("scope", &Ctags::Location::scope) .def_readwrite("source", &Ctags::Location::source) + .def_readwrite("kind", &Ctags::Location::kind) .def("__bool__", &Ctags::Location::operator bool) ; ctags + .def(py::init(), + py::arg("path"), + py::arg("enable_scope"), + py::arg("enable_kind"), + py::arg("languages")) .def("get_location", &Ctags::get_location, py::arg("line"), py::arg("add_markup"), @@ -303,6 +309,8 @@ void Ctags::init_module(py::module &api) { py::arg("name"), py::arg("type"), py::arg("languages")) + .def_readwrite("project_path", &Ctags::project_path) + .def("__bool__", &Ctags::operator bool) ; } diff --git a/tests/python_bindings/CMakeLists.txt b/tests/python_bindings/CMakeLists.txt index aeb8ad8..bcc26c9 100644 --- a/tests/python_bindings/CMakeLists.txt +++ b/tests/python_bindings/CMakeLists.txt @@ -23,9 +23,9 @@ add_executable(pb_config_test Config_tests/config_test.cc $) -target_link_libraries(pb_ctags_test test_suite) -add_test(pb_ctags_test pb_ctags_test) +# add_executable(pb_ctags_test Ctags_tests/ctags_test.cc $) +# target_link_libraries(pb_ctags_test test_suite) +# add_test(pb_ctags_test pb_ctags_test) if(LIBLLDB_FOUND AND NOT DEBIAN_STRETCH_FOUND) add_executable(pb_debug_lldb_test Debug_lldb_tests/debug_lldb_test.cc $) From 1a11a5736b399cbd9f66f93f0d3453c61ef2bfd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 17:32:37 +0200 Subject: [PATCH 62/63] update lldb test --- src/debug_lldb.cpp | 3 ++- tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/debug_lldb.cpp b/src/debug_lldb.cpp index 49fe600..9250529 100644 --- a/src/debug_lldb.cpp +++ b/src/debug_lldb.cpp @@ -10,8 +10,8 @@ #include "utility.hpp" #include #include -#include #include +#include extern char **environ; @@ -601,6 +601,7 @@ void Debug::LLDB::init_module(pybind11::module &api) { dbg .def(py::init([]() { return &(Debug::LLDB::get()); })) + .def_static("destroy", &Debug::LLDB::destroy) .def_readwrite("on_exit", &Debug::LLDB::on_exit) .def("continue_debug", &Debug::LLDB::continue_debug) .def("stop", &Debug::LLDB::stop) diff --git a/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py b/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py index 09e05fa..154674a 100644 --- a/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py +++ b/tests/python_bindings/Debug_lldb_tests/debug_lldb_test.py @@ -18,4 +18,4 @@ def start_on_exit(exec_path): while not exited: sleep(0.1) - l.cancel() + LLDB.destroy() From 4e6c2c2d956ca7207f6c4c4460da35e56b8fc4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Sverre=20Lien=20Sell=C3=A6g?= Date: Tue, 8 Sep 2020 21:48:37 +0200 Subject: [PATCH 63/63] bind up tiny process lib and add test should also fix terminal warnings --- src/CMakeLists.txt | 1 + src/python_module.cc | 2 ++ src/terminal.cpp | 10 +++---- src/tiny_process_module.cpp | 27 +++++++++++++++++++ src/tiny_process_module.hpp | 6 +++++ .../Terminal_tests/terminal_test.cc | 11 ++++++++ .../Terminal_tests/terminal_test.py | 13 ++++++++- 7 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/tiny_process_module.cpp create mode 100644 src/tiny_process_module.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f0f0007..7387a0d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,7 @@ set(JUCI_SHARED_FILES source_language_protocol.cpp source_spellcheck.cpp terminal.cpp + tiny_process_module.cpp tooltips.cpp usages_clang.cpp utility.cpp diff --git a/src/python_module.cc b/src/python_module.cc index ad34880..3b4cef4 100644 --- a/src/python_module.cc +++ b/src/python_module.cc @@ -9,6 +9,7 @@ #include "dialogs.hpp" #include "git.hpp" #include "terminal.hpp" +#include "tiny_process_module.hpp" PyObject *Module::init_jucipp_module() { auto api = py::module("Jucipp", "API"); @@ -23,5 +24,6 @@ PyObject *Module::init_jucipp_module() { Dispatcher::init_module(api); Git::init_module(api); Terminal::init_module(api); + TinyProcessModule::init_module(api); return api.ptr(); } diff --git a/src/terminal.cpp b/src/terminal.cpp index 77885a4..ce7e8a7 100644 --- a/src/terminal.cpp +++ b/src/terminal.cpp @@ -7,6 +7,8 @@ #include "utility.hpp" #include #include +#include +#include #include #include @@ -611,7 +613,7 @@ void Terminal::init_module(pybind11::module &api) { py::arg("command"), py::arg("path") = "", py::arg("use_pipes") = false) - .def("async_process", (void (Terminal::*)(const std::string &, const boost::filesystem::path &, const std::function &, bool)) & Terminal::async_process, + .def("async_process", &Terminal::async_process, py::arg("command"), py::arg("path") = "", py::arg("callback") = nullptr, @@ -623,14 +625,12 @@ void Terminal::init_module(pybind11::module &api) { .def("print", &Terminal::print, py::arg("message"), py::arg("bold") = false) - .def("async_print", (void (Terminal::*)(const std::string &, bool)) & Terminal::async_print, + .def("async_print", (void (Terminal::*)(std::string, bool)) & Terminal::async_print, py::arg("message"), py::arg("bold") = false) - .def("async_print", (void (Terminal::*)(size_t, const std::string &)) & Terminal::async_print, - py::arg("line_nr"), - py::arg("message")) .def("configure", &Terminal::configure) .def("clear", &Terminal::clear) + .def_readwrite("", &Terminal::scroll_to_bottom) ; } diff --git a/src/tiny_process_module.cpp b/src/tiny_process_module.cpp new file mode 100644 index 0000000..b5dd88e --- /dev/null +++ b/src/tiny_process_module.cpp @@ -0,0 +1,27 @@ +#include "tiny_process_module.hpp" +#include + +void TinyProcessModule::init_module(py::module &api) { + py::class_> process(api, "Process"); + process + // .def("kill", (void (TinyProcessLib::Process::*)(TinyProcessLib::Process::id_type, bool)) & TinyProcessLib::Process::kill, + // py::arg("id"), + // py::arg("force") = false) + // .def(py::init(), + // py::arg("command"), + // py::arg("path") = TinyProcessLib::Process::string_type()) + .def("get_id", &TinyProcessLib::Process::get_id) + .def("get_exit_status", &TinyProcessLib::Process::get_exit_status) + .def("try_get_exit_status", &TinyProcessLib::Process::try_get_exit_status, + py::arg("exit_status")) + .def("write", (bool (TinyProcessLib::Process::*)(const char *, size_t)) & TinyProcessLib::Process::write, + py::arg("bytes"), + py::arg("n")) + .def("write", (bool (TinyProcessLib::Process::*)(const std::string &)) & TinyProcessLib::Process::write, + py::arg("string")) + .def("close_stdin", &TinyProcessLib::Process::close_stdin) + .def("kill", (void (TinyProcessLib::Process::*)(bool)) & TinyProcessLib::Process::kill, + py::arg("force")) + + ; +} diff --git a/src/tiny_process_module.hpp b/src/tiny_process_module.hpp new file mode 100644 index 0000000..01bae74 --- /dev/null +++ b/src/tiny_process_module.hpp @@ -0,0 +1,6 @@ +#include "python_bind.h" + +class TinyProcessModule { +public: + static void init_module(py::module &api); +}; \ No newline at end of file diff --git a/tests/python_bindings/Terminal_tests/terminal_test.cc b/tests/python_bindings/Terminal_tests/terminal_test.cc index 48821a6..329dd27 100644 --- a/tests/python_bindings/Terminal_tests/terminal_test.cc +++ b/tests/python_bindings/Terminal_tests/terminal_test.cc @@ -37,4 +37,15 @@ int main() { connection.disconnect(); } } + { + suite test_suite(test_directory); + try { + const auto ls_dir = test_suite.test_file_path / test_directory / "ls"; + py::module::import("terminal_test").attr("async_process")(ls_dir); + test_suite.has_assertion = true; + } + catch(const py::error_already_set &error) { + std::cout << error.what(); + } + } } \ No newline at end of file diff --git a/tests/python_bindings/Terminal_tests/terminal_test.py b/tests/python_bindings/Terminal_tests/terminal_test.py index d8151d6..e364365 100644 --- a/tests/python_bindings/Terminal_tests/terminal_test.py +++ b/tests/python_bindings/Terminal_tests/terminal_test.py @@ -1,4 +1,5 @@ from Jucipp import Terminal +from jucipp_test import assert_equal t = Terminal() @@ -9,7 +10,17 @@ def clear(): t.clear() def process(path): - return t.process("ls", path, True) + p = t.process("ls", path, True) + assert_equal(p, 0) + return p def async_print(): return t.async_print("Hello, World!") + +def callback(exit_code): + assert_equal(0, exit_code) + +def async_process(path): + p = t.async_process("ls", path, callback, True) + assert_equal(0, p.get_exit_status()) + return p.get_exit_status()