From e68c420fb138a1e0b8401cef0168d89bcf348684 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 17 Oct 2015 11:54:35 +0200 Subject: [PATCH 01/34] Another try at: libclangmm submodule now links to https://github.com/cppit/libclangmm/tree/v0.9.3 --- .gitmodules | 2 +- libclangmm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index da58f90..4616210 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "libclangmm"] path = libclangmm - url = https://github.com/cppit/libclangmm/tree/v0.9.3 + url = https://github.com/cppit/libclangmm diff --git a/libclangmm b/libclangmm index e060dec..f1f784d 160000 --- a/libclangmm +++ b/libclangmm @@ -1 +1 @@ -Subproject commit e060dec32bb8306eff6f9114092cdbefe8fea5fb +Subproject commit f1f784dd02d78da35a27034c6cc854e676d4f78b From 2c0ee4614a9c378eb91ff06b761a324132351e8d Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 17 Oct 2015 12:04:27 +0200 Subject: [PATCH 02/34] Yet another try on libclangmm version linking. --- .gitmodules | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 4616210..2428fa6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "libclangmm"] path = libclangmm - url = https://github.com/cppit/libclangmm + url = https://github.com/cppit/libclangmm.git + branch = v0.9.3 From 77995d0fc16d32039f86b040ce282249821bcde4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 18 Oct 2015 10:44:48 +0200 Subject: [PATCH 03/34] Removed the MINGW-packages directory, since it is no longer needed for MSYS2. --- .../0006-hack-convert-path-back-to-unix.patch | 15 ----- .../mingw-w64-gtksourceview3/LICENSE | 27 -------- .../mingw-w64-gtksourceview3/PKGBUILD | 64 ------------------- .../mingw-w64-gtksourceviewmm3/LICENSE | 27 -------- .../mingw-w64-gtksourceviewmm3/PKGBUILD | 33 ---------- 5 files changed, 166 deletions(-) delete mode 100644 MINGW-packages/mingw-w64-gtksourceview3/0006-hack-convert-path-back-to-unix.patch delete mode 100644 MINGW-packages/mingw-w64-gtksourceview3/LICENSE delete mode 100644 MINGW-packages/mingw-w64-gtksourceview3/PKGBUILD delete mode 100644 MINGW-packages/mingw-w64-gtksourceviewmm3/LICENSE delete mode 100644 MINGW-packages/mingw-w64-gtksourceviewmm3/PKGBUILD diff --git a/MINGW-packages/mingw-w64-gtksourceview3/0006-hack-convert-path-back-to-unix.patch b/MINGW-packages/mingw-w64-gtksourceview3/0006-hack-convert-path-back-to-unix.patch deleted file mode 100644 index 68f217f..0000000 --- a/MINGW-packages/mingw-w64-gtksourceview3/0006-hack-convert-path-back-to-unix.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- gtksourceview-3.13.90/configure.ac.orig 2014-08-22 00:42:28.532000000 +0400 -+++ gtksourceview-3.13.90/configure.ac 2014-08-22 00:43:00.621200000 +0400 -@@ -133,6 +133,12 @@ - AC_MSG_RESULT([$GLADE_CATALOG_DIR]) - AC_SUBST(GLADE_CATALOG_DIR)]) - -+case "$host" in -+ *-*-mingw*) -+ GLADE_CATALOG_DIR=`cygpath -u $GLADE_CATALOG_DIR` -+ ;; -+esac -+ - # i18N stuff - IT_PROG_INTLTOOL([0.40]) - AS_IF([test "$USE_NLS" = "yes"], diff --git a/MINGW-packages/mingw-w64-gtksourceview3/LICENSE b/MINGW-packages/mingw-w64-gtksourceview3/LICENSE deleted file mode 100644 index e0f07ba..0000000 --- a/MINGW-packages/mingw-w64-gtksourceview3/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013, Алексей -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MINGW-packages/mingw-w64-gtksourceview3/PKGBUILD b/MINGW-packages/mingw-w64-gtksourceview3/PKGBUILD deleted file mode 100644 index 038333a..0000000 --- a/MINGW-packages/mingw-w64-gtksourceview3/PKGBUILD +++ /dev/null @@ -1,64 +0,0 @@ -# Maintainer: Alexey Pavlov - -_realname=gtksourceview -pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}3" -pkgver=3.12.0 -pkgrel=2 -pkgdesc="A text widget adding syntax highlighting and more to GNOME (mingw-w64)" -arch=('any') -url="http://www.gnome.org" -license=("LGPL") -makedepends=("${MINGW_PACKAGE_PREFIX}-gcc" - "${MINGW_PACKAGE_PREFIX}-pkg-config" - "${MINGW_PACKAGE_PREFIX}-gobject-introspection" - "${MINGW_PACKAGE_PREFIX}-glade" - "${MINGW_PACKAGE_PREFIX}-vala" - "intltool" - "gtk-doc") -depends=("${MINGW_PACKAGE_PREFIX}-gtk3" - "${MINGW_PACKAGE_PREFIX}-libxml2") -options=(!libtool strip staticlibs) -source=("http://ftp.gnome.org/pub/gnome/sources/gtksourceview/${pkgver%.*}/gtksourceview-${pkgver}.tar.xz" - 0006-hack-convert-path-back-to-unix.patch) -md5sums=('8850fc0aee4893668ede37a30ef05e85' - '324c9e3bb2e4fa2a4977653ce6ed6ef9') - -prepare() { - cd ${_realname}-${pkgver} - patch -p1 -i ${srcdir}/0006-hack-convert-path-back-to-unix.patch - - autoreconf -fi -} - -build() { - mkdir -p "${srcdir}/build-${MINGW_CHOST}" - cd "${srcdir}/build-${MINGW_CHOST}" - - mkdir -p docs/reference/html - cp -rf ../${_realname}-${pkgver}/docs/reference/html/* docs/reference/html - - DATADIRNAME=share \ - ../${_realname}-${pkgver}/configure \ - --prefix=${MINGW_PREFIX} \ - --build=${MINGW_CHOST} \ - --host=${MINGW_CHOST} \ - --enable-shared \ - --disable-static \ - --enable-glade-catalog - - LC_ALL=C make -} - -package() { - cd "${srcdir}/build-${MINGW_CHOST}" - make -j1 DESTDIR="${pkgdir}" install - - for ff in ${pkgdir}/${MINGW_PREFIX}/bin/libgtksourceview*.dll; do - local _reallib=$(basename $ff) - _reallib=${_reallib%.dll} - _reallib=${_reallib#lib} - sed -e "s|library=\"gtksourceview-3.0\"|library=\"${_reallib}\"|g" -i ${pkgdir}/${MINGW_PREFIX}/share/glade/catalogs/gtksourceview.xml - done - - install -Dm644 "${srcdir}/${_realname}-${pkgver}/COPYING" "${pkgdir}${MINGW_PREFIX}/share/licenses/${_realname}/COPYING" -} diff --git a/MINGW-packages/mingw-w64-gtksourceviewmm3/LICENSE b/MINGW-packages/mingw-w64-gtksourceviewmm3/LICENSE deleted file mode 100644 index e0f07ba..0000000 --- a/MINGW-packages/mingw-w64-gtksourceviewmm3/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013, Алексей -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MINGW-packages/mingw-w64-gtksourceviewmm3/PKGBUILD b/MINGW-packages/mingw-w64-gtksourceviewmm3/PKGBUILD deleted file mode 100644 index 0d842a8..0000000 --- a/MINGW-packages/mingw-w64-gtksourceviewmm3/PKGBUILD +++ /dev/null @@ -1,33 +0,0 @@ -_realname=gtksourceviewmm3 -pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}" -pkgver=3.12.0 -pkgrel=1 -pkgdesc="C++ bindings for gtksourceview3 (mingw-w64)" -arch=('any') -url="https://developer.gnome.org/gtksourceviewmm/" -license=("LGPL") -makedepends=("patch" "${MINGW_PACKAGE_PREFIX}-gcc" "${MINGW_PACKAGE_PREFIX}-pkg-config") -depends=("${MINGW_PACKAGE_PREFIX}-gtksourceview3=${pkgver}") -options=('staticlibs' 'strip') -source=("https://download.gnome.org/sources/gtksourceviewmm/${pkgver%.*}/gtksourceviewmm-${pkgver}.tar.xz") -sha256sums=("73939031bcc60e6ad31a315ec84b132deba15e5732de16e75fe424a619267ace") - -build() { - mkdir -p "${srcdir}/build-${MINGW_CHOST}" - cd "${srcdir}/build-${MINGW_CHOST}" - ../gtksourceviewmm-${pkgver}/configure \ - CXXFLAGS=-std=c++11 \ - --prefix=${MINGW_PREFIX} \ - --build=${MINGW_CHOST} \ - --host=${MINGW_CHOST} \ - --enable-shared \ - --enable-static \ - --disable-documentation - make -} - -package() { - cd "${srcdir}/build-${MINGW_CHOST}" - make DESTDIR="${pkgdir}" install - find "${pkgdir}${MINGW_PREFIX}" -name '*.def' -o -name '*.exp' | xargs -rtl1 rm -} \ No newline at end of file From 59b32b25f15107f5be760eedaba808b33a8b1f4f Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 18 Oct 2015 20:36:19 +0200 Subject: [PATCH 04/34] Added the missing checks if paths from Dialog::* were empty. --- src/files.h | 2 +- src/window.cc | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/files.h b/src/files.h index 8f49573..2c5d92f 100644 --- a/src/files.h +++ b/src/files.h @@ -70,7 +70,7 @@ const std::string configjson = " \"source_spellcheck_clear\": \"\",\n" " \"source_spellcheck_next_error\": \"e\",\n" " \"source_indentation_set_buffer_tab\": \"\",\n" -" \"source_indentation_auto_indent_buffer\": \"\",\n" +" \"source_indentation_auto_indent_buffer\": \"i\",\n" " \"source_goto_line\": \"g\",\n" " \"source_center_cursor\": \"l\",\n" " \"source_goto_declaration\": \"d\",\n" diff --git a/src/window.cc b/src/window.cc index 142a8c1..cd7a302 100644 --- a/src/window.cc +++ b/src/window.cc @@ -200,14 +200,13 @@ void Window::create_menu() { } else Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); + Singleton::directories()->select(path); } - Singleton::directories()->select(path); }); menu.action_group->add(Gtk::Action::create("FileNewProject", "New Project")); menu.action_group->add(Gtk::Action::create("FileNewProjectCpp", "C++"), [this]() { - boost::filesystem::path project_path = Dialog::new_folder(); - if(project_path=="") - return; + boost::filesystem::path project_path = Dialog::new_folder(); + if(project_path!="") { auto project_name=project_path.filename().string(); for(size_t c=0;cprint("Error: Could not create project "+project_path.string()+"\n"); + } }); menu.action_group->add(Gtk::Action::create("FileOpenFile", "Open File"), Gtk::AccelKey(menu.key_map["open_file"]), [this]() { - notebook.open(Dialog::select_file()); + auto path=Dialog::select_file(); + if(path!="") + notebook.open(path); }); menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(menu.key_map["open_folder"]), [this]() { auto path = Dialog::select_folder(); From 7a4d9e6d6146f178e851327f9adaaaeaf78557f5 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 11:53:43 +0200 Subject: [PATCH 05/34] Implemented auto-indentation of a whole buffer through clang-format. --- src/source.h | 1 + src/source_clang.cc | 22 +++++++++++++ src/terminal.cc | 77 +++++++++++++++++++++++++++++++++++-------- src/terminal.h | 1 + src/terminal_win.cc | 80 ++++++++++++++++++++++++++++++++++++++++----- src/window.cc | 6 +++- 6 files changed, 164 insertions(+), 23 deletions(-) diff --git a/src/source.h b/src/source.h index 2b60633..14f46c4 100644 --- a/src/source.h +++ b/src/source.h @@ -100,6 +100,7 @@ namespace Source { boost::filesystem::path project_path; Glib::RefPtr language; + std::function auto_indent; std::function()> get_declaration_location; std::function goto_method; std::function get_token; diff --git a/src/source_clang.cc b/src/source_clang.cc index 4e39072..8cffec8 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1,5 +1,6 @@ #include "source_clang.h" #include "singletons.h" +#include "sourcefile.h" #include //TODO: remove using namespace std; //TODO: remove @@ -928,6 +929,27 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { } }); + auto_indent=[this]() { + boost::filesystem::path temp_file_path = boost::filesystem::unique_path(); + juci::filesystem::write(temp_file_path, get_buffer()); + std::string command="clang-format \""+temp_file_path.string()+"\""; + command+=" -style=\"{IndentWidth: "+std::to_string(tab_size); + command+="}\""; + std::stringstream stdout_stream; + auto exit_code=Singleton::terminal()->execute(stdout_stream, command); + + if(exit_code==0) { + get_source_buffer()->begin_user_action(); + auto cursor_line_nr=get_buffer()->get_insert()->get_iter().get_line(); + get_buffer()->erase(get_buffer()->begin(), get_buffer()->end()); + get_buffer()->insert(get_buffer()->begin(), stdout_stream.str()); + if(cursor_line_nrget_line_count()) + get_buffer()->place_cursor(get_buffer()->get_iter_at_line(cursor_line_nr)); + get_source_buffer()->end_user_action(); + set_tab_char_and_size(' ', tab_size); //clang-format only does basic indentation with spaces as I understand it + } + }; + get_token=[this]() -> Token { if(source_readable) { auto iter=get_buffer()->get_insert()->get_iter(); diff --git a/src/terminal.cc b/src/terminal.cc index 8d3caad..989e3f4 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -8,6 +8,8 @@ #include //TODO: remove using namespace std; //TODO: remove +const size_t buffer_size=131072; + //A working implementation of popen3, with all pipes getting closed properly. //TODO: Eidheim is going to publish this one on his github, along with example uses pid_t popen3(const std::string &command, const std::string &path, int *stdin_fd, int *stdout_fd, int *stderr_fd) { @@ -145,7 +147,6 @@ Terminal::Terminal() { } int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { - JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); @@ -155,10 +156,11 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path } else { std::thread stderr_thread([this, stderr_fd](){ - char buffer[1024]; + char buffer[buffer_size]; ssize_t n; - while ((n=read(stderr_fd, buffer, 1024)) > 0) { + while ((n=read(stderr_fd, buffer, buffer_size)) > 0) { std::string message; + message.reserve(n); for(ssize_t c=0;c 0) { + while ((n=read(stdout_fd, buffer, buffer_size)) > 0) { std::string message; + message.reserve(n); for(ssize_t c=0;c 0) { + std::string message; + message.reserve(n); + for(ssize_t c=0;c 0) { + Glib::ustring umessage; + umessage.reserve(n); + for(ssize_t c=0;c callback) { std::thread async_execute_thread([this, command, path, callback](){ - JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; async_executes_mutex.lock(); stdin_buffer.clear(); @@ -205,10 +256,11 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem } else { std::thread stderr_thread([this, stderr_fd](){ - char buffer[1024]; + char buffer[buffer_size]; ssize_t n; - while ((n=read(stderr_fd, buffer, 1024)) > 0) { + while ((n=read(stderr_fd, buffer, buffer_size)) > 0) { std::string message; + message.reserve(n); for(ssize_t c=0;c 0) { + while ((n=read(stdout_fd, buffer, buffer_size)) > 0) { std::string message; + message.reserve(n); for(ssize_t c=0;c callback=nullptr); void kill_last_async_execute(bool force=false); void kill_async_executes(bool force=false); diff --git a/src/terminal_win.cc b/src/terminal_win.cc index ba65bfe..cd6a927 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -8,7 +8,7 @@ #include //TODO: remove using namespace std; //TODO: remove -#define BUFSIZE 1024 +const size_t buffer_size=131072; HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin_h, HANDLE *stdout_h, HANDLE *stderr_h) { HANDLE g_hChildStd_IN_Rd = NULL; @@ -192,13 +192,14 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path } std::thread stderr_thread([this, stderr_h](){ DWORD n; - CHAR buffer[BUFSIZE]; + CHAR buffer[buffer_size]; for (;;) { - BOOL bSuccess = ReadFile(stderr_h, buffer, BUFSIZE, &n, NULL); + BOOL bSuccess = ReadFile(stderr_h, buffer, static_cast(buffer_size), &n, NULL); if(!bSuccess || n == 0) break; std::string message; + message.reserve(n); for(DWORD c=0;c(buffer_size), &n, NULL); if(!bSuccess || n == 0) break; std::string message; + message.reserve(n); for(DWORD c=0;c(buffer_size), &n, NULL); + if(!bSuccess || n == 0) + break; + + std::string message; + message.reserve(n); + for(DWORD c=0;c(buffer_size), &n, NULL); + if(!bSuccess || n == 0) + break; + Glib::ustring umessage; + umessage.reserve(n); + for(DWORD c=0;c callback) { std::thread async_execute_thread([this, command, path, callback](){ HANDLE stdin_h, stdout_h, stderr_h; @@ -252,13 +312,14 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem std::thread stderr_thread([this, stderr_h](){ DWORD n; - CHAR buffer[BUFSIZE]; + CHAR buffer[buffer_size]; for (;;) { - BOOL bSuccess = ReadFile(stderr_h, buffer, BUFSIZE, &n, NULL); + BOOL bSuccess = ReadFile(stderr_h, buffer, static_cast(buffer_size), &n, NULL); if(!bSuccess || n == 0) break; std::string message; + message.reserve(n); for(DWORD c=0;c(buffer_size), &n, NULL); if(!bSuccess || n == 0) break; std::string message; + message.reserve(n); for(DWORD c=0;csearch_highlight(last_search, case_sensitive_search, regex_search); } + if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceIndentationAutoIndentBuffer"))) + menu_item->set_sensitive((bool)notebook.get_current_view()->auto_indent); + if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration"))) menu_item->set_sensitive((bool)notebook.get_current_view()->get_declaration_location); @@ -340,7 +343,8 @@ void Window::create_menu() { set_tab_entry(); }); menu.action_group->add(Gtk::Action::create("SourceIndentationAutoIndentBuffer", "Auto-Indent Current Buffer"), Gtk::AccelKey(menu.key_map["source_indentation_auto_indent_buffer"]), [this]() { - Singleton::terminal()->print("Auto-Indent Current Buffer will soon be implemented.\n"); + if(notebook.get_current_page()!=-1 && notebook.get_current_view()->auto_indent) + notebook.get_current_view()->auto_indent(); }); menu.action_group->add(Gtk::Action::create("SourceGotoLine", "Go to Line"), Gtk::AccelKey(menu.key_map["source_goto_line"]), [this]() { goto_line_entry(); From 6484c75e95c6e6ecaaa250e55165371656182d85 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 12:30:04 +0200 Subject: [PATCH 06/34] Now creates a tmp file in the users's tmp file directory when doing auto-indentation. --- src/source_clang.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 8cffec8..4d990cd 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -930,14 +930,16 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { }); auto_indent=[this]() { - boost::filesystem::path temp_file_path = boost::filesystem::unique_path(); + boost::filesystem::path temp_file = "jucipp_auto_indent_tmp_file"; + auto temp_directory=boost::filesystem::temp_directory_path(); + boost::filesystem::path temp_file_path=temp_directory.string()+'/'+temp_file.string(); juci::filesystem::write(temp_file_path, get_buffer()); std::string command="clang-format \""+temp_file_path.string()+"\""; command+=" -style=\"{IndentWidth: "+std::to_string(tab_size); command+="}\""; std::stringstream stdout_stream; - auto exit_code=Singleton::terminal()->execute(stdout_stream, command); + auto exit_code=Singleton::terminal()->execute(stdout_stream, command); if(exit_code==0) { get_source_buffer()->begin_user_action(); auto cursor_line_nr=get_buffer()->get_insert()->get_iter().get_line(); @@ -948,6 +950,8 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { get_source_buffer()->end_user_action(); set_tab_char_and_size(' ', tab_size); //clang-format only does basic indentation with spaces as I understand it } + + boost::filesystem::remove(temp_file_path); }; get_token=[this]() -> Token { From 8710dce3db445b34cbc622da914ddc2353b56a9b Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 12:43:56 +0200 Subject: [PATCH 07/34] Added auto-indentation in features. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b769f72..738f718 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ towards libclang with speed and ease of use in mind. * Run shell commands within JuCi++, even on Windows * Regex search and replace * Smart paste, keys and indentation +* Auto-indentation through clang-format (on some systems you need to create a symbolic link `/usr/local/bin/clang-format` to a specific clang-format-version) * Source minimap * Full UTF-8 support From 5bf5a0f828942454f56b37c96c09ca83068dc227 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 12:48:02 +0200 Subject: [PATCH 08/34] added clang-format to OS X installation notes. At the time being, one must install a spesific version of clang-format on Linux... --- README.md | 2 +- docs/install.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 738f718..f8df7de 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ towards libclang with speed and ease of use in mind. * Run shell commands within JuCi++, even on Windows * Regex search and replace * Smart paste, keys and indentation -* Auto-indentation through clang-format (on some systems you need to create a symbolic link `/usr/local/bin/clang-format` to a specific clang-format-version) +* Auto-indentation through clang-format (on some systems you need to create a symbolic link `/usr/local/bin/clang-format` to a specific installed clang-format-version) * Source minimap * Full UTF-8 support diff --git a/docs/install.md b/docs/install.md index 5877e17..3b09431 100644 --- a/docs/install.md +++ b/docs/install.md @@ -37,7 +37,7 @@ sudo make install ## OS X with Homebrew (http://brew.sh/) Install dependencies (installing llvm may take some time): ```sh -brew install cmake --with-clang llvm pkg-config boost gtkmm3 homebrew/x11/gtksourceviewmm3 aspell +brew install cmake --with-clang llvm pkg-config boost gtkmm3 homebrew/x11/gtksourceviewmm3 aspell clang-format ``` Get juCi++ source, compile and install: From d5b98be82e8ea7d94ccf499abaa080da917640f6 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 13:00:23 +0200 Subject: [PATCH 09/34] Specified that the auto-indentation feature using clang-format is for whole files. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8df7de..ace3b6d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ towards libclang with speed and ease of use in mind. * Run shell commands within JuCi++, even on Windows * Regex search and replace * Smart paste, keys and indentation -* Auto-indentation through clang-format (on some systems you need to create a symbolic link `/usr/local/bin/clang-format` to a specific installed clang-format-version) +* Auto-indentation of files through clang-format (on some systems you need to create a symbolic link `/usr/local/bin/clang-format` to a specific installed clang-format-version) * Source minimap * Full UTF-8 support From 8e7c3f963330b2b78813f030d35d9cbdac14573d Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 13:43:21 +0200 Subject: [PATCH 10/34] Cleanup of clang-format documentation. --- README.md | 2 +- docs/install.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ace3b6d..d36d1d2 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ towards libclang with speed and ease of use in mind. * Run shell commands within JuCi++, even on Windows * Regex search and replace * Smart paste, keys and indentation -* Auto-indentation of files through clang-format (on some systems you need to create a symbolic link `/usr/local/bin/clang-format` to a specific installed clang-format-version) +* Auto-indentation of C++ file buffers through [clang-format](http://clang.llvm.org/docs/ClangFormat.html) * Source minimap * Full UTF-8 support diff --git a/docs/install.md b/docs/install.md index 3b09431..95bcaa0 100644 --- a/docs/install.md +++ b/docs/install.md @@ -15,6 +15,12 @@ make sudo make install ``` +To use clang-format for auto-indentation of C++ files (replace \[version\] with an available clang-format version): +```sh +sudo apt-get install clang-format-[version] +sudo ln -s /usr/bin/clang-format-[version] /usr/local/bin/clang-format +``` + ## Ubuntu 14/Linux Mint 17 Install dependencies: ```sh @@ -34,6 +40,12 @@ make sudo make install ``` +To use clang-format for auto-indentation of C++ files (replace \[version\] with an available clang-format version): +```sh +sudo apt-get install clang-format-[version] +sudo ln -s /usr/bin/clang-format-[version] /usr/local/bin/clang-format +``` + ## OS X with Homebrew (http://brew.sh/) Install dependencies (installing llvm may take some time): ```sh From 30beb18ff3ace60e18d3485a3fe14181f37858ad Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 14:43:45 +0200 Subject: [PATCH 11/34] Added clang-format style options to config file. --- src/config.cc | 2 ++ src/files.h | 13 +++++++------ src/source.h | 1 + src/source_clang.cc | 2 ++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/config.cc b/src/config.cc index 6b98535..51fb2ac 100644 --- a/src/config.cc +++ b/src/config.cc @@ -135,6 +135,8 @@ void MainConfig::GenerateSource() { for (auto &i : source_json.get_child("clang_types")) source_cfg->clang_types[i.first] = i.second.get_value(); + source_cfg->clang_format_style = source_json.get("clang_format_style"); + auto pt_doc_search=cfg.get_child("documentation_searches"); for(auto &pt_doc_search_lang: pt_doc_search) { source_cfg->documentation_searches[pt_doc_search_lang.first].separator=pt_doc_search_lang.second.get("separator"); diff --git a/src/files.h b/src/files.h index 2c5d92f..d892167 100644 --- a/src/files.h +++ b/src/files.h @@ -29,6 +29,12 @@ const std::string configjson = " \"show_map\": true,\n" " \"map_font_size\": \"1\",\n" " \"spellcheck_language\": \"en_US\", //Use \"\" to set language from your locale settings\n" +" \"auto_tab_char_and_size\": true, //Use false to always use default tab char and size\n" +" \"default_tab_char\": \" \", //Use \"\\t\" for regular tab\n" +" \"default_tab_size\": 2,\n" +" \"wrap_lines\": false,\n" +" \"highlight_current_line\": true,\n" +" \"show_line_numbers\": true,\n" " \"clang_types\": {\n" " \"8\": \"def:function\",\n" " \"21\": \"def:function\",\n" @@ -43,12 +49,7 @@ const std::string configjson = " \"702\": \"def:statement\",\n" " \"705\": \"def:comment\"\n" " },\n" -" \"auto_tab_char_and_size\": true, //Use false to always use default tab char and size\n" -" \"default_tab_char\": \" \", //Use \"\\t\" for regular tab\n" -" \"default_tab_size\": 2,\n" -" \"wrap_lines\": false,\n" -" \"highlight_current_line\": true,\n" -" \"show_line_numbers\": true\n" +" \"clang_format_style\": \"UseTab: Never, ColumnLimit: 0\" //See http://clang.llvm.org/docs/ClangFormatStyleOptions.html\n" " },\n" " \"keybindings\": {\n" " \"new_file\": \"n\",\n" diff --git a/src/source.h b/src/source.h index 14f46c4..bb7a308 100644 --- a/src/source.h +++ b/src/source.h @@ -36,6 +36,7 @@ namespace Source { bool highlight_current_line; bool show_line_numbers; std::unordered_map clang_types; + std::string clang_format_style; std::unordered_map documentation_searches; }; diff --git a/src/source_clang.cc b/src/source_clang.cc index 4d990cd..d855131 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -936,6 +936,8 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { juci::filesystem::write(temp_file_path, get_buffer()); std::string command="clang-format \""+temp_file_path.string()+"\""; command+=" -style=\"{IndentWidth: "+std::to_string(tab_size); + if(Singleton::Config::source()->clang_format_style!="") + command+=", "+Singleton::Config::source()->clang_format_style; command+="}\""; std::stringstream stdout_stream; From 1fa209454e199b96e8a479435e5725100bda68cc Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 14:53:34 +0200 Subject: [PATCH 12/34] Changed to version 0.9.4 since I added another configuration item among other things. --- src/files.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/files.h b/src/files.h index d892167..7874e90 100644 --- a/src/files.h +++ b/src/files.h @@ -1,6 +1,6 @@ #include -#define JUCI_VERSION "0.9.3" +#define JUCI_VERSION "0.9.4" const std::string configjson = "{\n" From d912faf4848961a858101b3e74fc8c637065a7dd Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 17:57:00 +0200 Subject: [PATCH 13/34] Fixes to auto-indent buffer. --- src/source_clang.cc | 21 ++++++++++++++++++--- src/terminal.cc | 2 +- src/terminal_win.cc | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index d855131..8325c59 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -944,11 +944,26 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { auto exit_code=Singleton::terminal()->execute(stdout_stream, command); if(exit_code==0) { get_source_buffer()->begin_user_action(); - auto cursor_line_nr=get_buffer()->get_insert()->get_iter().get_line(); + auto iter=get_buffer()->get_insert()->get_iter(); + auto cursor_line_nr=iter.get_line(); + auto cursor_line_offset=iter.get_line_offset(); + get_buffer()->erase(get_buffer()->begin(), get_buffer()->end()); get_buffer()->insert(get_buffer()->begin(), stdout_stream.str()); - if(cursor_line_nrget_line_count()) - get_buffer()->place_cursor(get_buffer()->get_iter_at_line(cursor_line_nr)); + + cursor_line_nr=std::min(cursor_line_nr, get_buffer()->get_line_count()-1); + if(cursor_line_nr>=0) { + iter=get_buffer()->get_iter_at_line(cursor_line_nr); + for(int c=0;cplace_cursor(iter); + while(gtk_events_pending()) + gtk_main_iteration(); + scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } get_source_buffer()->end_user_action(); set_tab_char_and_size(' ', tab_size); //clang-format only does basic indentation with spaces as I understand it } diff --git a/src/terminal.cc b/src/terminal.cc index 989e3f4..c710ae1 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -225,7 +225,7 @@ int Terminal::execute(std::iostream &stdout_stream, const std::string &command, next_char_iter++; umessage.replace(iter, next_char_iter, "?"); } - stdout_stream << umessage; + stdout_stream.write(umessage.data(), n); } }); stdout_thread.detach(); diff --git a/src/terminal_win.cc b/src/terminal_win.cc index cd6a927..9d2fcbc 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -277,7 +277,7 @@ int Terminal::execute(std::iostream &stdout_stream, const std::string &command, next_char_iter++; umessage.replace(iter, next_char_iter, "?"); } - stdout_stream << umessage; + stdout_stream.write(umessage.data(), static_cast(n)); } }); stdout_thread.detach(); From ef7804bdeaf3f25c0cd23f7139f6d9f8cd39438e Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Oct 2015 21:13:16 +0200 Subject: [PATCH 14/34] Fixed activation/deactivation of Auto-indent buffer menu item. --- src/window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.cc b/src/window.cc index 58dddbc..345cca2 100644 --- a/src/window.cc +++ b/src/window.cc @@ -105,7 +105,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) { notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search); } - if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceIndentationAutoIndentBuffer"))) + if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceIndentation/SourceIndentationAutoIndentBuffer"))) menu_item->set_sensitive((bool)notebook.get_current_view()->auto_indent); if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration"))) From 61722b063bcc6320b788dd216261a3fd93c74915 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 20 Oct 2015 09:35:53 +0200 Subject: [PATCH 15/34] Auto-indent now uses stdin instead of temporary file. --- src/source_clang.cc | 13 ++++--------- src/terminal.cc | 17 ++++++++++++++--- src/terminal.h | 3 ++- src/terminal_win.cc | 18 +++++++++++++++--- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 8325c59..597aac0 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -930,18 +930,15 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { }); auto_indent=[this]() { - boost::filesystem::path temp_file = "jucipp_auto_indent_tmp_file"; - auto temp_directory=boost::filesystem::temp_directory_path(); - boost::filesystem::path temp_file_path=temp_directory.string()+'/'+temp_file.string(); - juci::filesystem::write(temp_file_path, get_buffer()); - std::string command="clang-format \""+temp_file_path.string()+"\""; + std::string command="clang-format"; command+=" -style=\"{IndentWidth: "+std::to_string(tab_size); if(Singleton::Config::source()->clang_format_style!="") command+=", "+Singleton::Config::source()->clang_format_style; command+="}\""; - std::stringstream stdout_stream; - auto exit_code=Singleton::terminal()->execute(stdout_stream, command); + std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream; + + auto exit_code=Singleton::terminal()->execute(stdin_stream, stdout_stream, command); if(exit_code==0) { get_source_buffer()->begin_user_action(); auto iter=get_buffer()->get_insert()->get_iter(); @@ -967,8 +964,6 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { get_source_buffer()->end_user_action(); set_tab_char_and_size(' ', tab_size); //clang-format only does basic indentation with spaces as I understand it } - - boost::filesystem::remove(temp_file_path); }; get_token=[this]() -> Token { diff --git a/src/terminal.cc b/src/terminal.cc index c710ae1..9536efe 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -8,7 +8,7 @@ #include //TODO: remove using namespace std; //TODO: remove -const size_t buffer_size=131072; +const ssize_t buffer_size=131072; //A working implementation of popen3, with all pipes getting closed properly. //TODO: Eidheim is going to publish this one on his github, along with example uses @@ -190,7 +190,7 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path } } -int Terminal::execute(std::iostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) { +int Terminal::execute(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) { int stdin_fd, stdout_fd, stderr_fd; auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); @@ -230,9 +230,20 @@ int Terminal::execute(std::iostream &stdout_stream, const std::string &command, }); stdout_thread.detach(); + char buffer[buffer_size]; + for(;;) { + stdin_stream.readsome(buffer, buffer_size); + auto read_n=stdin_stream.gcount(); + if(read_n==0) + break; + auto write_n=write(stdin_fd, buffer, read_n); + if(write_n==0) + break; + } + close(stdin_fd); + int exit_code; waitpid(pid, &exit_code, 0); - close(stdin_fd); close(stdout_fd); close(stderr_fd); diff --git a/src/terminal.h b/src/terminal.h index c047682..497ec07 100644 --- a/src/terminal.h +++ b/src/terminal.h @@ -8,6 +8,7 @@ #include #include #include +#include class Terminal : public Gtk::TextView { public: @@ -34,7 +35,7 @@ public: Terminal(); int execute(const std::string &command, const boost::filesystem::path &path=""); - int execute(std::iostream &stdout_stream, const std::string &command, const boost::filesystem::path &path=""); + int execute(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path=""); void async_execute(const std::string &command, const boost::filesystem::path &path="", std::function callback=nullptr); void kill_last_async_execute(bool force=false); void kill_async_executes(bool force=false); diff --git a/src/terminal_win.cc b/src/terminal_win.cc index 9d2fcbc..d644efe 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -235,7 +235,7 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path return exit_code; } -int Terminal::execute(std::iostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) { +int Terminal::execute(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) { HANDLE stdin_h, stdout_h, stderr_h; auto process=popen3(command, path.string(), &stdin_h, &stdout_h, &stderr_h); @@ -281,13 +281,25 @@ int Terminal::execute(std::iostream &stdout_stream, const std::string &command, } }); stdout_thread.detach(); - + + CHAR buffer[buffer_size]; + for(;;) { + stdin_stream.readsome(buffer, buffer_size); + auto read_n=stdin_stream.gcount(); + if(read_n==0) + break; + DWORD write_n; + BOOL bSuccess = WriteFile(stdin_h, buffer, static_cast(read_n), &write_n, NULL); + if(!bSuccess || write_n==0) + break; + } + CloseHandle(stdin_h); + unsigned long exit_code; WaitForSingleObject(process, INFINITE); GetExitCodeProcess(process, &exit_code); CloseHandle(process); - CloseHandle(stdin_h); CloseHandle(stdout_h); CloseHandle(stderr_h); return exit_code; From d9fdf27db5c028f651d426869af3c46b4ee56f66 Mon Sep 17 00:00:00 2001 From: "U-olece-PC\\olece" Date: Tue, 20 Oct 2015 11:07:00 +0200 Subject: [PATCH 16/34] Improved process methods. --- src/juci.cc | 2 +- src/terminal.cc | 66 +++++++------- src/terminal.h | 2 +- src/terminal_win.cc | 204 ++++++++++++++++++++++++-------------------- 4 files changed, 152 insertions(+), 122 deletions(-) diff --git a/src/juci.cc b/src/juci.cc index a7d5cb7..05929a3 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -59,7 +59,7 @@ void app::on_activate() { } std::thread another_juci_app([this, directory, files_in_directory](){ Singleton::terminal()->async_print("Executing: juci "+directory.string()+files_in_directory); - Singleton::terminal()->execute("juci "+directory.string()+files_in_directory, ""); //TODO: do not open pipes here, doing this after Juci compiles on Windows + Singleton::terminal()->execute("juci "+directory.string()+files_in_directory, "", false); }); another_juci_app.detach(); } diff --git a/src/terminal.cc b/src/terminal.cc index 9536efe..b804da7 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -146,45 +146,53 @@ Terminal::Terminal() { }); } -int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { +int Terminal::execute(const std::string &command, const boost::filesystem::path &path, bool use_pipes) { int stdin_fd, stdout_fd, stderr_fd; - auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); + pid_t pid; + if(use_pipes) + pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); + else + pid=popen3(command, path.string(), nullptr, nullptr, nullptr); if (pid<=0) { async_print("Error: Failed to run command: " + command + "\n"); return -1; } else { - std::thread stderr_thread([this, stderr_fd](){ - char buffer[buffer_size]; - ssize_t n; - while ((n=read(stderr_fd, buffer, buffer_size)) > 0) { - std::string message; - message.reserve(n); - for(ssize_t c=0;c 0) { - std::string message; - message.reserve(n); - for(ssize_t c=0;c 0) { + std::string message; + message.reserve(n); + for(ssize_t c=0;c 0) { + std::string message; + message.reserve(n); + for(ssize_t c=0;c callback=nullptr); void kill_last_async_execute(bool force=false); diff --git a/src/terminal_win.cc b/src/terminal_win.cc index d644efe..a299e9b 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -10,6 +10,9 @@ using namespace std; //TODO: remove const size_t buffer_size=131072; +//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx +//Note: on Windows it seems impossible to specify which pipes to use +//Thus, if stdin_h, stdout_h and stderr all are NULL, the out,err,in is sent to the parent process instead HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin_h, HANDLE *stdout_h, HANDLE *stderr_h) { HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; @@ -21,43 +24,49 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = NULL; - - if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) - return NULL; - if(!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - return NULL; - } - if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - return NULL; - } - if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - CloseHandle(g_hChildStd_OUT_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - return NULL; - } - if (!CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - CloseHandle(g_hChildStd_OUT_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - return NULL; - } - if(!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - CloseHandle(g_hChildStd_OUT_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - CloseHandle(g_hChildStd_ERR_Rd); - CloseHandle(g_hChildStd_ERR_Wr); - return NULL; + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + bool use_pipes=(stdin_h!=nullptr || stdout_h!=nullptr || stderr_h!=nullptr); + + if(use_pipes) { + if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) + return NULL; + if(!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_IN_Wr); + return NULL; + } + + if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_IN_Wr); + return NULL; + } + if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_IN_Wr); + CloseHandle(g_hChildStd_OUT_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + return NULL; + } + + if (!CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0)) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_IN_Wr); + CloseHandle(g_hChildStd_OUT_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + return NULL; + } + if(!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_IN_Wr); + CloseHandle(g_hChildStd_OUT_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + CloseHandle(g_hChildStd_ERR_Rd); + CloseHandle(g_hChildStd_ERR_Wr); + return NULL; + } } PROCESS_INFORMATION process_info; @@ -66,11 +75,13 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION)); ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); - siStartInfo.hStdError = g_hChildStd_ERR_Wr; - siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; - siStartInfo.hStdInput = g_hChildStd_IN_Rd; - siStartInfo.dwFlags |= STARTF_USESTDHANDLES; + siStartInfo.cb = sizeof(STARTUPINFO); + if(use_pipes) { + siStartInfo.hStdInput = g_hChildStd_IN_Rd; + siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; + siStartInfo.hStdError = g_hChildStd_ERR_Wr; + siStartInfo.dwFlags |= STARTF_USESTDHANDLES; + } char* path_ptr; if(path=="") @@ -95,9 +106,11 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin if(!bSuccess) { CloseHandle(process_info.hProcess); CloseHandle(process_info.hThread); - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - CloseHandle(g_hChildStd_ERR_Wr); + if(use_pipes) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + CloseHandle(g_hChildStd_ERR_Wr); + } return NULL; } else { @@ -106,14 +119,16 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin // of the child process, for example. CloseHandle(process_info.hThread); - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - CloseHandle(g_hChildStd_ERR_Wr); + if(use_pipes) { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + CloseHandle(g_hChildStd_ERR_Wr); + } } - *stdin_h=g_hChildStd_IN_Wr; - *stdout_h=g_hChildStd_OUT_Rd; - *stderr_h=g_hChildStd_ERR_Rd; + if(stdin_h!=NULL) *stdin_h=g_hChildStd_IN_Wr; + if(stdout_h!=NULL) *stdout_h=g_hChildStd_OUT_Rd; + if(stderr_h!=NULL) *stderr_h=g_hChildStd_ERR_Rd; return process_info.hProcess; } @@ -181,57 +196,64 @@ Terminal::Terminal() { }); } -//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx -int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { +int Terminal::execute(const std::string &command, const boost::filesystem::path &path, bool use_pipes) { HANDLE stdin_h, stdout_h, stderr_h; - - auto process=popen3(command, path.string(), &stdin_h, &stdout_h, &stderr_h); + + HANDLE process; + if(use_pipes) + process=popen3(command, path.string(), &stdin_h, &stdout_h, &stderr_h); + else + process=popen3(command, path.string(), nullptr, nullptr, nullptr); if(process==NULL) { async_print("Error: Failed to run command: " + command + "\n"); return -1; } - std::thread stderr_thread([this, stderr_h](){ - DWORD n; - CHAR buffer[buffer_size]; - for (;;) { - BOOL bSuccess = ReadFile(stderr_h, buffer, static_cast(buffer_size), &n, NULL); - if(!bSuccess || n == 0) - break; - - std::string message; - message.reserve(n); - for(DWORD c=0;c(buffer_size), &n, NULL); - if(!bSuccess || n == 0) - break; - - std::string message; - message.reserve(n); - for(DWORD c=0;c(buffer_size), &n, NULL); + if(!bSuccess || n == 0) + break; + + std::string message; + message.reserve(n); + for(DWORD c=0;c(buffer_size), &n, NULL); + if(!bSuccess || n == 0) + break; + + std::string message; + message.reserve(n); + for(DWORD c=0;c Date: Tue, 20 Oct 2015 20:20:37 +0200 Subject: [PATCH 17/34] More clean processing function for windoes. --- src/terminal_win.cc | 59 +++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/terminal_win.cc b/src/terminal_win.cc index a299e9b..99e2e78 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -27,9 +27,7 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; - bool use_pipes=(stdin_h!=nullptr || stdout_h!=nullptr || stderr_h!=nullptr); - - if(use_pipes) { + if(stdin_h!=nullptr) { if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) return NULL; if(!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) { @@ -37,32 +35,34 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin CloseHandle(g_hChildStd_IN_Wr); return NULL; } - + } + if(stdout_h!=nullptr) { if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Rd); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Wr); return NULL; } if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Rd); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Wr); CloseHandle(g_hChildStd_OUT_Rd); CloseHandle(g_hChildStd_OUT_Wr); return NULL; } - + } + if(stderr_h!=nullptr) { if (!CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - CloseHandle(g_hChildStd_OUT_Rd); - CloseHandle(g_hChildStd_OUT_Wr); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Rd); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Wr); + if(stdout_h!=nullptr) CloseHandle(g_hChildStd_OUT_Rd); + if(stdout_h!=nullptr) CloseHandle(g_hChildStd_OUT_Wr); return NULL; } if(!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_IN_Wr); - CloseHandle(g_hChildStd_OUT_Rd); - CloseHandle(g_hChildStd_OUT_Wr); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Rd); + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Wr); + if(stdout_h!=nullptr) CloseHandle(g_hChildStd_OUT_Rd); + if(stdout_h!=nullptr) CloseHandle(g_hChildStd_OUT_Wr); CloseHandle(g_hChildStd_ERR_Rd); CloseHandle(g_hChildStd_ERR_Wr); return NULL; @@ -76,12 +76,11 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); - if(use_pipes) { - siStartInfo.hStdInput = g_hChildStd_IN_Rd; - siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; - siStartInfo.hStdError = g_hChildStd_ERR_Wr; + if(stdin_h!=nullptr) siStartInfo.hStdInput = g_hChildStd_IN_Rd; + if(stdout_h!=nullptr) siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; + if(stderr_h!=nullptr) siStartInfo.hStdError = g_hChildStd_ERR_Wr; + if(stdin_h!=nullptr || stdout_h!=nullptr || stderr_h!=nullptr) siStartInfo.dwFlags |= STARTF_USESTDHANDLES; - } char* path_ptr; if(path=="") @@ -106,11 +105,9 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin if(!bSuccess) { CloseHandle(process_info.hProcess); CloseHandle(process_info.hThread); - if(use_pipes) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - CloseHandle(g_hChildStd_ERR_Wr); - } + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Rd); + if(stdout_h!=nullptr) CloseHandle(g_hChildStd_OUT_Wr); + if(stderr_h!=nullptr) CloseHandle(g_hChildStd_ERR_Wr); return NULL; } else { @@ -119,11 +116,9 @@ HANDLE popen3(const std::string &command, const std::string &path, HANDLE *stdin // of the child process, for example. CloseHandle(process_info.hThread); - if(use_pipes) { - CloseHandle(g_hChildStd_IN_Rd); - CloseHandle(g_hChildStd_OUT_Wr); - CloseHandle(g_hChildStd_ERR_Wr); - } + if(stdin_h!=nullptr) CloseHandle(g_hChildStd_IN_Rd); + if(stdout_h!=nullptr) CloseHandle(g_hChildStd_OUT_Wr); + if(stderr_h!=nullptr) CloseHandle(g_hChildStd_ERR_Wr); } if(stdin_h!=NULL) *stdin_h=g_hChildStd_IN_Wr; From 2ac04c15a5cd079c76bd32d4061e3c67b46b5fd4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 21 Oct 2015 09:56:26 +0200 Subject: [PATCH 18/34] Now stores the last tab when opening a new one such that notebook returns to the previous tab after closing the new tab, if no other tab-operations have happened. Like what happens in for instance Chrome. --- src/notebook.cc | 17 ++++++++++++++++- src/notebook.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/notebook.cc b/src/notebook.cc index 4cf8d7d..445756a 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -27,8 +27,12 @@ namespace sigc { #endif } -Notebook::Notebook() : Gtk::Notebook() { +Notebook::Notebook() : Gtk::Notebook(), last_index(-1) { Gsv::init(); + + signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) { + last_index=-1; + }); } int Notebook::size() { @@ -114,7 +118,13 @@ void Notebook::open(const boost::filesystem::path &file_path) { set_tab_reorderable(*hboxes.back(), true); show_all_children(); + + size_t last_index_tmp=-1; + if(get_current_page()!=-1) + last_index_tmp=get_index(get_current_page()); set_current_page(size()-1); + last_index=last_index_tmp; + set_focus_child(*source_views.back()); get_current_view()->get_buffer()->set_modified(false); get_current_view()->grab_focus(); @@ -229,6 +239,11 @@ bool Notebook::close_current_page() { } int page = get_current_page(); int index=get_index(page); + + if(last_index!=-1) { + set_current_page(page_num(*hboxes.at(last_index))); + last_index=-1; + } remove_page(page); #if GTK_VERSION_GE(3, 18) source_maps.erase(source_maps.begin()+index); diff --git a/src/notebook.h b/src/notebook.h index 12388ed..00892bb 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -29,5 +29,7 @@ private: std::vector > source_maps; std::vector > scrolled_windows; std::vector > hboxes; + + size_t last_index; }; #endif // JUCI_NOTEBOOK_H_ From f20823c477c8d2e33559536d638fc22bb05cab24 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 21 Oct 2015 10:45:07 +0200 Subject: [PATCH 19/34] Now getting rid of all dispatchers on source_clang delete. --- src/source_clang.cc | 32 ++++++++++++++++++-------------- src/source_clang.h | 24 +++++++++++++++--------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 597aac0..3cf76f5 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -36,7 +36,7 @@ Source::View(file_path, project_path, language), parse_error(false) { parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path.string()); //GTK-calls must happen in main thread, so the parse_thread //sends signals to the main thread that it is to call the following functions: - parse_start.connect([this]{ + parse_start_connection=parse_start.connect([this]{ if(parse_thread_buffer_map_mutex.try_lock()) { parse_thread_buffer_map=get_buffer_map(); parse_thread_mapped=true; @@ -44,7 +44,7 @@ Source::View(file_path, project_path, language), parse_error(false) { } parse_thread_go=true; }); - parse_done.connect([this](){ + parse_done_connection=parse_done.connect([this](){ if(parse_thread_mapped) { if(parsing_mutex.try_lock()) { update_syntax(); @@ -59,7 +59,7 @@ Source::View(file_path, project_path, language), parse_error(false) { parse_thread_go=true; } }); - parse_fail.connect([this](){ + parse_fail_connection=parse_fail.connect([this](){ Singleton::terminal()->print("Error: failed to reparse "+this->file_path.string()+".\n"); set_status(""); set_info(""); @@ -106,10 +106,6 @@ void Source::ClangViewParse::configure() { no_bracket_no_para_statement_regex=std::regex("^([ \\t]*)(else|try|do) *$"); } -Source::ClangViewParse::~ClangViewParse() { - delayed_reparse_connection.disconnect(); -} - void Source::ClangViewParse::init_parse() { type_tooltips.hide(); diagnostic_tooltips.hide(); @@ -660,9 +656,10 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_cancel_s autocomplete_cancel_starting=false; }); - do_delete_object.connect([this](){ + do_delete_object_connection=do_delete_object.connect([this](){ if(delete_thread.joinable()) delete_thread.join(); + do_delete_object_connection.disconnect(); delete this; }); do_restart_parse.connect([this](){ @@ -875,8 +872,6 @@ std::vector Source::ClangViewAu void Source::ClangViewAutocomplete::async_delete() { parsing_in_progress->cancel("canceled, freeing resources in the background"); - autocomplete_done_connection.disconnect(); - autocomplete_fail_connection.disconnect(); parse_thread_stop=true; delete_thread=std::thread([this](){ //TODO: Is it possible to stop the clang-process in progress? @@ -1262,13 +1257,22 @@ void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) { } } -Source::ClangViewRefactor::~ClangViewRefactor() { - delayed_tag_similar_tokens_connection.disconnect(); -} - Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): ClangViewRefactor(file_path, project_path, language) { if(language) { get_source_buffer()->set_highlight_syntax(true); get_source_buffer()->set_language(language); } } + +void Source::ClangView::async_delete() { + delayed_reparse_connection.disconnect(); + parse_done_connection.disconnect(); + parse_start_connection.disconnect(); + parse_fail_connection.disconnect(); + autocomplete_done_connection.disconnect(); + autocomplete_fail_connection.disconnect(); + do_restart_parse_connection.disconnect(); + delayed_tag_similar_tokens_connection.disconnect(); + ClangViewAutocomplete::async_delete(); +} + diff --git a/src/source_clang.h b/src/source_clang.h index e029a58..1ffd4b2 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -21,8 +21,7 @@ namespace Source { }; ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); - ~ClangViewParse(); - void configure(); + virtual void configure(); void start_reparse(); bool reparse_needed=false; @@ -39,8 +38,8 @@ namespace Source { std::atomic parse_thread_stop; std::atomic parse_error; - void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle); - void show_type_tooltips(const Gdk::Rectangle &rectangle); + virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle); + virtual void show_type_tooltips(const Gdk::Rectangle &rectangle); std::regex bracket_regex; std::regex no_bracket_statement_regex; @@ -48,6 +47,10 @@ namespace Source { std::set diagnostic_offsets; std::vector fix_its; + + sigc::connection parse_done_connection; + sigc::connection parse_start_connection; + sigc::connection parse_fail_connection; private: std::map get_buffer_map() const; void update_syntax(); @@ -77,11 +80,15 @@ namespace Source { }; ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); - void async_delete(); + virtual void async_delete(); bool restart_parse(); protected: bool on_key_press_event(GdkEventKey* key); std::thread autocomplete_thread; + sigc::connection autocomplete_done_connection; + sigc::connection autocomplete_fail_connection; + sigc::connection do_delete_object_connection; + sigc::connection do_restart_parse_connection; private: void start_autocomplete(); void autocomplete(); @@ -89,9 +96,7 @@ namespace Source { bool completion_dialog_shown=false; std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map); Glib::Dispatcher autocomplete_done; - sigc::connection autocomplete_done_connection; Glib::Dispatcher autocomplete_fail; - sigc::connection autocomplete_fail_connection; bool autocomplete_starting=false; std::atomic autocomplete_cancel_starting; guint last_keyval=0; @@ -108,13 +113,13 @@ namespace Source { class ClangViewRefactor : public ClangViewAutocomplete { public: ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); - ~ClangViewRefactor(); + protected: + sigc::connection delayed_tag_similar_tokens_connection; private: std::list, Glib::RefPtr > > similar_token_marks; void tag_similar_tokens(const Token &token); Glib::RefPtr similar_tokens_tag; Token last_tagged_token; - sigc::connection delayed_tag_similar_tokens_connection; std::unique_ptr selection_dialog; bool renaming=false; }; @@ -122,6 +127,7 @@ namespace Source { class ClangView : public ClangViewRefactor { public: ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + virtual void async_delete(); }; } From 2c5f5139947340ff1609100bb67e6bec9ee666b2 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 22 Oct 2015 13:46:51 +0200 Subject: [PATCH 20/34] Removed a gcc warning. --- src/notebook.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/notebook.cc b/src/notebook.cc index 445756a..1bbec27 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -240,7 +240,7 @@ bool Notebook::close_current_page() { int page = get_current_page(); int index=get_index(page); - if(last_index!=-1) { + if(last_index!=static_cast(-1)) { set_current_page(page_num(*hboxes.at(last_index))); last_index=-1; } From d6f3b8c3e52f9e243a8b3b1fbb80eb83d77364b1 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 22 Oct 2015 18:58:19 +0200 Subject: [PATCH 21/34] Added background_pattern. --- src/files.h | 3 ++- src/source.cc | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/files.h b/src/files.h index 7874e90..9d678b7 100644 --- a/src/files.h +++ b/src/files.h @@ -138,10 +138,11 @@ const std::string juci_light_style = " \n" "\n" "