diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..da710eb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required (VERSION 2.8.4) + +set(project_name juci) +set(module juci_to_python_api) + +#### TODO WINDOWS SUPPORT #### +set(bin_install_path "/usr/local/bin") +set(lib_install_path "/usr/local/lib/python2.7/dist-packages/") +##### + +project (${project_name}) + +add_subdirectory("src") \ No newline at end of file diff --git a/README.md b/README.md index cf441e9..3823f43 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,42 @@ # juCi++ ###### a lightweight C++-IDE with support for C++11 and C++14. ## About -juCi++ is a lightweight C++-IDE written in C++. You can write plugins -in Python and configure the IDE from the config.json file. - - -## Autocompletion -The IDE supports autocompletion on accessor specifiers such as dot and arrow. The autocompletion has excellent support for C++11/14. - -## Syntax Highlighting -The IDE also supports syntax highligthing even in C++11 and C++14. - -## To get C++11 and C++14 support -If you want support for external libraries and C++11 and C++14 you need to make sure you add a parameter to the cmake command. This will make compile_commands.json wich tells juCi++ all the paramters for the compiler. There is a bug where juCi++ sometimes puts the compile_commands.json file in the incorrect folder. Please make sure this file exists and that the contents of it covers all your files. -```sh -$ cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -``` - -## Plugins -There are expansion oppertunities with usage of python plugins. - -## Configuration -Configuration description will arrive shortly after source code is added. +A lot of IDEs struggle with good C++11/14 support. Therefore we +created juCi++. juCi++ is based of the compiler and will *always* +support new versions of C++. + +## Features +* Syntax highlighing (even C++11/14) +* Superfast autocomletion (even external libraries) +* Accurate refactoring across files +* Basic editor functionallity +* Highlighting of similar types +* write your own plugins in python (limited atm) ## Dependencies ## Please install these dependencies on your system. - -* libclang +* libboost-python-dev +* libboost-filesystem-dev +* libboost-log-dev +* libboost-test-dev +* libboost-thread-dev +* libboost-system-dev +* libgtkmm-3.0-dev +* libgtksourceview2.0-dev +* libgtksourceviewmm-3.0-dev +* libpython-dev +* libclang-dev * [libclangmm](http://github.com/cppit/libclangmm/) * cmake * make * clang or gcc (compiler) ## Installation ## - +Quickstart: ```sh $ cmake . $ make +$ sudo make install ``` +See [installation guide](http://github.com/cppit/jucipp/blob/master/docs/install.md) for more details. -## Run -```sh -$ ./bin/juci -``` diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..3e06b5e --- /dev/null +++ b/docs/install.md @@ -0,0 +1,22 @@ +# juCi++ +## Installation guide ## +Before installation, please install libclangmm see [installation guide](http://github.com/cppit/libclangmm/blob/master/docs/install.md) for installation. +## Debian +First dependencies: +```sh +$ sudo apt-get install libboost-python-dev libboost-filesystem-dev libboost-log-dev libboost-test-dev +libboost-thread-dev libboost-system-dev libgtkmm-3.0-dev libgtksourceview2.0-dev libgtksourceviewmm-3.0-dev +libpython-dev libclang-dev make cmake gcc +``` +Install the project: +```sh +$ git clone http://github.com/cppit/jucipp.git juci +$ cd juci +$ cmake . +$ make +$ sudo make install +``` +## Run +```sh +$ juci +``` diff --git a/juci/CMakeLists.txt b/juci/CMakeLists.txt deleted file mode 100644 index 694961c..0000000 --- a/juci/CMakeLists.txt +++ /dev/null @@ -1,164 +0,0 @@ -cmake_minimum_required (VERSION 2.8.4) -set(project_name juci) -set(module juci_to_python_api) -project (${project_name}) -add_definitions(-DBOOST_LOG_DYN_LINK) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++11 -pthread -Wall -Wno-reorder") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/") - -#You are of course using Homebrew: -if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/local/opt/gettext/lib -I/usr/local/opt/gettext/include -undefined dynamic_lookup") #TODO: fix this - set(CMAKE_MACOSX_RPATH 1) - set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig") -endif() -INCLUDE(FindPkgConfig) - -message("Searcing for libclang") -#LIBCLANG_FOUND System has libclang. -#LIBCLANG_INCLUDE_DIRS The libclang include directories. -#LIBCLANG_LIBRARIES The libraries needed to use libclang. -#LIBCLANG_LIBRARY_DIR The path to the directory containing libclang. -#LIBCLANG_KNOWN_LLVM_VERSIONS Known LLVM release numbers. -find_package(LibClangmm) -find_package(LibClang) - -if(${LCL_FOUND}) - message("libclangmm libraries found. Continuing") - message("${LCL_INCLUDE_DIRS}") -else() - message(FATAL_ERROR "The libclangmm libraries are required. Quitting.") -endif() - -if(${LIBCLANG_FOUND}) - message("libclangmm libraries found. Continuing") - message("${LIBCLANG_INCLUDE_DIRS}") -else() - message(FATAL_ERROR "The libclangmm libraries are required. Quitting.") -endif() - -#### Finding boost, the variables below is set ##### -#PYTHONLIBS_FOUND - True if headers and requested libraries were found -#PYTHON_INCLUDE_DIRS - Boost include directories -#PYTHON_LIBRARIES - Boost component libraries to be linked -find_package(PythonLibs 2.7) - -#If python is found -if(${PYTHONLIBS_FOUND}) - message("Python libraries found. Continuing") -else() - message("Please install python libraries. The libraries where not found.") - message("Python include dirs: ${PYTHON_INCLUDE_DIRS}") - message("Python link dirs ${PYTHON_LIBRARIES}") - message(FATAL_ERROR "The python libraries are required. Quitting.") -endif() - -#### Finding boost, the variables below is set ##### -#Boost_FOUND - True if headers and requested libraries were found -#Boost_INCLUDE_DIRS - Boost include directories -#Boost_LIBRARY_DIRS - Link directories for Boost libraries -#Boost_LIBRARIES - Boost component libraries to be linked -find_package(Boost 1.55 COMPONENTS python thread log system filesystem REQUIRED) - -#If boost is not found -if(${Boost_FOUND}) - message("Boost libraries found. Continuing") -else() - message("Please install boost libraries. The libraries where not found.") - message("Boost library dirs: ${Boost_LIBRARY_DIRS}") - message("Boost include dirs: ${Boost_INCLUDE_DIRS}") - message("Boost link dirs ${Boost_LIBRARIES}") - message(FATAL_ERROR "The boost libraries are required. Quitting.") -endif() - -#### Finding gtkmm, the variables below is set ##### -#GTKMM_FOUND - True if headers and requested libraries were found -#GTKMM_INCLUDE_DIRS - GTKMM include directories -#GTKMM_LIBRARY_DIRS - Link directories for GTKMM libraries -#GTKMM_LIBRARIES - GTKMM libraries to be linked -pkg_check_modules(GTKMM gtkmm-3.0) # The name GTKMM is set here for the variables abouve - -#If gtkmm is not found -if(${GTKMM_FOUND}) - message("Gtkmm libraries found. Continuing") -else() - message("Please install gtkmm libraries. The libraries where not found.") - message("Gtkmm library dirs ${GTKMM_LIBRARY_DIRS}") - message("Gtkmm include dirs ${GTKMM_INCLUDE_DIRS}") - message("Gtkmm link dirs ${GTKMM_LIBRARIES}") - message(FATAL_ERROR "The gtkmm libraries are required. Quitting.") -endif() - -pkg_check_modules(GTKSVMM gtksourceviewmm-3.0) -if(${GTKSVMM_FOUND}) - message("Gtksourceviewmm libraries found. Continuing") -else() - message(FATAL_ERROR "The gtksourceviewmm libraries are required. Quitting.") -endif() - -# name of the executable on Windows will be example.exe -add_executable(${project_name} - #list of every needed file to create the executable - juci.h - juci.cc - menu.h - menu.cc - source.h - source.cc - selectiondialog.h - selectiondialog.cc - config.h - config.cc - sourcefile.h - sourcefile.cc - window.cc - window.h - api.h - api.cc - notebook.cc - notebook.h - entrybox.h - entrybox.cc - directories.h - directories.cc - terminal.h - terminal.cc - tooltips.h - tooltips.cc - singletons.h - singletons.cc - ) - -set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) - - -add_library(${module} SHARED - api - api_ext - ) -# dependencies - -include_directories( - ${Boost_INCLUDE_DIRS} - ${PYTHON_INCLUDE_DIRS} - ${GTKMM_INCLUDE_DIRS} - ${GTKSVMM_INCLUDE_DIRS} - ${LCL_INCLUDE_DIRS} - ${LIBCLANG_INCLUDE_DIRS} - ) -link_directories( - ${GTKMM_LIBRARY_DIRS} - ${GTKSVMM_LIBRARY_DIRS} - ${Boost_LIBRARY_DIRS} - ${PYTHON_INCLUDE_DIRS} - ${LCL_LIBRARY_DIRS} - ${LIBCLANG_LIBRARY_DIRS} - ) -#module: -set_target_properties(${module} PROPERTIES PREFIX "" -LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/") -target_link_libraries(${module} ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) -#executable: -target_link_libraries(${project_name} ${LIVCLANG_LIBRARIES} ${LCL_LIBRARIES} ${GTKMM_LIBRARIES} ${GTKSVMM_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) - - diff --git a/juci/config.json b/juci/config.json deleted file mode 100644 index a3c3ebd..0000000 --- a/juci/config.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "source": { - "colors": { - "text_color": "black", - "string": "#CC0000", - "namespace_ref": "#990099", - "type": "#0066FF", - "keyword": "blue", - "comment": "grey", - "own": "pink", - "diagnostic_warning": "orange", - "diagnostic_error": "red" - }, - "syntax": { - "43": "type", - "46": "namespace_ref", - "109": "string", - "702": "keyword", - "703": "own", - "705": "comment" - }, - "visual": { - "background": "white", - "background_selected": "blue", - "background_tooltips": "yellow", - "font": "Monospace", - "show_line_numbers": 1, - "highlight_current_line": 1 - }, - "tab_size": 2, - "tab_char": "" - }, - "keybindings": { - "new_file": "n", - "open_folder": "o", - "open_file": "o", - "save": "s", - "save_as": "s", - "quit": "q", - "split_window": "s", - "close_tab": "w", - "edit_copy": "c", - "edit_cut": "x", - "edit_paste": "v", - "edit_undo": "z", - "edit_redo": "z", - "edit_find": "f", - "source_goto_declaration": "d", - "source_goto_method": "m", - "source_rename": "r", - "compile_and_run": "Return", - "compile": "Return" - }, - "directoryfilter": { - "ignore": [ - "cmake", - "#", - "~", - ".idea", - ".so", - "in-lowercase.pls" - ], - "exceptions": [ - "cmakelists.txt", - "in-lowercase.pls" - ] - }, - "project": { - "run_commands": [ - "./.build/" - ], - "compile_commands": [ - "rm -rf ./.build", - "mkdir ./.build", - "cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B./.build -H.", - "cd ./.build/; make", - "cp ./.build/compile_commands.json compile_commands.json" - ] - }, - "example": { - "key": "value", - "key2": [ - "val1", - "val2", - 3 - ], - "key3": "value" - } -} diff --git a/juci/menu.xml b/juci/menu.xml deleted file mode 100644 index d93305f..0000000 --- a/juci/menu.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/juci/plugins.py b/juci/plugins.py deleted file mode 100644 index ef50bb7..0000000 --- a/juci/plugins.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/python -#plugin handler -import sys, os, glob -cwd = os.getcwd() -sys.path.append(cwd+"/lib") - -import juci_to_python_api as juci -def loadplugins(): - plugin_files = glob.glob(cwd+"/plugins/*.py") - for current_file in plugin_files: - juci.initPlugin(current_file) - -loadplugins() diff --git a/juci/sourcefile.cc b/juci/sourcefile.cc deleted file mode 100644 index 0374584..0000000 --- a/juci/sourcefile.cc +++ /dev/null @@ -1,92 +0,0 @@ -#include "sourcefile.h" -#include -#include -#include -#include - -using namespace std; - -sourcefile::sourcefile(const string &input_filename) - : lines(), filename(input_filename) { - open(input_filename); -} - -/** - * - */ -void sourcefile::open(const string &filename) { - Gio::init(); - - // Creates/Opens a file specified by the input string. - Glib::RefPtr file = Gio::File::create_for_path(filename); - - if (!file) // Gio::File has overloaded operator - cerr << "Was not able to open file: " << filename << endl; - - // Creates pointer for filestream - - if (!file->query_exists()) { - file->create_file()->close(); - } - - Glib::RefPtr stream = file->read(); - - if (!stream) // error message on stream failure - cerr << filename << " returned an empty stream" << endl; - - Glib::RefPtr - datainput = Gio::DataInputStream::create(stream); - - string line; - while (datainput->read_line(line)) { - lines.push_back(line); - } - - datainput->close(); - stream->close(); -} - -vector sourcefile::get_lines() { - return lines; -} - -string sourcefile::get_line(int line_number) { - return lines[line_number]; -} - -int sourcefile::save(const string &text) { - Gio::init(); - - // Creates/Opens a file specified by the input string. - Glib::RefPtr file = Gio::File::create_for_path(filename); - - if (!file) // Gio::File has overloaded operator - cerr << "Was not able to open file: " << filename << endl; - - // Creates - Glib::RefPtr stream = - file->query_exists() ? file->replace() : file->create_file(); - - if (!stream) // error message on stream failure - cerr << filename << " returned an empty stream" << endl; - - Glib::RefPtr - output = Gio::DataOutputStream::create(stream); - - output->put_string(text); - - output->close(); - stream->close(); - - - return 0; -} - -string sourcefile::get_content() { - string res; - for (auto line : lines) { - res.append(line).append("\n"); - } - return res; -} - diff --git a/juci/sourcefile.h b/juci/sourcefile.h deleted file mode 100644 index 2afc263..0000000 --- a/juci/sourcefile.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef JUCI_SOURCEFILE_H_ -#define JUCI_SOURCEFILE_H_ - -#include -#include - -class sourcefile { -public: - explicit sourcefile(const std::string &filename); - std::vector get_lines(); - std::string get_content(); - std::string get_line(int line_number); - int save(const std::string &text); - -private: - void open(const std::string &filename); - std::vector lines; - std::string filename; -}; - -#endif // JUCI_SOURCEFILE_H_ diff --git a/juci/plugins/snippet.py b/plugins/snippet.py similarity index 100% rename from juci/plugins/snippet.py rename to plugins/snippet.py diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..54c9549 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,123 @@ +add_definitions(-DBOOST_LOG_DYN_LINK) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++11 -pthread -Wall -Wno-reorder") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/") + +if(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/local/opt/gettext/lib -I/usr/local/opt/gettext/include -undefined dynamic_lookup") #T + set(CMAKE_MACOSX_RPATH 1) + set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig") +endif() +INCLUDE(FindPkgConfig) + +set(validation true) + +function(install_help APPLE UNIX WINDOWS) + message("Install package with:") + if(UNIX) + if(APPLE) + message("brew install ${APPLE}") + else() + message("sudo apt-get install ${UNIX}") + endif(APPLE) + endif(UNIX) + if(WINDOWS) + message("choco install ${WINDOWS}") + endif(WINDOWS) +endfunction(install_help) + +function(validate FOUND APPLE UNIX WINDOWS) + if(!${FOUND}) + set(validation false) + install_help(${APPLE} ${UNIX} ${WINDOWS}) + endif() +endfunction(validate) + +find_package(LibClangmm) +validate(${LCL_FOUND} "clangmm" "clangmm" "clangmm") + +find_package(LibClang) +validate(${LIBCLANG_FOUND} "clang" "libclang-dev" "llvm") + +find_package(PythonLibs 2.7) +validate(${PYTHONLIBS_FOUND} "python" "libpython-dev" "python") + +find_package(Boost 1.55 COMPONENTS python thread log system filesystem REQUIRED) +validate(${Boost_FOUND} "boost" "libboost-all-dev" "boost") + +pkg_check_modules(GTKMM gtkmm-3.0) # The name GTKMM is set here for the variables abouve +validate(${GTKMM_FOUND} "gtkmm" "libgtkmm-dev" "gtkmm") + +pkg_check_modules(GTKSVMM gtksourceviewmm-3.0) +validate(${GTKSVMM_FOUND} "gtksvmm" "libgtksvmm-dev" "gtkmmsv") + +if(${validation}) + add_executable(${project_name} + juci.h + juci.cc + menu.h + menu.cc + source.h + source.cc + selectiondialog.h + selectiondialog.cc + config.h + config.cc + sourcefile.h + sourcefile.cc + window.cc + window.h + api.h + api.cc + notebook.cc + notebook.h + entrybox.h + entrybox.cc + directories.h + directories.cc + terminal.h + terminal.cc + tooltips.h + tooltips.cc + singletons.h + singletons.cc) + + add_library(${module} SHARED + api + api_ext) + + include_directories( + ${Boost_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIRS} + ${GTKMM_INCLUDE_DIRS} + ${GTKSVMM_INCLUDE_DIRS} + ${LCL_INCLUDE_DIRS} + ${LIBCLANG_INCLUDE_DIRS}) + + link_directories( + ${GTKMM_LIBRARY_DIRS} + ${GTKSVMM_LIBRARY_DIRS} + ${Boost_LIBRARY_DIRS} + ${PYTHON_INCLUDE_DIRS} + ${LCL_LIBRARY_DIRS} + ${LIBCLANG_LIBRARY_DIRS}) + + set_target_properties(${module} + PROPERTIES PREFIX "" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/") + + target_link_libraries(${module} ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) + + target_link_libraries(${project_name} + ${LIBCLANG_LIBRARIES} + ${LCL_LIBRARIES} + ${GTKMM_LIBRARIES} + ${GTKSVMM_LIBRARIES} + ${Boost_LIBRARIES} + ${PYTHON_LIBRARIES}) + + install(TARGETS ${project_name} ${module} + RUNTIME DESTINATION ${bin_install_path} + LIBRARY DESTINATION ${lib_install_path} + ) +endif(${validation}) + diff --git a/juci/api.cc b/src/api.cc similarity index 96% rename from juci/api.cc rename to src/api.cc index 9b4703c..fa93820 100644 --- a/juci/api.cc +++ b/src/api.cc @@ -18,12 +18,6 @@ PluginApi::PluginApi(Notebook* notebook) { DEBUG("Plugins initiated.."); } -std::string PluginApi::ProjectPath() { - int MAXPATHLEN = 50; - char temp[MAXPATHLEN]; - return ( getcwd(temp, MAXPATHLEN) ? std::string( temp ) : std::string("") ); -} - void PluginApi::ReplaceWord(std::string word) { Glib::RefPtr buffer = libjuci::BufferFromNotebook(); Gtk::TextIter word_start = libjuci::IterFromNotebook(); @@ -57,7 +51,7 @@ std::string PluginApi::GetWord() { } void PluginApi::InitPlugins() { - libjuci::LoadPlugin(ProjectPath()+"/plugins.py"); + libjuci::LoadPlugin(Singleton::config_dir() + "plugins.py"); } void PluginApi::AddMenuElement(std::string plugin_name) { diff --git a/juci/api.h b/src/api.h similarity index 98% rename from juci/api.h rename to src/api.h index 6292c07..4468631 100644 --- a/juci/api.h +++ b/src/api.h @@ -16,7 +16,6 @@ public: static Menu* menu_; static Notebook* notebook; static void InitPlugins(); - static std::string ProjectPath(); // for Python module: static std::string GetWord(); // menu management diff --git a/juci/api_ext.cc b/src/api_ext.cc similarity index 100% rename from juci/api_ext.cc rename to src/api_ext.cc diff --git a/juci/cmake/Modules/FindLibClang.cmake b/src/cmake/Modules/FindLibClang.cmake similarity index 100% rename from juci/cmake/Modules/FindLibClang.cmake rename to src/cmake/Modules/FindLibClang.cmake diff --git a/juci/cmake/Modules/FindLibClangmm.cmake b/src/cmake/Modules/FindLibClangmm.cmake similarity index 71% rename from juci/cmake/Modules/FindLibClangmm.cmake rename to src/cmake/Modules/FindLibClangmm.cmake index 0cb9fc5..49f950b 100644 --- a/juci/cmake/Modules/FindLibClangmm.cmake +++ b/src/cmake/Modules/FindLibClangmm.cmake @@ -1,20 +1,15 @@ -# - Try to find LCL - - -# Once done this will define # LCL_FOUND - Libclangmm is available # LCL_INCLUDE_DIRS - The libclangmm include directories # LCL_LIBRARIES - -# LCL_DEFINITIONS - Compiler switches required for using libclangmm find_package(PkgConfig) find_path(LCL_INCLUDE_DIR clangmm.h - HINTS "/usr/local/lib/libclangmm/include/" + HINTS "/usr/local/include/libclangmm/" ) find_library(LCL_LIBRARY NAMES clangmm - HINTS "/usr/local/lib/libclangmm/" + HINTS "/usr/local/lib/" ) set(LCL_LIBRARIES ${LCL_LIBRARY} ) diff --git a/juci/config.cc b/src/config.cc similarity index 68% rename from juci/config.cc rename to src/config.cc index aa0dfbf..a75b078 100644 --- a/juci/config.cc +++ b/src/config.cc @@ -1,24 +1,37 @@ #include "singletons.h" #include "config.h" #include "logging.h" -#include -#include +#include +#include "files.h" +#include "sourcefile.h" MainConfig::MainConfig() { - INFO("Reading config file"); - boost::property_tree::json_parser::read_json("config.json", cfg_); - INFO("Config file read"); + find_or_create_config_files(); + boost::property_tree::json_parser::read_json(Singleton::config_dir() + "config.json", cfg); GenerateSource(); GenerateKeybindings(); GenerateDirectoryFilter(); GenerateTerminalCommands(); } +void MainConfig::find_or_create_config_files() { + std::vector files = {"config.json", "menu.xml", "plugins.py"}; + boost::filesystem::create_directories(boost::filesystem::path(Singleton::config_dir())); + for (auto &file : files) { + auto path = boost::filesystem::path(Singleton::config_dir() + file); + if (!boost::filesystem::is_regular_file(path)) { + if (file == "config.json") juci::filesystem::save(path, configjson); + if (file == "plugins.py") juci::filesystem::save(path, pluginspy); + if (file == "menu.xml") juci::filesystem::save(path, menuxml); + } + } +} + void MainConfig::GenerateSource() { auto source_cfg=Singleton::Config::source(); DEBUG("Fetching source cfg"); // boost::property_tree::ptree - auto source_json = cfg_.get_child("source"); + auto source_json = cfg.get_child("source"); auto syntax_json = source_json.get_child("syntax"); auto colors_json = source_json.get_child("colors"); auto visual_json = source_json.get_child("visual"); @@ -48,7 +61,7 @@ void MainConfig::GenerateSource() { void MainConfig::GenerateTerminalCommands() { auto terminal_cfg=Singleton::Config::terminal(); - boost::property_tree::ptree source_json = cfg_.get_child("project"); + boost::property_tree::ptree source_json = cfg.get_child("project"); boost::property_tree::ptree compile_commands_json = source_json.get_child("compile_commands"); boost::property_tree::ptree run_commands_json = source_json.get_child("run_commands"); for (auto &i : compile_commands_json) @@ -58,15 +71,14 @@ void MainConfig::GenerateTerminalCommands() { } void MainConfig::GenerateKeybindings() { - auto menu=Singleton::menu(); - DEBUG("Fetching keybindings"); - std::string line; - std::ifstream menu_xml("menu.xml"); - if (menu_xml.is_open()) { - while (getline(menu_xml, line)) - menu->ui+=line; + auto menu = Singleton::menu(); + boost::filesystem::path path(Singleton::config_dir() + "menu.xml"); + if (!boost::filesystem::is_regular_file(path)) { + std::cerr << "menu.xml not found" << std::endl; + throw; } - boost::property_tree::ptree keys_json = cfg_.get_child("keybindings"); + menu->ui = juci::filesystem::open(path); + boost::property_tree::ptree keys_json = cfg.get_child("keybindings"); for (auto &i : keys_json) { auto key=i.second.get_value(); menu->key_map[i.first] = key; @@ -77,7 +89,7 @@ void MainConfig::GenerateKeybindings() { void MainConfig::GenerateDirectoryFilter() { auto dir_cfg=Singleton::Config::directories(); DEBUG("Fetching directory filter"); - boost::property_tree::ptree dir_json = cfg_.get_child("directoryfilter"); + boost::property_tree::ptree dir_json = cfg.get_child("directoryfilter"); boost::property_tree::ptree ignore_json = dir_json.get_child("ignore"); boost::property_tree::ptree except_json = dir_json.get_child("exceptions"); for ( auto &i : except_json ) diff --git a/juci/config.h b/src/config.h similarity index 75% rename from juci/config.h rename to src/config.h index 9729467..9f97a90 100644 --- a/juci/config.h +++ b/src/config.h @@ -6,13 +6,14 @@ class MainConfig { public: MainConfig(); + void find_or_create_config_files(); void PrintMenu(); void GenerateSource(); void GenerateKeybindings(); void GenerateDirectoryFilter(); void GenerateTerminalCommands(); private: - boost::property_tree::ptree cfg_; - boost::property_tree::ptree key_tree_; + boost::property_tree::ptree cfg; + boost::property_tree::ptree key_tree; }; #endif diff --git a/juci/directories.cc b/src/directories.cc similarity index 96% rename from juci/directories.cc rename to src/directories.cc index 4c5757d..7c6505f 100644 --- a/juci/directories.cc +++ b/src/directories.cc @@ -1,8 +1,8 @@ #include "directories.h" +#include "sourcefile.h" #include "logging.h" #include "singletons.h" #include -#include #include "boost/algorithm/string.hpp" namespace sigc { @@ -103,9 +103,7 @@ std::string Directories::get_cmakelists_variable(const boost::filesystem::path& boost::filesystem::directory_iterator end_itr; for (boost::filesystem::directory_iterator itr( dir_path );itr != end_itr;++itr ) { if (itr->path().filename().string() == "CMakeLists.txt") { - std::ifstream ifs(itr->path().string()); - std::string line; - while (std::getline(ifs, line)) { + for (auto &line : juci::filesystem::lines(itr->path())) { if (line.find(command_name+"(", 0) != std::string::npos || line.find(command_name+" (", 0) != std::string::npos ) { size_t variable_start = line.find("{", 0); @@ -140,8 +138,7 @@ std::string Directories::get_cmakelists_variable(const boost::filesystem::path& } } } - std::ifstream ifs2(itr->path().string()); - while (std::getline(ifs2, line)) { + for (auto &line : juci::filesystem::lines(itr->path())) { if (line.find("set(", 0) != std::string::npos || line.find("set (", 0) != std::string::npos) { if( line.find(project_name_var, 0) != std::string::npos) { diff --git a/juci/directories.h b/src/directories.h similarity index 100% rename from juci/directories.h rename to src/directories.h diff --git a/juci/entrybox.cc b/src/entrybox.cc similarity index 100% rename from juci/entrybox.cc rename to src/entrybox.cc diff --git a/juci/entrybox.h b/src/entrybox.h similarity index 100% rename from juci/entrybox.h rename to src/entrybox.h diff --git a/src/files.h b/src/files.h new file mode 100644 index 0000000..fa34cd7 --- /dev/null +++ b/src/files.h @@ -0,0 +1,225 @@ +#include +const std::string configjson = +"{\n" +" \"source\": {\n" +" \"colors\": {\n" +" \"text_color\": \"black\",\n" +" \"string\": \"#CC0000\",\n" +" \"namespace_ref\": \"#990099\",\n" +" \"type\": \"#0066FF\",\n" +" \"keyword\": \"blue\",\n" +" \"comment\": \"grey\",\n" +" \"own\": \"pink\",\n" +" \"diagnostic_warning\": \"orange\",\n" +" \"diagnostic_error\": \"red\"\n" +" },\n" +" \"syntax\": {\n" +" \"43\": \"type\",\n" +" \"46\": \"namespace_ref\",\n" +" \"109\": \"string\",\n" +" \"702\": \"keyword\",\n" +" \"703\": \"own\",\n" +" \"705\": \"comment\"\n" +" },\n" +" \"extensions\": [\n" +" \"c\",\n" +" \"cc\",\n" +" \"cpp\",\n" +" \"cxx\",\n" +" \"c++\",\n" +" \"h\",\n" +" \"hh\",\n" +" \"hpp\",\n" +" \"hxx\",\n" +" \"h++\"\n" +" ],\n" +" \"visual\": {\n" +" \"background\": \"white\",\n" +" \"background_selected\": \"blue\",\n" +" \"background_tooltips\": \"yellow\",\n" +" \"font\": \"Monospace\",\n" +" \"show_line_numbers\": 1,\n" +" \"highlight_current_line\": 1\n" +" },\n" +" \"tab_size\": 2,\n" +" \"tab_char\": \"\"\n" +" },\n" +" \"keybindings\": {\n" +" \"new_file\": \"n\",\n" +" \"open_folder\": \"o\",\n" +" \"open_file\": \"o\",\n" +" \"save\": \"s\",\n" +" \"save_as\": \"s\",\n" +" \"quit\": \"q\",\n" +" \"split_window\": \"s\",\n" +" \"close_tab\": \"w\",\n" +" \"edit_copy\": \"c\",\n" +" \"edit_cut\": \"x\",\n" +" \"edit_paste\": \"v\",\n" +" \"edit_undo\": \"z\",\n" +" \"edit_redo\": \"z\",\n" +" \"edit_find\": \"f\",\n" +" \"source_goto_declaration\": \"d\",\n" +" \"source_goto_method\": \"m\",\n" +" \"source_rename\": \"r\",\n" +" \"compile_and_run\": \"Return\",\n" +" \"compile\": \"Return\"\n" +" },\n" +" \"directoryfilter\": {\n" +" \"ignore\": [\n" +" \"cmake\",\n" +" \"#\",\n" +" \"~\",\n" +" \".idea\",\n" +" \".so\",\n" +" \"in-lowercase.pls\"\n" +" ],\n" +" \"exceptions\": [\n" +" \"cmakelists.txt\",\n" +" \"in-lowercase.pls\"\n" +" ]\n" +" },\n" +" \"project\": {\n" +" \"run_commands\": [\n" +" \"./.build/\"\n" +" ],\n" +" \"compile_commands\": [\n" +" \"rm -rf ./.build\",\n" +" \"mkdir ./.build\",\n" +" \"cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B./.build -H.\",\n" +" \"cd ./.build/; make\",\n" +" \"cp ./.build/compile_commands.json compile_commands.json\"\n" +" ]\n" +" },\n" +" \"example\": {\n" +" \"key\": \"value\",\n" +" \"key2\": [\n" +" \"val1\",\n" +" \"val2\",\n" +" 3\n" +" ],\n" +" \"key3\": \"value\"\n" +" }\n" +"}\n"; + +const std::string menuxml = +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n"; + +const std::string pluginspy = +"#!/usr/bin/python \n" +"import juci_to_python_api as juci \n" +"import glob \n" +"\n" +"def loadplugins(): \n" +" plugin_files = glob.glob(\"../plugins/*.py\") \n" +" for current_file in plugin_files: \n" +" juci.initPlugin(current_file) \n" +"loadplugins() \n"; + +const std::string snippetpy = +"#!/usr/bin/python \n" +"#snippet plugin \n" +"import juci_to_python_api as juci, inspect \n" +" \n" +"def initPlugin(): \n" +" juci.addMenuElement(\"Snippet\") \n" +" juci.addSubMenuElement(\"SnippetMenu\", #name of parent menu \n" +" \"Insert snippet\", #menu description \n" +" \"insertSnippet()\", #function to execute \n" +" inspect.getfile(inspect.currentframe()), #plugin path \n" +" \"space\") \n" +"snippets = {} \n" +" \n" +"snippets[\"for\"] = \"\"\"\ \n" +"for(int i=0; i \n" +" \n" +"int main(int argc, char *argv[]) { \n" +" std::cout << \"Hello, world! << std::endl; \n" +"} \n" +"\"\"\" \n" +" \n" +"def getSnippet(word): \n" +" try: \n" +" output = snippets[word] \n" +" except KeyError: \n" +" output = word \n" +" return output \n" +" \n" +"def insertSnippet(): \n" +" theWord=juci.getWord() \n" +" output=getSnippet(theWord) \n" +" juci.replaceWord(output) \n"; + + diff --git a/juci/juci.cc b/src/juci.cc similarity index 94% rename from juci/juci.cc rename to src/juci.cc index 4ade243..629c22b 100644 --- a/juci/juci.cc +++ b/src/juci.cc @@ -3,7 +3,7 @@ void init_logging() { add_common_attributes(); - add_file_log(keywords::file_name = "juci.log", + add_file_log(keywords::file_name = Singleton::log_dir() + "juci.log", keywords::auto_flush = true); INFO("Logging initalized"); } diff --git a/juci/juci.h b/src/juci.h similarity index 100% rename from juci/juci.h rename to src/juci.h diff --git a/juci/logging.h b/src/logging.h similarity index 100% rename from juci/logging.h rename to src/logging.h diff --git a/juci/menu.cc b/src/menu.cc similarity index 94% rename from juci/menu.cc rename to src/menu.cc index 3c3113a..7a040d3 100644 --- a/juci/menu.cc +++ b/src/menu.cc @@ -1,7 +1,9 @@ #include "menu.h" +#include "logging.h" #include Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { + INFO("Creating menu"); action_group = Gtk::ActionGroup::create(); ui_manager = Gtk::UIManager::create(); @@ -16,6 +18,7 @@ Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { action_group->add(Gtk::Action::create("HelpMenu", "Help")); action_group->add(Gtk::Action::create("HelpAbout", "About"), [this]() { }); + INFO("Menu created"); } Gtk::Widget& Menu::get_widget() { diff --git a/juci/menu.h b/src/menu.h similarity index 100% rename from juci/menu.h rename to src/menu.h diff --git a/juci/notebook.cc b/src/notebook.cc similarity index 95% rename from juci/notebook.cc rename to src/notebook.cc index e5ed07e..3c60ccb 100644 --- a/juci/notebook.cc +++ b/src/notebook.cc @@ -1,8 +1,7 @@ -#include #include "notebook.h" #include "logging.h" +#include "sourcefile.h" #include "singletons.h" -#include //TODO: remove using namespace std; //TODO: remove namespace sigc { @@ -86,10 +85,7 @@ bool Notebook::save(int page) { return false; auto view=get_view(page); if (view->file_path != "" && view->get_buffer()->get_modified()) { - std::ofstream file; - file.open(view->file_path); - file << view->get_buffer()->get_text(); - file.close(); + juci::filesystem::save(view->file_path, view->get_buffer()->get_text()); view->get_buffer()->set_modified(false); Singleton::terminal()->print("File saved to: " +view->file_path+"\n"); return true; diff --git a/juci/notebook.h b/src/notebook.h similarity index 100% rename from juci/notebook.h rename to src/notebook.h diff --git a/juci/selectiondialog.cc b/src/selectiondialog.cc similarity index 100% rename from juci/selectiondialog.cc rename to src/selectiondialog.cc diff --git a/juci/selectiondialog.h b/src/selectiondialog.h similarity index 100% rename from juci/selectiondialog.h rename to src/selectiondialog.h diff --git a/juci/singletons.cc b/src/singletons.cc similarity index 99% rename from juci/singletons.cc rename to src/singletons.cc index c43ba63..9af56e2 100644 --- a/juci/singletons.cc +++ b/src/singletons.cc @@ -15,4 +15,4 @@ Menu *Singleton::menu() { if(!menu_) menu_=std::unique_ptr(new Menu()); return menu_.get(); -} \ No newline at end of file +} diff --git a/juci/singletons.h b/src/singletons.h similarity index 79% rename from juci/singletons.h rename to src/singletons.h index 126965c..973eca8 100644 --- a/juci/singletons.h +++ b/src/singletons.h @@ -6,6 +6,7 @@ #include "terminal.h" #include "notebook.h" #include "menu.h" +#include class Singleton { public: @@ -19,7 +20,8 @@ public: static std::unique_ptr terminal_; static std::unique_ptr directories_; }; - + static std::string config_dir() { return std::string(getenv("HOME")) + "/.juci/config/"; } + static std::string log_dir() { return std::string(getenv("HOME")) + "/.juci/log/"; } static Terminal *terminal(); static Menu *menu(); private: diff --git a/juci/source.cc b/src/source.cc similarity index 99% rename from juci/source.cc rename to src/source.cc index c0fd173..0df15fb 100644 --- a/juci/source.cc +++ b/src/source.cc @@ -1,7 +1,6 @@ #include "source.h" #include "sourcefile.h" #include -#include #include #include "logging.h" #include @@ -42,13 +41,10 @@ file_path(file_path), project_path(project_path) { set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); set_show_line_numbers(Singleton::Config::source()->show_line_numbers); set_highlight_current_line(Singleton::Config::source()->highlight_current_line); - sourcefile s(file_path); get_source_buffer()->get_undo_manager()->begin_not_undoable_action(); - get_source_buffer()->set_text(s.get_content()); + get_source_buffer()->set_text(juci::filesystem::open(file_path)); get_source_buffer()->get_undo_manager()->end_not_undoable_action(); - - get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); - + get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); search_settings = gtk_source_search_settings_new(); gtk_source_search_settings_set_wrap_around(search_settings, true); search_context = gtk_source_search_context_new(get_source_buffer()->gobj(), search_settings); diff --git a/juci/source.h b/src/source.h similarity index 100% rename from juci/source.h rename to src/source.h diff --git a/src/sourcefile.cc b/src/sourcefile.cc new file mode 100644 index 0000000..0583f06 --- /dev/null +++ b/src/sourcefile.cc @@ -0,0 +1,32 @@ +#include "sourcefile.h" +#include + +std::string juci::filesystem::open(std::string path) { + std::string res; + for (auto &line : lines(path)) { + res += line; + } + return res; +} + +std::vector juci::filesystem::lines(std::string path) { + std::vector res; + std::ifstream input(path); + if (input.is_open()) { + do { res.emplace_back(); } while(getline(input, res.back())); + } + input.close(); + return res; +} + +int juci::filesystem::save(std::string path, std::string new_content) { + std::ofstream output(path); + if(output.is_open()) { + output << new_content; + } else { + output.close(); + return 1; + } + output.close(); + return 0; +} \ No newline at end of file diff --git a/src/sourcefile.h b/src/sourcefile.h new file mode 100644 index 0000000..c86bc89 --- /dev/null +++ b/src/sourcefile.h @@ -0,0 +1,20 @@ +#ifndef JUCI_SOURCEFILE_H_ +#define JUCI_SOURCEFILE_H_ +#include +#include +#include + +namespace juci { + class filesystem { + public: + static std::string open(std::string); + static std::string open(boost::filesystem::path path) { return open(path.string()); } + static std::vector lines(std::string); + static std::vector lines(boost::filesystem::path path) { return lines(path.string()); }; + static int save(std::string, std::string); + static int save(boost::filesystem::path path, std::string new_content) { return save(path.string(), new_content); } + static int save(std::string path) { return save(path, ""); }; + static int save(boost::filesystem::path path) { return save(path, ""); }; + }; +} // namepace juci +#endif // JUCI_SOURCEFILE_H_ diff --git a/juci/terminal.cc b/src/terminal.cc similarity index 100% rename from juci/terminal.cc rename to src/terminal.cc diff --git a/juci/terminal.h b/src/terminal.h similarity index 100% rename from juci/terminal.h rename to src/terminal.h diff --git a/juci/tooltips.cc b/src/tooltips.cc similarity index 100% rename from juci/tooltips.cc rename to src/tooltips.cc diff --git a/juci/tooltips.h b/src/tooltips.h similarity index 100% rename from juci/tooltips.h rename to src/tooltips.h diff --git a/juci/window.cc b/src/window.cc similarity index 94% rename from juci/window.cc rename to src/window.cc index a5365d8..fd2ba56 100644 --- a/juci/window.cc +++ b/src/window.cc @@ -1,6 +1,7 @@ #include "window.h" #include "logging.h" #include "singletons.h" +#include "sourcefile.h" #include "config.h" #include "api.h" @@ -14,27 +15,27 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL) { set_default_size(600, 400); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); add(box); - + MainConfig(); //Read the configs here PluginApi(&this->notebook); //Initialise plugins add_menu(); - + box.pack_start(entry_box, Gtk::PACK_SHRINK); - + directory_and_notebook_panes.pack1(directories, true, true); directory_and_notebook_panes.pack2(notebook); directory_and_notebook_panes.set_position(120); - + vpaned.set_position(300); vpaned.pack1(directory_and_notebook_panes, true, false); vpaned.pack2(*Singleton::terminal(), true, true); box.pack_end(vpaned); show_all_children(); - + directories.on_row_activated=[this](const std::string &file) { notebook.open(file); }; - + entry_box.signal_show().connect([this](){ std::vector focus_chain; focus_chain.emplace_back(&entry_box); @@ -48,7 +49,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL) { notebook.get_current_view()->grab_focus(); } }); - + notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) { if(search_entry_shown && entry_box.labels.size()>0 && notebook.get_current_page()!=-1) { notebook.get_current_view()->update_search_occurrences=[this](int number){ @@ -56,14 +57,14 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL) { }; notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search); } - + if(notebook.get_current_page()!=-1) { if(auto menu_item=dynamic_cast(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration"))) menu_item->set_sensitive((bool)notebook.get_current_view()->get_declaration_location); - + if(auto menu_item=dynamic_cast(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoMethod"))) menu_item->set_sensitive((bool)notebook.get_current_view()->goto_method); - + if(auto menu_item=dynamic_cast(Singleton::menu()->ui_manager->get_widget("/MenuBar/SourceMenu/SourceRename"))) menu_item->set_sensitive((bool)notebook.get_current_view()->rename_similar_tokens); } @@ -73,6 +74,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL) { void Window::add_menu() { auto menu=Singleton::menu(); + INFO("Adding actions to menu"); menu->action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu->key_map["quit"]), [this]() { hide(); }); @@ -92,13 +94,13 @@ void Window::add_menu() { menu->action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu->key_map["save"]), [this]() { notebook.save_current(); }); - + menu->action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(menu->key_map["edit_copy"]), [this]() { auto widget=get_focus(); if(auto entry=dynamic_cast(widget)) entry->copy_clipboard(); else if(auto text_view=dynamic_cast(widget)) - text_view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); + text_view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); }); menu->action_group->add(Gtk::Action::create("EditCut", "Cut"), Gtk::AccelKey(menu->key_map["edit_cut"]), [this]() { auto widget=get_focus(); @@ -118,7 +120,7 @@ void Window::add_menu() { search_and_replace_entry(); }); menu->action_group->add(Gtk::Action::create("EditUndo", "Undo"), Gtk::AccelKey(menu->key_map["edit_undo"]), [this]() { - INFO("On undo"); + INFO("On undo"); if(notebook.get_current_page()!=-1) { auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager(); if (undo_manager->can_undo()) { @@ -126,7 +128,7 @@ void Window::add_menu() { } } INFO("Done undo"); - }); + }); menu->action_group->add(Gtk::Action::create("EditRedo", "Redo"), Gtk::AccelKey(menu->key_map["edit_redo"]), [this]() { INFO("On Redo"); if(notebook.get_current_page()!=-1) { @@ -137,7 +139,7 @@ void Window::add_menu() { } INFO("Done Redo"); }); - + menu->action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to declaration"), Gtk::AccelKey(menu->key_map["source_goto_declaration"]), [this]() { if(notebook.get_current_page()!=-1) { if(notebook.get_current_view()->get_declaration_location) { @@ -162,7 +164,7 @@ void Window::add_menu() { menu->action_group->add(Gtk::Action::create("SourceRename", "Rename"), Gtk::AccelKey(menu->key_map["source_rename"]), [this]() { rename_token_entry(); }); - + menu->action_group->add(Gtk::Action::create("ProjectCompileAndRun", "Compile And Run"), Gtk::AccelKey(menu->key_map["compile_and_run"]), [this]() { if(notebook.get_current_page()==-1) return; @@ -205,9 +207,9 @@ void Window::add_menu() { menu->action_group->add(Gtk::Action::create("WindowCloseTab", "Close tab"), Gtk::AccelKey(menu->key_map["close_tab"]), [this]() { notebook.close_current_page(); }); - add_accel_group(menu->ui_manager->get_accel_group()); menu->build(); + INFO("Menu build") box.pack_start(menu->get_widget(), Gtk::PACK_SHRINK); } @@ -248,7 +250,7 @@ bool Window::on_key_press_event(GdkEventKey *event) { } } #endif - + return Gtk::Window::on_key_press_event(event); } @@ -278,17 +280,11 @@ void Window::new_file_entry() { Singleton::terminal()->print("Error: "+p.string()+" already exists.\n"); } else { - std::ofstream f(p.string().c_str()); - if(f) { - notebook.open(boost::filesystem::canonical(p).string()); - Singleton::terminal()->print("New file "+p.string()+" created.\n"); - if(notebook.project_path!="") - directories.open_folder(notebook.project_path); //TODO: Do refresh instead - } - else { - Singleton::terminal()->print("Error: could not create new file "+p.string()+".\n"); - } - f.close(); + juci::filesystem::save(p); + notebook.open(boost::filesystem::canonical(p).string()); + Singleton::terminal()->print("New file "+p.string()+" created.\n"); + if(notebook.project_path!="") + directories.open_folder(notebook.project_path); //TODO: Do refresh instead } } entry_box.hide(); @@ -423,7 +419,7 @@ void Window::search_and_replace_entry() { if(notebook.get_current_page()!=-1) notebook.get_current_view()->search_highlight(search_entry_it->get_text(), case_sensitive_search, regex_search); }); - + entry_box.entries.emplace_back(last_replace, [this](const std::string &content){ if(notebook.get_current_page()!=-1) notebook.get_current_view()->replace_forward(content); @@ -441,7 +437,7 @@ void Window::search_and_replace_entry() { replace_entry_it->signal_changed().connect([this, replace_entry_it](){ last_replace=replace_entry_it->get_text(); }); - + entry_box.buttons.emplace_back("Find", [this](){ if(notebook.get_current_page()!=-1) notebook.get_current_view()->search_forward(); @@ -498,23 +494,23 @@ void Window::rename_token_entry() { }; label_it->update(0, ""); entry_box.entries.emplace_back(*token_name, [this, token_name, token](const std::string& content){ - if(notebook.get_current_page()!=-1 && content!=*token_name) { - for(int c=0;crename_similar_tokens) { - auto number=notebook.get_view(c)->rename_similar_tokens(*token, content); - if(number>0) { - Singleton::terminal()->print("Replaced "+std::to_string(number)+" occurrences in file "+notebook.get_view(c)->file_path+"\n"); - notebook.save(c); + if(notebook.get_current_page()!=-1 && content!=*token_name) { + for(int c=0;crename_similar_tokens) { + auto number=notebook.get_view(c)->rename_similar_tokens(*token, content); + if(number>0) { + Singleton::terminal()->print("Replaced "+std::to_string(number)+" occurrences in file "+notebook.get_view(c)->file_path+"\n"); + notebook.save(c); + } } } + entry_box.hide(); } - entry_box.hide(); - } - }); + }); auto entry_it=entry_box.entries.begin(); entry_box.buttons.emplace_back("Rename", [this, entry_it](){ - entry_it->activate(); - }); + entry_it->activate(); + }); entry_box.show(); } } diff --git a/juci/window.h b/src/window.h similarity index 100% rename from juci/window.h rename to src/window.h